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::*;