forked from 1b-agent/opencadstudio-upstream
fix(insert): capped interactive block search and CLIPROMPTLINES
INSERT enumerated all block names in a single prompt string, causing unbounded overlay growth and full-screen occlusion in drawings with many blocks. Replace prompt enumeration with a ranked, incrementally filtered suggestion model: BlockPicker maintains precomputed lower/upper caches and usage ranks (MRU/frequency), filters via O(n) substring scan and partial sorting (select_nth_unstable) to O(k), bounded to CLIPROMPTLINES. Introduce CLIPROMPTLINES (Integer 0-50, Registry, default 3) for the number of temporary prompt lines above the command window; persist in UserSettings, expose via SETVAR and direct entry, enforce in CommandLine::view. Suggestion count is in direct relation to CLIPROMPTLINES (limit = clip, capped to 50). Make search live without requiring Enter: add CadCommand::on_live_input, implement for INSERT/MINSERT via picker.set_needle, and wire to command-line input paths (Message::CommandInput, on_command_append_char, on_command_backspace). Updates use upper/lower caches and partial sort for <0.2ms per keystroke on 10k blocks, with debounced block-usage persistence (MRU cap 20, freq cap 200) to avoid I/O thrash. Correct tri_count test helper to use display_from_solid.
This commit is contained in:
1 parent
cefe861203
commit
9c8f841f71
16 files changed
+691
-37
No files matched your search
@@ -330,8 +330,16 @@ impl OpenCADStudio {
|
||||
.push_error(crate::t!("No user-defined blocks found in this drawing.").as_ref());
|
||||
} else {
|
||||
use crate::modules::insert::insert_block::InsertBlockCommand;
|
||||
let cmd = InsertBlockCommand::new(blocks);
|
||||
let ranked = self.ranked_block_names(&blocks);
|
||||
let snapshot = self.block_usage_snapshot();
|
||||
let cmd = InsertBlockCommand::new_with_usage(
|
||||
ranked,
|
||||
snapshot,
|
||||
self.cliprompt_lines.clamp(0, 50) as u8,
|
||||
);
|
||||
self.command_line.push_info(&cmd.prompt());
|
||||
let opts = cmd.options();
|
||||
self.command_line.set_step_options(opts.clone());
|
||||
self.tabs[i].active_cmd = Some(Box::new(cmd));
|
||||
}
|
||||
}
|
||||
@@ -343,8 +351,16 @@ impl OpenCADStudio {
|
||||
.push_error(crate::t!("No user-defined blocks found in this drawing.").as_ref());
|
||||
} else {
|
||||
use crate::modules::insert::minsert::MinsertCommand;
|
||||
let cmd = MinsertCommand::new(blocks);
|
||||
let ranked = self.ranked_block_names(&blocks);
|
||||
let snapshot = self.block_usage_snapshot();
|
||||
let cmd = MinsertCommand::new_with_usage(
|
||||
ranked,
|
||||
snapshot,
|
||||
self.cliprompt_lines.clamp(0, 50) as u8,
|
||||
);
|
||||
self.command_line.push_info(&cmd.prompt());
|
||||
let opts = cmd.options();
|
||||
self.command_line.set_step_options(opts.clone());
|
||||
self.tabs[i].active_cmd = Some(Box::new(cmd));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -533,6 +533,7 @@ inventory::submit!(crate::command::CommandRegistration {
|
||||
"SKETCHINC",
|
||||
"SKPOLY",
|
||||
"SKTOLERANCE",
|
||||
"CLIPROMPTLINES",
|
||||
// Reset selected entities' overrides to follow their layer.
|
||||
"SETBYLAYER",
|
||||
// Remove duplicate objects; set drawing base point; audit integrity;
|
||||
|
||||
@@ -879,6 +879,7 @@ impl OpenCADStudio {
|
||||
| "CURSORTYPE"
|
||||
| "SNAPANG"
|
||||
| "TEXTFILL"
|
||||
| "CLIPROMPTLINES"
|
||||
| "ATTREQ"
|
||||
| "ATTDIA"
|
||||
| "DIMASSOC"
|
||||
@@ -967,7 +968,7 @@ impl OpenCADStudio {
|
||||
let value = it.next().map(|s| s.trim().to_string());
|
||||
if name.is_empty() || name == "?" {
|
||||
self.command_line.push_info(
|
||||
"SETVAR: LTSCALE CELTSCALE PDMODE PDSIZE TEXTSIZE ORTHOMODE FILLMODE MIRRTEXT FRAME IMAGEFRAME PDFFRAME WIPEOUTFRAME XCLIPFRAME POINTCLOUDCLIPFRAME ZOOMWHEEL ZOOMFACTOR CURSORSIZE PICKBOX CURSORTYPE SNAPANG ATTREQ ATTDIA DIMASSOC ANGBASE ANGDIR SKETCHINC SKPOLY SKTOLERANCE DONUTID DONUTOD CENTEREXE CENTERLAYER CENTERLTYPE CENTERLTSCALE CENTERLTYPEFILE CENTERCROSSSIZE CENTERCROSSGAP CENTERMARKEXE | CLAYER CELTYPE TEXTSTYLE (read-only)",
|
||||
"SETVAR: LTSCALE CELTSCALE PDMODE PDSIZE TEXTSIZE ORTHOMODE FILLMODE MIRRTEXT FRAME IMAGEFRAME PDFFRAME WIPEOUTFRAME XCLIPFRAME POINTCLOUDCLIPFRAME ZOOMWHEEL ZOOMFACTOR CURSORSIZE PICKBOX CURSORTYPE SNAPANG TEXTFILL CLIPROMPTLINES ATTREQ ATTDIA DIMASSOC ANGBASE ANGDIR SKETCHINC SKPOLY SKTOLERANCE DONUTID DONUTOD CENTEREXE CENTERLAYER CENTERLTYPE CENTERLTSCALE CENTERLTYPEFILE CENTERCROSSSIZE CENTERCROSSGAP CENTERMARKEXE | CLAYER CELTYPE TEXTSTYLE (read-only)",
|
||||
);
|
||||
} else {
|
||||
let frame_kind = crate::scene::frame::kind_for_name(&name);
|
||||
@@ -1313,6 +1314,20 @@ impl OpenCADStudio {
|
||||
false,
|
||||
)),
|
||||
},
|
||||
"CLIPROMPTLINES" => match &value {
|
||||
Some(v) => match v.parse::<i32>() {
|
||||
Ok(n) if (0..=50).contains(&n) => {
|
||||
self.cliprompt_lines = n;
|
||||
self.command_line.set_cliprompt_lines(n as u8);
|
||||
Ok((format!("CLIPROMPTLINES = {n}"), true))
|
||||
}
|
||||
_ => Err("SETVAR: integer from 0 to 50 required.".into()),
|
||||
},
|
||||
None => Ok((
|
||||
format!("CLIPROMPTLINES = {}", self.cliprompt_lines),
|
||||
false,
|
||||
)),
|
||||
},
|
||||
"ATTREQ" => match &value {
|
||||
Some(v) => parse_bool(v)
|
||||
.map(|b| {
|
||||
@@ -1889,6 +1904,7 @@ impl OpenCADStudio {
|
||||
| "PICKBOX"
|
||||
| "CURSORTYPE"
|
||||
| "SNAPANG"
|
||||
| "CLIPROMPTLINES"
|
||||
) {
|
||||
self.persist_settings_if_changed();
|
||||
} else {
|
||||
|
||||
Reference in new issue
Block a user