From e13de2c2f1d82c7ca2e82a587cf72b8490ee7561 Mon Sep 17 00:00:00 2001 From: MarekSpodBiedry <73122968+MarekSpodBiedry@users.noreply.github.com> Date: Sat, 10 Oct 2026 20:39:28 +0200 Subject: [PATCH] Layer delete and purge keep layers used by block definitions (#72) (#189) --- crates/engine/src/cmd/blocks.rs | 3 ++- crates/engine/src/cmd/layer.rs | 17 ++++++++++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/crates/engine/src/cmd/blocks.rs b/crates/engine/src/cmd/blocks.rs index f6ee909..ba82fc7 100644 --- a/crates/engine/src/cmd/blocks.rs +++ b/crates/engine/src/cmd/blocks.rs @@ -268,7 +268,8 @@ fn run_purge(s: &mut Session, _p: &Value) -> Result { let before_b = d.blocks.len(); d.blocks.retain(|k, _| used.contains(&k.to_ascii_uppercase())); let blocks = before_b - d.blocks.len(); - let used_layers: std::collections::HashSet = all.iter().map(|e| e.common.layer.to_ascii_lowercase()).collect(); + // Layers used by the model, layouts and the block definitions that survived above. + let used_layers = super::layer::used_layers(d); let cur = d.header.str("CLAYER", "0").to_ascii_lowercase(); let before_l = d.layers.len(); d.layers.retain(|l| { diff --git a/crates/engine/src/cmd/layer.rs b/crates/engine/src/cmd/layer.rs index d902ec6..1867ce9 100644 --- a/crates/engine/src/cmd/layer.rs +++ b/crates/engine/src/cmd/layer.rs @@ -238,7 +238,8 @@ fn run_delete(s: &mut Session, p: &Value) -> Result { return Err(bad("layer.delete", "cannot delete layer 0, Defpoints or the current layer")); } let used = d.model.iter().any(|e| e.common.layer.eq_ignore_ascii_case(&name)) - || d.layouts.iter().any(|l| l.entities.iter().any(|e| e.common.layer.eq_ignore_ascii_case(&name))); + || d.layouts.iter().any(|l| l.entities.iter().any(|e| e.common.layer.eq_ignore_ascii_case(&name))) + || d.blocks.values().any(|b| b.entities.iter().any(|e| e.common.layer.eq_ignore_ascii_case(&name))); if used { return Err(bad("layer.delete", "layer has objects on it")); } @@ -438,4 +439,18 @@ mod tests { s.execute("layer.set", &json!({ "name": "0", "color": 3 })).unwrap(); assert_ne!(s.doc().unwrap().layer("0").unwrap(), &before); } + + #[test] + fn delete_and_purge_keep_layers_used_by_block_definitions() { + let mut s = Session::new(); + s.execute("layer.new", &json!({ "name": "A", "color": 1 })).unwrap(); + s.execute("layer.current", &json!({ "name": "A" })).unwrap(); + let l = s.execute("line", &json!({ "points": [[0, 0], [1, 1]] })).unwrap()["handles"][0].as_str().unwrap().to_string(); + s.execute("block", &json!({ "name": "B", "base": [0, 0], "handles": [l], "keep": "delete" })).unwrap(); + s.execute("layer.current", &json!({ "name": "0" })).unwrap(); + s.execute("insert", &json!({ "name": "B", "at": [5, 5] })).unwrap(); + assert!(s.execute("layer.delete", &json!({ "name": "A" })).is_err()); + s.execute("purge", &json!({})).unwrap(); + assert!(s.doc().unwrap().layer("A").is_some()); + } }