From c6821516e5582ea26e893f38c51e15dd8c33ebcf Mon Sep 17 00:00:00 2001 From: moppeeer Date: Fri, 23 Oct 2026 19:32:08 +0200 Subject: [PATCH] =?UTF-8?q?Edit=20=E2=80=BA=20Clear=20with=20points=20sele?= =?UTF-8?q?cted=20deletes=20the=20points,=20not=20their=20paths?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Delete key already ran path.deletePoints under Direct Selection, but Edit › Clear (the menu item, a native accelerator, or the control channel) called edit.clear, which removed every path whose points were selected. With points selected and no ids given, edit.clear now deletes those points, as InDesign's Clear does. Found by CodeRabbit on #1657. Co-Authored-By: Claude Opus 5.5 --- crates/engine/src/cmd/anchors.rs | 4 ++++ crates/engine/src/cmd/edit.rs | 6 +++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/crates/engine/src/cmd/anchors.rs b/crates/engine/src/cmd/anchors.rs index 6adc9b5c6..1307ddab1 100644 --- a/crates/engine/src/cmd/anchors.rs +++ b/crates/engine/src/cmd/anchors.rs @@ -577,6 +577,10 @@ mod tests { assert_eq!(r["removed"], json!([l])); assert!(s.doc().unwrap().doc.item(ItemId(l)).is_none()); assert!(s.execute("path.deletePoints", &json!({"points": []})).is_err()); + // Edit › Clear with points selected deletes the points, not their paths. + s.execute("selection.set", &json!({"anchors": [[a, 0, 0]]})).unwrap(); + s.execute("edit.clear", &json!({})).unwrap(); + assert_eq!(s.doc().unwrap().doc.item(ItemId(a)).unwrap().path.subpaths[0].anchors.len(), 3, "one point gone, the frame stays"); } #[test] diff --git a/crates/engine/src/cmd/edit.rs b/crates/engine/src/cmd/edit.rs index 1d2a9d1df..3205dd2ba 100644 --- a/crates/engine/src/cmd/edit.rs +++ b/crates/engine/src/cmd/edit.rs @@ -289,7 +289,7 @@ pub fn specs() -> Vec { "Clear", ["Edit"], Some("Delete"), - "{ids?} — delete selected items (or the selected text or ruler guides)", + "{ids?} — delete selected items (or the selected text, points or ruler guides)", has_doc, |s, p| { if s.doc()?.selection.text.is_some() && p.get("ids").is_none() { @@ -298,6 +298,10 @@ pub fn specs() -> Vec { if p.get("ids").is_none() && s.doc()?.selection.items.is_empty() && !s.doc()?.selection.guides.is_empty() { return s.execute("guide.delete", &json!({})); } + // Points selected with Direct Selection: they go, not their paths (as InDesign). + if p.get("ids").is_none() && !s.doc()?.selection.anchors.is_empty() { + return s.execute("path.deletePoints", &json!({})); + } let ids = super::targets(s, p)?; // With a placed graphic itself selected (Direct Selection), only the graphic goes: its // frame stays, empty and selected (as in InDesign). Other items are deleted.