From 9f7972ee0d1206531214b05158ecfa1cf3eb8e8c Mon Sep 17 00:00:00 2001 From: Felix Riestra Date: Thu, 10 Sep 2026 11:24:30 +0200 Subject: [PATCH] Register all sketch-constraint commands in the autocomplete registry None of the 17 constraint commands (HCONSTRAINT, VCONSTRAINT, PCONSTRAINT, QCONSTRAINT, ECONSTRAINT, TCONSTRAINT, NCONSTRAINT, NRCONSTRAINT, LCONSTRAINT, FXCONSTRAINT, SYCONSTRAINT, CCONSTRAINT, EDCONSTRAINT, CPCONSTRAINT, MPCONSTRAINT, OCCONSTRAINT, DCONSTRAINT, ACONSTRAINT) carried an inventory::submit! registration, so they were invisible to command-line autocomplete, the MCP commands listing, and the ALIASEDIT shortcut editor (which rejects a custom shortcut target that isn't in this same registry). Each constraint module now registers itself, with a regression test pinning the full set. Co-Authored-By: Claude Sonnet 5 --- CHANGELOG.md | 29 +++++++++++++- src/command.rs | 40 +++++++++++++++++++ src/modules/draw/constrain/coincident.rs | 3 ++ src/modules/draw/constrain/equal_distance.rs | 3 ++ src/modules/draw/constrain/point_on_entity.rs | 3 ++ src/modules/draw/constrain/tools.rs | 17 ++++++++ src/modules/draw/constrain/value.rs | 3 ++ 7 files changed, 97 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d40cbc73d..06779d265 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,34 @@ Notable changes on `feature/parametric-constraint-system` since each push to GitHub. Newest entries first. "Unreleased" covers local changes not yet pushed. -## Unreleased (since `eb96e8b6`) +## Unreleased (since `3d0a41b6`) + +- **Fix:** none of the 17 sketch-constraint commands (`HCONSTRAINT`, + `VCONSTRAINT`, `PCONSTRAINT`, `QCONSTRAINT`, `ECONSTRAINT`, `TCONSTRAINT`, + `NCONSTRAINT`, `NRCONSTRAINT`, `LCONSTRAINT`, `FXCONSTRAINT`, + `SYCONSTRAINT`, `CCONSTRAINT`, `EDCONSTRAINT`, `CPCONSTRAINT`, + `MPCONSTRAINT`, `OCCONSTRAINT`, `DCONSTRAINT`, `ACONSTRAINT`) carried an + `inventory::submit!` registration — a pre-existing gap the + `docs/command_reference.md` generator had already flagged, which meant + every constraint command (including this session's new `NRCONSTRAINT`) + was invisible to command-line autocomplete and the MCP server's + `commands` listing, despite working fine when typed exactly. Each + constraint module now registers itself, with a regression test pinning + it so the gap can't silently reappear. + - The same missing registration also broke the **keyboard-shortcut + editor** (`ALIASEDIT`): it validates a custom shortcut's target + against this same registry and silently rejected anything not in it, + so a user could not assign a custom shortcut to *any* constraint + command — not just the new ones, the original `HCONSTRAINT`/ + `CCONSTRAINT`/etc. family too. Fixed by the same change. + ([tools.rs](src/modules/draw/constrain/tools.rs), + [coincident.rs](src/modules/draw/constrain/coincident.rs), + [equal_distance.rs](src/modules/draw/constrain/equal_distance.rs), + [point_on_entity.rs](src/modules/draw/constrain/point_on_entity.rs), + [value.rs](src/modules/draw/constrain/value.rs), + [command.rs](src/command.rs)) + +## Pushed 2026-09-10 (`eb96e8b6` → `3d0a41b6`) - **Fix:** a dimensional constraint's value prompt (e.g. `DCONSTRAINT`'s "Specify distance:") rejected a named parameter typed in its own diff --git a/src/command.rs b/src/command.rs index c380356a2..8250dbfdb 100644 --- a/src/command.rs +++ b/src/command.rs @@ -2445,3 +2445,43 @@ pub fn all_registered_command_names() -> Vec<&'static str> { .flat_map(|r| r.names.iter().copied()) .collect() } + +#[cfg(test)] +mod constraint_registry_tests { + use super::*; + + /// Regression guard: the whole `src/modules/draw/constrain/` family + /// (17 command ids, every one of the geometric/dimensional constraint + /// commands) predated `inventory::submit!` and was invisible to + /// command-line autocomplete and the MCP `commands` listing — + /// `docs/command_reference.md`'s own generator flagged this. Each + /// constraint module now registers itself; this pins that so the gap + /// can't silently reappear (e.g. a new constraint command added + /// without its own registration). + #[test] + fn every_constraint_command_is_in_the_autocomplete_registry() { + let names = all_registered_command_names(); + for id in [ + "CCONSTRAINT", + "EDCONSTRAINT", + "CPCONSTRAINT", + "MPCONSTRAINT", + "OCCONSTRAINT", + "HCONSTRAINT", + "VCONSTRAINT", + "PCONSTRAINT", + "QCONSTRAINT", + "ECONSTRAINT", + "TCONSTRAINT", + "NCONSTRAINT", + "NRCONSTRAINT", + "LCONSTRAINT", + "FXCONSTRAINT", + "SYCONSTRAINT", + "DCONSTRAINT", + "ACONSTRAINT", + ] { + assert!(names.contains(&id), "{id} is missing from the command registry"); + } + } +} diff --git a/src/modules/draw/constrain/coincident.rs b/src/modules/draw/constrain/coincident.rs index 6160a8789..b4da68fa3 100644 --- a/src/modules/draw/constrain/coincident.rs +++ b/src/modules/draw/constrain/coincident.rs @@ -71,3 +71,6 @@ impl CadCommand for CoincidentConstraintCommand { CmdResult::Cancel } } + +// ── Autocomplete registry ───────────────────────────────── +inventory::submit!(crate::command::CommandRegistration { names: &["CCONSTRAINT"] }); diff --git a/src/modules/draw/constrain/equal_distance.rs b/src/modules/draw/constrain/equal_distance.rs index ed648a458..f71725a3b 100644 --- a/src/modules/draw/constrain/equal_distance.rs +++ b/src/modules/draw/constrain/equal_distance.rs @@ -65,3 +65,6 @@ impl CadCommand for EqualDistanceConstraintCommand { CmdResult::Cancel } } + +// ── Autocomplete registry ───────────────────────────────── +inventory::submit!(crate::command::CommandRegistration { names: &["EDCONSTRAINT"] }); diff --git a/src/modules/draw/constrain/point_on_entity.rs b/src/modules/draw/constrain/point_on_entity.rs index 88b5e141a..f572a2439 100644 --- a/src/modules/draw/constrain/point_on_entity.rs +++ b/src/modules/draw/constrain/point_on_entity.rs @@ -89,3 +89,6 @@ impl CadCommand for PointOnEntityConstraintCommand { CmdResult::Cancel } } + +// ── Autocomplete registry ───────────────────────────────── +inventory::submit!(crate::command::CommandRegistration { names: &["CPCONSTRAINT", "MPCONSTRAINT", "OCCONSTRAINT"] }); diff --git a/src/modules/draw/constrain/tools.rs b/src/modules/draw/constrain/tools.rs index 6ed14b260..aaf83458c 100644 --- a/src/modules/draw/constrain/tools.rs +++ b/src/modules/draw/constrain/tools.rs @@ -141,3 +141,20 @@ pub mod symmetric { } } } + +// ── Autocomplete registry ───────────────────────────────── +inventory::submit!(crate::command::CommandRegistration { + names: &[ + "HCONSTRAINT", + "VCONSTRAINT", + "PCONSTRAINT", + "QCONSTRAINT", + "ECONSTRAINT", + "TCONSTRAINT", + "NCONSTRAINT", + "NRCONSTRAINT", + "LCONSTRAINT", + "FXCONSTRAINT", + "SYCONSTRAINT", + ] +}); diff --git a/src/modules/draw/constrain/value.rs b/src/modules/draw/constrain/value.rs index 256253f23..5b7363f75 100644 --- a/src/modules/draw/constrain/value.rs +++ b/src/modules/draw/constrain/value.rs @@ -307,6 +307,9 @@ impl CadCommand for AngleConstraintCommand { } } +// ── Autocomplete registry ───────────────────────────────── +inventory::submit!(crate::command::CommandRegistration { names: &["DCONSTRAINT", "ACONSTRAINT"] }); + #[cfg(test)] mod tests { use super::*;