Document Esc and Ctrl bracket mode exits
This commit is contained in:
@@ -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
|
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,
|
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
|
`Space` commits a literal space immediately and `Tab` inserts spaces by default
|
||||||
(expandtab, matching the dotfiles Neovim baseline). Physical keyboards may use
|
(expandtab, matching the dotfiles Neovim baseline). Escape returns to Normal;
|
||||||
conventional direct keys such as Escape as aliases back to Normal, but those
|
Ctrl-[ is the same terminal byte and is documented as the Ctrl-capable SSH alias.
|
||||||
aliases are optional accelerators, not required controls.
|
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
|
### Select mode
|
||||||
|
|
||||||
Selection-building mode. Movement extends the active selection by default.
|
Selection-building mode. Escape or Ctrl-[ returns to Normal. Movement extends the
|
||||||
Vertical movement preserves a preferred cursor column across ragged lines,
|
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
|
clamping only to the current line length until horizontal/editing motion resets
|
||||||
that preference. Semantic object selections live behind the match/object rail
|
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
|
(`m w`, `m l`, `m i`, `m p`, etc.) so bare `h/j/k/l`, word motions, arrows, and
|
||||||
|
|||||||
@@ -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 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 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 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
|
## ui
|
||||||
|
|
||||||
|
|||||||
@@ -290,3 +290,15 @@ test "adversarial: replay names first event mismatch" {
|
|||||||
.ok => return error.ExpectedTraceDivergence,
|
.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);
|
||||||
|
}
|
||||||
|
|||||||
@@ -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("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("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("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("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("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│", "☻")),
|
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│", "☻")),
|
||||||
|
|||||||
Reference in New Issue
Block a user