feat(commandline): autocomplete suggestions + inventory-based registry

Type-as-you-go suggestion popup above the input that filters known
command names by substring (so `LEADER` surfaces both LEADER and
MLEADER). Up / Down navigates the list, Enter dispatches the
highlighted entry, clicking a row dispatches directly. Esc on a
non-empty input clears the buffer instead of escalating to
command-cancel.

The name corpus comes from `inventory::submit!` blocks placed next
to each `CadCommand` impl rather than a hand-maintained static list.
Adding a new interactive command means dropping one `inventory::submit!`
line in its own module file — the autocomplete picks it up at the
next compile. 98 submissions seeded across 60 module files;
`command::all_registered_command_names()` flattens them at runtime.

One-shot dispatch arms in `app/commands.rs` (NEW, OPEN, SAVE, UNDO,
…) don't have a `CadCommand` impl and are therefore absent from
autocomplete by design.

Co-Authored-By: Claude Opus 4.7 <[email protected]>
This commit is contained in:
Hakan SevenandClaude Opus 4.7 committed 2026-05-26 22:45:54 +03:00
1 parent 4124cb2689
commit 05ea31aa2a
67 files changed
+507 -2

No files matched your search

+4
View File
@@ -149,3 +149,7 @@ fn preview_aligned(p1: Vec3, p2: Vec3, dim_pt: Vec3) -> WireModel {
fill_tris: vec![],
}
}
// ── Autocomplete registry ─────────────────────────────────
inventory::submit!(crate::command::CommandRegistration { names: &["DAL", "DIMALIGNED"] }); // AlignedDimensionCommand
+4
View File
@@ -173,3 +173,7 @@ fn angular_preview(vertex: Vec3, first: Vec3, second: Vec3, arc_pt: Vec3) -> Vec
}
points
}
// ── Autocomplete registry ─────────────────────────────────
inventory::submit!(crate::command::CommandRegistration { names: &["DIMANGULAR"] }); // AngularDimensionCommand
+4
View File
@@ -112,3 +112,7 @@ fn preview_line(a: Vec3, b: Vec3) -> WireModel {
fill_tris: vec![],
}
}
// ── Autocomplete registry ─────────────────────────────────
inventory::submit!(crate::command::CommandRegistration { names: &["DDI", "DIMDIAMETER"] }); // DiameterDimensionCommand
+4
View File
@@ -177,3 +177,7 @@ impl CadCommand for DimBaselineCommand {
fn v3(p: Vec3) -> Vector3 {
Vector3::new(p.x as f64, p.y as f64, p.z as f64)
}
// ── Autocomplete registry ─────────────────────────────────
inventory::submit!(crate::command::CommandRegistration { names: &["DBA", "DIMBASELINE"] }); // DimBaselineCommand
+4
View File
@@ -158,3 +158,7 @@ impl CadCommand for DimContinueCommand {
fn v3(p: Vec3) -> Vector3 {
Vector3::new(p.x as f64, p.y as f64, p.z as f64)
}
// ── Autocomplete registry ─────────────────────────────────
inventory::submit!(crate::command::CommandRegistration { names: &["DCO", "DIMCONTINUE"] }); // DimContinueCommand
+4
View File
@@ -97,3 +97,7 @@ impl CadCommand for DimBreakCommand {
CmdResult::Cancel
}
}
// ── Autocomplete registry ─────────────────────────────────
inventory::submit!(crate::command::CommandRegistration { names: &["DBR", "DIMBREAK"] }); // DimBreakCommand
+4
View File
@@ -85,3 +85,7 @@ impl CadCommand for DimEditCommand {
CmdResult::Cancel
}
}
// ── Autocomplete registry ─────────────────────────────────
inventory::submit!(crate::command::CommandRegistration { names: &["DED", "DIMEDIT"] }); // DimEditCommand
+4
View File
@@ -108,3 +108,7 @@ impl CadCommand for DimJogLineCommand {
})
}
}
// ── Autocomplete registry ─────────────────────────────────
inventory::submit!(crate::command::CommandRegistration { names: &["DIMJOGLINE", "DJL"] }); // DimJogLineCommand
+4
View File
@@ -125,3 +125,7 @@ impl CadCommand for DimSpaceCommand {
}
}
}
// ── Autocomplete registry ─────────────────────────────────
inventory::submit!(crate::command::CommandRegistration { names: &["DIMSPACE", "DSPACE"] }); // DimSpaceCommand
+4
View File
@@ -128,3 +128,7 @@ impl CadCommand for DimTeditCommand {
}
}
}
// ── Autocomplete registry ─────────────────────────────────
inventory::submit!(crate::command::CommandRegistration { names: &["DIMTED", "DIMTEDIT"] }); // DimTeditCommand
+4
View File
@@ -252,3 +252,7 @@ pub fn arrowhead_wings(tip: Vec3, next: Vec3, size: f32) -> [Vec3; 2] {
),
]
}
// ── Autocomplete registry ─────────────────────────────────
inventory::submit!(crate::command::CommandRegistration { names: &["LE", "LEADER"] }); // LeaderCommand
+4
View File
@@ -163,3 +163,7 @@ fn linear_text_pos(first: Vec3, second: Vec3, def: Vec3) -> Vec3 {
let d2 = second + perp * offset;
(d1 + d2) * 0.5 + perp * 0.15
}
// ── Autocomplete registry ─────────────────────────────────
inventory::submit!(crate::command::CommandRegistration { names: &["DIMLINEAR"] }); // LinearDimensionCommand
+4
View File
@@ -199,3 +199,7 @@ fn arrowhead_wings(tip: Vec3, next: Vec3, size: f32) -> [Vec3; 2] {
),
]
}
// ── Autocomplete registry ─────────────────────────────────
inventory::submit!(crate::command::CommandRegistration { names: &["MLD", "MLEADER"] }); // MLeaderCommand
+7
View File
@@ -476,3 +476,10 @@ fn preview_wire(pts: &[Vec3]) -> WireModel {
// Silence unused-import warning for MultiLeader and LeaderLine if not used in all paths
fn _uses_ml_types(_ml: &MultiLeader, _ll: &LeaderLine) {}
// ── Autocomplete registry ─────────────────────────────────
inventory::submit!(crate::command::CommandRegistration { names: &["MLA", "MLEADERADD"] }); // MLeaderAddCommand
inventory::submit!(crate::command::CommandRegistration { names: &["MLAL", "MLEADERALIGN"] }); // MLeaderAlignCommand
inventory::submit!(crate::command::CommandRegistration { names: &["MLC", "MLEADERCOLLECT"] }); // MLeaderCollectCommand
inventory::submit!(crate::command::CommandRegistration { names: &["MLEADERREMOVE", "MLR"] }); // MLeaderRemoveCommand
+4
View File
@@ -91,3 +91,7 @@ impl CadCommand for MTextCommand {
None
}
}
// ── Autocomplete registry ─────────────────────────────────
inventory::submit!(crate::command::CommandRegistration { names: &["MT", "MTEXT"] }); // MTextCommand
+4
View File
@@ -86,3 +86,7 @@ impl CadCommand for OrdinateDimCommand {
fn v3(p: Vec3) -> Vector3 {
Vector3::new(p.x as f64, 0.0, p.z as f64)
}
// ── Autocomplete registry ─────────────────────────────────
inventory::submit!(crate::command::CommandRegistration { names: &["DIMORDINATE", "DOR"] }); // OrdinateDimCommand
+4
View File
@@ -128,3 +128,7 @@ pub fn make_linear_dim(p1: Vec3, p2: Vec3, dim_pt: Vec3) -> EntityType {
dim.base.actual_measurement = dim.measurement();
EntityType::Dimension(Dimension::Linear(dim))
}
// ── Autocomplete registry ─────────────────────────────────
inventory::submit!(crate::command::CommandRegistration { names: &["QDIM"] }); // QdimCommand
+4
View File
@@ -117,3 +117,7 @@ fn preview_wire(points: Vec<Vec3>) -> WireModel {
fill_tris: vec![],
}
}
// ── Autocomplete registry ─────────────────────────────────
inventory::submit!(crate::command::CommandRegistration { names: &["DIMRADIUS"] }); // RadiusDimensionCommand
+4
View File
@@ -169,3 +169,7 @@ impl CadCommand for TableCommand {
}
}
}
// ── Autocomplete registry ─────────────────────────────────
inventory::submit!(crate::command::CommandRegistration { names: &["TABLE"] }); // TableCommand
+4
View File
@@ -86,3 +86,7 @@ impl CadCommand for TextCommand {
None
}
}
// ── Autocomplete registry ─────────────────────────────────
inventory::submit!(crate::command::CommandRegistration { names: &["DT", "T", "TEXT"] }); // TextCommand
+4
View File
@@ -108,3 +108,7 @@ impl CadCommand for ToleranceCommand {
})
}
}
// ── Autocomplete registry ─────────────────────────────────
inventory::submit!(crate::command::CommandRegistration { names: &["TOL", "TOLERANCE"] }); // ToleranceCommand
+4
View File
@@ -58,3 +58,7 @@ impl CadCommand for PasteCommand {
self.wires.iter().map(|w| w.translated(delta)).collect()
}
}
// ── Autocomplete registry ─────────────────────────────────
inventory::submit!(crate::command::CommandRegistration { names: &["PASTECLIP", "PC"] }); // PasteCommand
+13
View File
@@ -1102,3 +1102,16 @@ impl CadCommand for ArcCSLCommand {
}
}
}
// ── Autocomplete registry ─────────────────────────────────
inventory::submit!(crate::command::CommandRegistration { names: &["ARC_3P"] }); // Arc3PCommand
inventory::submit!(crate::command::CommandRegistration { names: &["ARC_CSA"] }); // ArcCSACommand
inventory::submit!(crate::command::CommandRegistration { names: &["ARC_CSL"] }); // ArcCSLCommand
inventory::submit!(crate::command::CommandRegistration { names: &["A", "ARC"] }); // ArcCommand
inventory::submit!(crate::command::CommandRegistration { names: &["ARC_SCA"] }); // ArcSCACommand
inventory::submit!(crate::command::CommandRegistration { names: &["ARC_SCE"] }); // ArcSCECommand
inventory::submit!(crate::command::CommandRegistration { names: &["ARC_SCL"] }); // ArcSCLCommand
inventory::submit!(crate::command::CommandRegistration { names: &["ARC_SEA"] }); // ArcSEACommand
inventory::submit!(crate::command::CommandRegistration { names: &["ARC_SED"] }); // ArcSEDCommand
inventory::submit!(crate::command::CommandRegistration { names: &["ARC_SER"] }); // ArcSERCommand
+4
View File
@@ -184,3 +184,7 @@ impl CadCommand for AttdefCommand {
})
}
}
// ── Autocomplete registry ─────────────────────────────────
inventory::submit!(crate::command::CommandRegistration { names: &["ATTDEF"] }); // AttdefCommand
+9
View File
@@ -910,3 +910,12 @@ impl CadCommand for CircleTTTCommand {
None
}
}
// ── Autocomplete registry ─────────────────────────────────
inventory::submit!(crate::command::CommandRegistration { names: &["CIRCLE_2P"] }); // Circle2PCommand
inventory::submit!(crate::command::CommandRegistration { names: &["CIRCLE_3P"] }); // Circle3PCommand
inventory::submit!(crate::command::CommandRegistration { names: &["CIRCLE_CD"] }); // CircleCDCommand
inventory::submit!(crate::command::CommandRegistration { names: &["C", "CIRCLE"] }); // CircleCommand
inventory::submit!(crate::command::CommandRegistration { names: &["CIRCLE_TTR"] }); // CircleTTRCommand
inventory::submit!(crate::command::CommandRegistration { names: &["CIRCLE_TTT"] }); // CircleTTTCommand
+4
View File
@@ -132,3 +132,7 @@ fn make_donut(cx: f64, cy: f64, inner_r: f64, outer_r: f64) -> EntityType {
p.vertices = vec![v0, v1];
EntityType::LwPolyline(p)
}
// ── Autocomplete registry ─────────────────────────────────
inventory::submit!(crate::command::CommandRegistration { names: &["DO", "DONUT"] }); // DonutCommand
+6
View File
@@ -532,3 +532,9 @@ fn line_wire(from: Vec3, to: Vec3) -> WireModel {
fill_tris: vec![],
}
}
// ── Autocomplete registry ─────────────────────────────────
inventory::submit!(crate::command::CommandRegistration { names: &["ELLIPSE_ARC"] }); // EllipseArcCommand
inventory::submit!(crate::command::CommandRegistration { names: &["ELLIPSE_AXIS"] }); // EllipseAxisCommand
inventory::submit!(crate::command::CommandRegistration { names: &["EL", "ELLIPSE"] }); // EllipseCommand
+6
View File
@@ -423,3 +423,9 @@ impl CadCommand for BoundaryCommand {
CmdResult::Cancel
}
}
// ── Autocomplete registry ─────────────────────────────────
inventory::submit!(crate::command::CommandRegistration { names: &["BOUNDARY"] }); // BoundaryCommand
inventory::submit!(crate::command::CommandRegistration { names: &["GRADIENT"] }); // GradientCommand
inventory::submit!(crate::command::CommandRegistration { names: &["H", "HATCH"] }); // HatchCommand
+4
View File
@@ -161,3 +161,7 @@ impl CadCommand for HatcheditCommand {
CmdResult::Cancel
}
}
// ── Autocomplete registry ─────────────────────────────────
inventory::submit!(crate::command::CommandRegistration { names: &["HATCHEDIT", "HE"] }); // HatcheditCommand
+4
View File
@@ -94,3 +94,7 @@ impl CadCommand for LineCommand {
})
}
}
// ── Autocomplete registry ─────────────────────────────────
inventory::submit!(crate::command::CommandRegistration { names: &["L", "LINE"] }); // LineCommand
+4
View File
@@ -157,3 +157,7 @@ fn build_mline(pts: &[Vec3], scale: f64, closed: bool, style_name: &str) -> Enti
mline.style_name = style_name.to_string();
EntityType::MLine(mline)
}
// ── Autocomplete registry ─────────────────────────────────
inventory::submit!(crate::command::CommandRegistration { names: &["ML", "MLINE"] }); // MlineCommand
+4
View File
@@ -55,3 +55,7 @@ impl CadCommand for PointCommand {
None
}
}
// ── Autocomplete registry ─────────────────────────────────
inventory::submit!(crate::command::CommandRegistration { names: &["PO", "POINT"] }); // PointCommand
+4
View File
@@ -321,3 +321,7 @@ impl CadCommand for PlineCommand {
))
}
}
// ── Autocomplete registry ─────────────────────────────────
inventory::submit!(crate::command::CommandRegistration { names: &["PL", "PLINE"] }); // PlineCommand
+5
View File
@@ -173,3 +173,8 @@ impl CadCommand for XLineCommand {
})
}
}
// ── Autocomplete registry ─────────────────────────────────
inventory::submit!(crate::command::CommandRegistration { names: &["RAY"] }); // RayCommand
inventory::submit!(crate::command::CommandRegistration { names: &["CONSTRUCTIONLINE", "XL", "XLINE"] }); // XLineCommand
+4
View File
@@ -133,3 +133,7 @@ fn make_revcloud(pts: &[Vec3], arc_len: f64) -> EntityType {
p.vertices = vertices;
EntityType::LwPolyline(p)
}
// ── Autocomplete registry ─────────────────────────────────
inventory::submit!(crate::command::CommandRegistration { names: &["REVCLOUD"] }); // RevCloudCommand
+9
View File
@@ -633,3 +633,12 @@ fn edge_poly_params(a: Vec3, b: Vec3, sides: u32) -> Option<(Vec3, f32, f32)> {
let sa = angle_xy(center, a);
Some((center, vr, sa))
}
// ── Autocomplete registry ─────────────────────────────────
inventory::submit!(crate::command::CommandRegistration { names: &["POLY_C"] }); // PolyCCommand
inventory::submit!(crate::command::CommandRegistration { names: &["POL", "POLY", "POLYGON"] }); // PolyCommand
inventory::submit!(crate::command::CommandRegistration { names: &["POLY_E"] }); // PolyECommand
inventory::submit!(crate::command::CommandRegistration { names: &["RECT_CEN"] }); // RectCenCommand
inventory::submit!(crate::command::CommandRegistration { names: &["REC", "RECT", "RECTANG"] }); // RectCommand
inventory::submit!(crate::command::CommandRegistration { names: &["RECT_ROT"] }); // RectRotCommand
+4
View File
@@ -118,3 +118,7 @@ impl CadCommand for SplineCommand {
))
}
}
// ── Autocomplete registry ─────────────────────────────────
inventory::submit!(crate::command::CommandRegistration { names: &["SPL", "SPLINE"] }); // SplineCommand
+4
View File
@@ -59,3 +59,7 @@ impl CadCommand for UngroupCommand {
vec![]
}
}
// ── Autocomplete registry ─────────────────────────────────
inventory::submit!(crate::command::CommandRegistration { names: &["UG", "UNGROUP"] }); // UngroupCommand
+4
View File
@@ -82,3 +82,7 @@ impl CadCommand for AreaCommand {
})
}
}
// ── Autocomplete registry ─────────────────────────────────
inventory::submit!(crate::command::CommandRegistration { names: &["AREA"] }); // AreaCommand
+4
View File
@@ -77,3 +77,7 @@ impl CadCommand for DistCommand {
})
}
}
// ── Autocomplete registry ─────────────────────────────────
inventory::submit!(crate::command::CommandRegistration { names: &["DI", "DIST"] }); // DistCommand
+5
View File
@@ -295,3 +295,8 @@ fn arc_span_rad(start: f64, end: f64) -> f64 {
span
}
}
// ── Autocomplete registry ─────────────────────────────────
inventory::submit!(crate::command::CommandRegistration { names: &["DIV", "DIVIDE"] }); // DivideCommand
inventory::submit!(crate::command::CommandRegistration { names: &["ME", "MEASURE"] }); // MeasureCommand
+4
View File
@@ -34,3 +34,7 @@ impl CadCommand for IdCommand {
CmdResult::Cancel
}
}
// ── Autocomplete registry ─────────────────────────────────
inventory::submit!(crate::command::CommandRegistration { names: &["ID"] }); // IdCommand
+4
View File
@@ -79,3 +79,7 @@ impl CadCommand for LayMatchCommand {
vec![]
}
}
// ── Autocomplete registry ─────────────────────────────────
inventory::submit!(crate::command::CommandRegistration { names: &["LAYMATCH", "LAYMCH"] }); // LayMatchCommand
+4
View File
@@ -189,3 +189,7 @@ impl AlignCommand {
}
}
}
// ── Autocomplete registry ─────────────────────────────────
inventory::submit!(crate::command::CommandRegistration { names: &["AL", "ALIGN"] }); // AlignCommand
+5
View File
@@ -467,3 +467,8 @@ impl CadCommand for BreakAtPointCommand {
CmdResult::Cancel
}
}
// ── Autocomplete registry ─────────────────────────────────
inventory::submit!(crate::command::CommandRegistration { names: &["BAP", "BREAKATPOINT"] }); // BreakAtPointCommand
inventory::submit!(crate::command::CommandRegistration { names: &["BR", "BREAK"] }); // BreakInteractiveCommand
+5
View File
@@ -1706,3 +1706,8 @@ impl CadCommand for ChamferCommand {
CmdResult::Cancel
}
}
// ── Autocomplete registry ─────────────────────────────────
inventory::submit!(crate::command::CommandRegistration { names: &["CHA", "CHAMFER"] }); // ChamferCommand
inventory::submit!(crate::command::CommandRegistration { names: &["F", "FILLET"] }); // FilletCommand
+4
View File
@@ -237,3 +237,7 @@ fn try_join_arcs(arcs: &[&(Handle, &EntityType)]) -> Option<(Vec<Handle>, Vec<En
fn vec3_xz_to_v3(v: Vec3, z: f64) -> Vector3 {
Vector3::new(v.x as f64, v.y as f64, z)
}
// ── Autocomplete registry ─────────────────────────────────
inventory::submit!(crate::command::CommandRegistration { names: &["J", "JOIN"] }); // JoinCommand
+4
View File
@@ -500,3 +500,7 @@ fn lengthen_spline(spl: &SplineEnt, pick_pt: Vec3, mode: &LenMode) -> Option<Ent
Some(EntityType::Spline(bspline_to_spline(&right, spl)))
}
}
// ── Autocomplete registry ─────────────────────────────────
inventory::submit!(crate::command::CommandRegistration { names: &["LEN", "LENGTHEN"] }); // LengthenCommand
+4
View File
@@ -714,3 +714,7 @@ impl CadCommand for OffsetCommand {
CmdResult::Cancel
}
}
// ── Autocomplete registry ─────────────────────────────────
inventory::submit!(crate::command::CommandRegistration { names: &["O", "OFFSET"] }); // OffsetCommand
+4
View File
@@ -138,3 +138,7 @@ pub fn apply_pedit(entity: &mut EntityType, op: &PeditOp) -> bool {
},
}
}
// ── Autocomplete registry ─────────────────────────────────
inventory::submit!(crate::command::CommandRegistration { names: &["PE", "PEDIT"] }); // PeditCommand
+5
View File
@@ -206,3 +206,8 @@ pub fn apply_insert_inverse_transform(entity: &mut EntityType, session: &RefEdit
);
}
}
// ── Autocomplete registry ─────────────────────────────────
inventory::submit!(crate::command::CommandRegistration { names: &["REFCLOSE"] }); // RefCloseCommand
inventory::submit!(crate::command::CommandRegistration { names: &["REFEDIT"] }); // RefEditPickCommand
+4
View File
@@ -200,3 +200,7 @@ pub fn apply_spline_op(doc: &mut acadrust::CadDocument, handle: acadrust::Handle
_ => {}
}
}
// ── Autocomplete registry ─────────────────────────────────
inventory::submit!(crate::command::CommandRegistration { names: &["SPE", "SPLINEDIT"] }); // SplineditCommand
+5
View File
@@ -2457,3 +2457,8 @@ impl CadCommand for ExtendCommand {
CmdResult::Cancel
}
}
// ── Autocomplete registry ─────────────────────────────────
inventory::submit!(crate::command::CommandRegistration { names: &["EX", "EXTEND"] }); // ExtendCommand
inventory::submit!(crate::command::CommandRegistration { names: &["TR", "TRIM"] }); // TrimCommand
@@ -89,3 +89,7 @@ impl CadCommand for MatchPropCommand {
vec![]
}
}
// ── Autocomplete registry ─────────────────────────────────
inventory::submit!(crate::command::CommandRegistration { names: &["MA", "MATCHPROP"] }); // MatchPropCommand
+4
View File
@@ -60,3 +60,7 @@ impl CadCommand for SelectObjectsCommand {
vec![]
}
}
// ── Autocomplete registry ─────────────────────────────────
inventory::submit!(crate::command::CommandRegistration { names: &["AR", "ARRAY", "ARRAYPATH", "ARRAYPOLAR", "ARRAYRECT", "BLOCK", "CC", "CO", "COPY", "COPYCLIP", "CUTCLIP", "CX", "E", "ERASE", "EXPLODE", "G", "GROUP", "LAYFRZ", "LAYLCK", "LAYMCUR", "LAYOFF", "LAYULK", "M", "MI", "MIRROR", "MOVE", "RO", "ROTATE", "SC", "SCALE", "SS", "STRETCH", "X"] }); // SelectObjectsCommand
+4
View File
@@ -210,3 +210,7 @@ impl InsertBlockCommand {
}
}
}
// ── Autocomplete registry ─────────────────────────────────
inventory::submit!(crate::command::CommandRegistration { names: &["INSERT"] }); // InsertBlockCommand
+10
View File
@@ -658,3 +658,13 @@ impl CadCommand for LoftCommand {
pub fn empty_solid3d() -> EntityType {
EntityType::Solid3D(Solid3D::new())
}
// ── Autocomplete registry ─────────────────────────────────
inventory::submit!(crate::command::CommandRegistration { names: &["BOX"] }); // BoxCommand
inventory::submit!(crate::command::CommandRegistration { names: &["CYLINDER"] }); // CylinderCommand
inventory::submit!(crate::command::CommandRegistration { names: &["EXT", "EXTRUDE"] }); // ExtrudeCommand
inventory::submit!(crate::command::CommandRegistration { names: &["LOFT"] }); // LoftCommand
inventory::submit!(crate::command::CommandRegistration { names: &["REV", "REVOLVE"] }); // RevolveCommand
inventory::submit!(crate::command::CommandRegistration { names: &["SPHERE"] }); // SphereCommand
inventory::submit!(crate::command::CommandRegistration { names: &["SWEEP"] }); // SweepCommand
+4
View File
@@ -104,3 +104,7 @@ impl CadCommand for MviewCommand {
})
}
}
// ── Autocomplete registry ─────────────────────────────────
inventory::submit!(crate::command::CommandRegistration { names: &["MV", "MVIEW"] }); // MviewCommand
+4
View File
@@ -106,3 +106,7 @@ impl CadCommand for VplayerCommand {
None
}
}
// ── Autocomplete registry ─────────────────────────────────
inventory::submit!(crate::command::CommandRegistration { names: &["VPLAYER"] }); // VplayerCommand
+4
View File
@@ -75,3 +75,7 @@ impl CadCommand for PlotWindowCommand {
})
}
}
// ── Autocomplete registry ─────────────────────────────────
inventory::submit!(crate::command::CommandRegistration { names: &["PLOTWINDOW", "PW"] }); // PlotWindowCommand