feat(purge): nested fixpoint purge + option prompt (#375)

PURGE now repeats until a pass removes nothing, so definitions freed by
a purged block (nested blocks, layers, linetypes, styles) go in one run.
Reference scan keeps layer linetypes, ATTDEF/ATTRIB text styles, and
dimstyle DIMTXSTY + arrow blocks; the undo snapshot moves before the
first removal so one UNDO restores everything. Bare PURGE prompts with
clickable category options (aliases B/LA/LT/ST run directly), and
pinned prompts drop their "[A / B / …]" listing when the same options
render as buttons.

Co-Authored-By: Claude Fable 5 <[email protected]>
This commit is contained in:
Hakan SevenandClaude Fable 5 committed 2026-07-21 22:15:33 +03:00
1 parent 5ba8928675
commit 3205f7a2b9
2 files changed
+266 -143

No files matched your search

+22 -2
View File
@@ -22,6 +22,23 @@ fn cmd_input_id() -> iced::widget::Id {
iced::widget::Id::new(CMD_INPUT_ID)
}
/// Drop a prompt's "[A / B / …]" option listing — used for the pinned line
/// when the same options render as clickable buttons beside it. Collapses the
/// leftover double spaces and the orphaned " :" the removal leaves behind.
fn strip_option_listing(s: &str) -> String {
let Some(a) = s.find('[') else {
return s.to_string();
};
let Some(off) = s[a..].find(']') else {
return s.to_string();
};
let mut out = format!("{}{}", &s[..a], &s[a + off + 1..]);
while out.contains(" ") {
out = out.replace(" ", " ");
}
out.replace(" :", ":").trim().to_string()
}
const MAX_HISTORY: usize = 64;
#[derive(Clone, Default)]
@@ -346,9 +363,12 @@ impl CommandLine {
// The current step's prompt is the single pinned line. When the
// step offers options, render them as clickable buttons inline
// beside the prompt text — so options need never be typed and
// don't clutter the prompt string itself. (#304)
// don't clutter the prompt string itself. (#304) The buttons
// already name every choice, so the prompt's own "[A / B / …]"
// listing is dropped here (the history log keeps the full text).
if entry.pinned && !self.step_options.is_empty() {
let mut r = row![text(&entry.text).size(11).color(color)]
let shown = strip_option_listing(&entry.text);
let mut r = row![text(shown).size(11).color(color)]
.spacing(6)
.align_y(iced::Center);
for opt in &self.step_options {