Skip to content

fix(input): freeze Command enum with explicit values (gui-cs/Editor#241)#5524

Merged
tig merged 2 commits into
developfrom
tig/freeze-command-enum
Jun 23, 2026
Merged

fix(input): freeze Command enum with explicit values (gui-cs/Editor#241)#5524
tig merged 2 commits into
developfrom
tig/freeze-command-enum

Conversation

@tig

@tig tig commented Jun 23, 2026

Copy link
Copy Markdown
Member

The bug (tui-cs/Editor#241, still live)

Command was a declaration-ordinal enum — only NotBound = 0 was explicit; every other member took its value from position. Enums compile to integer constants, so a separately-built assembly — notably the Terminal.Gui.Editor package — bakes each command's integer into its key bindings at build time.

When TG 2.4.4 inserted Home near the top of the enum, every later value shifted by +1. An Editor package compiled against the pre-Home ordinals then had its bindings resolve to the wrong commands at runtime — most visibly Backspace invoking SelectAll ("Backspace selects all"). #241 was closed by republishing aligned versions, but the underlying fragility was never removed, so it recurs on any version skew (e.g. the Editor repo currently pins TG 2.4.0, pre-Home, while consumers run 2.4.8).

The fix

Give every Command member an explicit integer value frozen to its current ordinal. This is a pure no-op for the running TG (values are unchanged) but makes the integers an ABI contract: inserting/reordering a member can no longer silently renumber the rest. New commands must be appended with the next unused number.

  • Command.cs: explicit = N on all 92 members + a <remarks> note explaining the contract.
  • CommandFrozenValueTests: locks NotBound = 0, the binding-critical DeleteCharRight=40 / DeleteCharLeft=41 / SelectAll=42 trio, value uniqueness, and a frozen sample — so a future reorder fails CI instead of shipping.

Existing CommandEnumOrderTests continue to pass.

Note

This freeze prevents future drift. Already-published Editor packages built against pre-Home ordinals still need one republish against a post-freeze TG to realign — tracked separately (Editor repo TG-pin bump + release).

🤖 Generated with Claude Code

tig and others added 2 commits June 23, 2026 08:44
Command was a declaration-ordinal enum (only NotBound=0 explicit). Enums
compile to integer constants, so separately-built assemblies — notably the
Terminal.Gui.Editor package — bake each command's integer into their key
bindings. Inserting a member (e.g. Home in 2.4.4) shifted every later value,
re-mapping already-compiled bindings to the wrong command: Backspace invoked
SelectAll (tui-cs/Editor#241).

Assign every member an explicit value frozen to its current ordinal (no
behavior change) so the integers are an ABI contract, plus a doc note and a
CommandFrozenValueTests guard. New commands must be appended with the next
unused number, never inserted or renumbered.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Bump the Editor package 2.4.1 -> 2.5.4 so its compiled-in Command ordinals
match this TG (the frozen enum), fixing the Notepad/ConfigurationEditor
'Backspace selects all' mismatch (tui-cs/Editor#241). 2.5.4 also renamed the
Document/Highlighting namespaces under Terminal.Gui.Editor.*, so update the
scenarios' usings to match.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant