Gum gum-tool-delete-logic
Reference guide for Gum's delete architecture. Load this when working on delete commands, IEditCommands delete methods, IDeleteLogic, DeleteLogic, DeleteOptionsWindow, HandleDeleteCommand, AskToDeleteState, AskToDeleteStateCategory, or DeleteSelection.
git clone https://github.com/vchelaru/Gum
T=$(mktemp -d) && git clone --depth=1 https://github.com/vchelaru/Gum "$T" && mkdir -p ~/.claude/skills && cp -r "$T/.claude/skills/gum-tool-delete-logic" ~/.claude/skills/vchelaru-gum-gum-tool-delete-logic && rm -rf "$T"
.claude/skills/gum-tool-delete-logic/SKILL.mdGum Delete Logic Reference
Two Delete Patterns
There are two distinct delete flows depending on the object type being deleted.
Pattern 1 — AskTo* (states and categories)
Used for states and state categories. These types have blocking conditions that must be checked before any dialog is shown, so they have their own typed methods on
IEditCommands.
Flow:
IEditCommands.AskTo* → validate (behavior deps, plugin hooks, default-state check) → simple Yes/No dialog → undo lock → IDeleteLogic.Remove*
Entry points:
IEditCommands.AskToDeleteState(stateSave, stateContainer)IEditCommands.AskToDeleteStateCategory(category, container)
Why not DeleteOptionsWindow: States and categories are in-memory only — no XML files, no child hierarchy — so plugins have nothing to contribute to the delete dialog.
Pattern 2 — DeleteSelection (elements, behaviors, instances)
Used for screens, components, behaviors, and instances. All go through one shared entry point that dispatches based on what is currently selected.
Flow:
IEditCommands.DeleteSelection → undo lock → IDeleteLogic.HandleDeleteCommand → DoDeletingLogic → ShowDeleteDialog (creates DeleteOptionsWindow) → IDeleteLogic.Remove*
Entry point:
IEditCommands.DeleteSelection()
Why DeleteOptionsWindow: Plugins contribute runtime UI to this dialog (e.g.
DeleteObjectPlugin adds "Delete XML file?" and "Delete children?" options via the DeleteOptionsWindowShow plugin event).
Responsibility Split
| Class | Responsibility |
|---|---|
/ | All user-triggered deletes. Shows dialogs, acquires undo locks, then delegates to . Only entry point callers should use. |
/ | Pure data mutation after confirmation. methods do not show dialogs. is the exception — it orchestrates the DeleteOptionsWindow flow and is only called from . |
Callers
All delete actions funnel through
IEditCommands:
- Delete key →
→HotkeyManagerIEditCommands.DeleteSelection - Element tree right-click Delete →
→ElementTreeViewManagerIEditCommands.DeleteSelection - State tree right-click Delete state →
→StateTreeViewRightClickServiceIEditCommands.AskToDeleteState - State tree right-click Delete category →
→StateTreeViewRightClickServiceIEditCommands.AskToDeleteStateCategory - Menu strip Remove > Element →
→MenuStripManagerIEditCommands.DeleteSelection - Menu strip Remove > State/Category →
→MenuStripManager
/IEditCommands.AskToDeleteStateAskToDeleteStateCategory
Do not call
IDeleteLogic methods directly from UI code — always go through IEditCommands.
Testability
ShowDeleteDialog creates a WPF DeleteOptionsWindow and calls ShowDialog() — it cannot be unit-tested directly. The internal BuildDeleteDialogMessage(Array, List<InstanceSave>?) method on DeleteLogic is the testable seam for asserting dialog message content (InternalsVisibleTo("GumToolUnitTests") is already configured).
Key Files
| File | Purpose |
|---|---|
| Interface with architecture overview comment |
| Implementation; AskTo* dialog logic lives here |
| Interface for pure data-mutation operations |
| Data mutation + DeleteOptionsWindow orchestration |
| class; and used to build impact warnings in the delete dialog |
| Contributes "Delete XML?" and "Delete children?" to DeleteOptionsWindow |
| State/category right-click menu; calls AskTo* methods |
| Element tree right-click; calls DeleteSelection |
| Delete key handler; calls DeleteSelection |