Document Esc and Ctrl bracket mode exits

This commit is contained in:
slhx agent
2026-06-21 22:29:20 +02:00
parent 2e60a0961c
commit d5c31a92c5
4 changed files with 23 additions and 5 deletions
+9 -5
View File
@@ -121,14 +121,18 @@ selection entry, leader rails, tool commands, save/quit, and recoverability.
Text-entry mode for ordinary typing. `mim` starts in Normal mode; Insert mode is
entered explicitly with `i`, `a`, `o`, or another visible command. In Insert mode,
`Space` commits a literal space immediately and `Tab` inserts spaces by default
(expandtab, matching the dotfiles Neovim baseline). Physical keyboards may use
conventional direct keys such as Escape as aliases back to Normal, but those
aliases are optional accelerators, not required controls.
(expandtab, matching the dotfiles Neovim baseline). Escape returns to Normal;
Ctrl-[ is the same terminal byte and is documented as the Ctrl-capable SSH alias.
This preserves ordinary spaces and avoids reviving a Space-prefix escape chord.
If a client exposes neither Esc nor Ctrl-[, it is missing the mobile SSH
accelerator tier required for safe Insert-mode recovery; use the client's Esc
toolbar or an attached-keyboard path rather than overloading literal text input.
### Select mode
Selection-building mode. Movement extends the active selection by default.
Vertical movement preserves a preferred cursor column across ragged lines,
Selection-building mode. Escape or Ctrl-[ returns to Normal. Movement extends the
active selection by default. Vertical movement preserves a preferred cursor
column across ragged lines,
clamping only to the current line length until horizontal/editing motion resets
that preference. Semantic object selections live behind the match/object rail
(`m w`, `m l`, `m i`, `m p`, etc.) so bare `h/j/k/l`, word motions, arrows, and
+1
View File
@@ -27,6 +27,7 @@ Rows are redgate TSV requirements: `ring<TAB>id<TAB>summary [tag]`.
1 014 Normal-mode dot repeat SHALL replay the last deterministic local edit for the supported insert/change/delete/put subset without recording panel, search, or external side effects. [mobile]
1 015 The keymap SHALL classify bindings into core mobile, mobile SSH accelerator, and attached-keyboard tiers so Esc/Ctrl/arrow-capable clients can be used without making those keys mandatory for core commands. [mobile]
1 016 Every attached-keyboard or Ctrl/Esc accelerator that performs a core editing, navigation, recovery, or panel action SHALL have a documented visible mobile fallback or rail path. [mobile]
1 017 Insert and Select mode SHALL return to Normal via Escape and Ctrl-[ as equivalent terminal events while preserving literal Insert-mode Space. [mobile]
## ui
+12
View File
@@ -290,3 +290,15 @@ test "adversarial: replay names first event mismatch" {
.ok => return error.ExpectedTraceDivergence,
}
}
test "regular: Ctrl-[ normalizes as escape" {
try std.testing.expectEqual(Event{ .key = .escape }, normalize("\x1b"));
}
test "regular: Ctrl-[ trace labels as escape" {
var recorder = TraceRecorder.init(std.testing.allocator);
defer recorder.deinit();
try recorder.capture("\x1b");
try std.testing.expect(std.mem.indexOf(u8, recorder.text(), "escape") != null);
}
+1
View File
@@ -542,6 +542,7 @@ SCENARIOS = [
Scenario("attached-existing-medium", 72, 18, "existing", "attached-keyboard", "insert-normal", "truecolor", "file", setup_existing, ATTACHED_SAVE_QUIT, "alpha!\nbeta", ("1│", "2│", ""), max_key_events=8),
Scenario("new-file-mono-narrow", 40, 12, "new", "ios-default-qwertz-space-path", "normal-symbol-save", "mono", "file", setup_new, MOBILE_SYMBOL_SAVE_QUIT, "/", ("1│", "", "mode:normal")),
Scenario("esc-attached-key-mode-switch", 56, 14, "empty", "attached-keyboard", "insert-normal", "truecolor", "file", setup_empty, (b"i", b"e", b"s", b"c", b"\x1b", b" ", b"w", b" ", b"q"), "esc", ("1│", "", "mode:normal")),
Scenario("ctrl-bracket-mode-switch", 56, 14, "empty", "attached-keyboard", "insert-normal", "truecolor", "file", setup_empty, (b"i", b"c", b"t", b"r", b"l", b"\x1b", b" ", b"w", b" ", b"q"), "ctrl", ("1│", "", "mode:normal"), forbidden_raw=("^[",)),
Scenario("attached-cursor-left-insert", 56, 14, "empty", "attached-keyboard", "insert-cursor", "truecolor", "file", setup_empty, (b"i", b"a", b"b", b"\x1b[D", b"X", b"\x1b", b" ", b"w", b" ", b"q"), "aXb", ("1│", "", "aX", "mode:normal")),
Scenario("normal-A-append", 56, 14, "existing", "attached-keyboard", "append-eol", "truecolor", "file", setup_existing, (b"A", b"!", b"\x1b", b" ", b"w", b" ", b"q"), "alpha!\nbeta", ("1│", "", "alpha")),
Scenario("insert-enter-indent", 56, 14, "indented", "attached-keyboard", "newline-indent", "truecolor", "file", setup_indented, (b"A", b"\r", b"x", b"\x1b", b" ", b"w", b" ", b"q"), " item\n x", ("1│", "2│", "")),