Add select object rail
This commit is contained in:
@@ -134,12 +134,12 @@ Selection-building mode. Escape or Ctrl-[ returns to Normal. Movement extends th
|
||||
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
|
||||
mobile line aliases keep behaving as selection-extending motions. Line object
|
||||
selection includes the line's newline boundary when present, matching Vim-like
|
||||
linewise edit semantics. Select mode can apply operations such as delete,
|
||||
replace, copy, format, code action, or explain to the selection.
|
||||
that preference. Semantic object selections live behind the select-object rail
|
||||
(`s` then `o w`, `o l`, `o i`, `o p`, etc.) so bare `h/j/k/l`, word motions,
|
||||
arrows, and mobile line aliases keep behaving as selection-extending motions.
|
||||
Line object selection includes the line's newline boundary when present, matching
|
||||
Vim-like linewise edit semantics. Select mode can apply operations such as
|
||||
delete, replace, copy, format, code action, or explain to the selection.
|
||||
|
||||
### Panel mode
|
||||
|
||||
@@ -254,12 +254,13 @@ Objects are shared by Normal and Select mode.
|
||||
| `m` `{` | jump/select `{}` pair, depending on mode |
|
||||
| `m` `[` | jump/select `[]` pair, depending on mode |
|
||||
| `m` `"` / `m` `'` / `m` `` ` `` | jump/select quoted string where parseable |
|
||||
| `s` `w` | select word |
|
||||
| `s` `l` | select line |
|
||||
| `s` `i` | select current indent block |
|
||||
| `s` `p` | select current parameter/argument |
|
||||
| `s` `f` | select current function or syntactic enclosing form where available |
|
||||
| `s` `d` | select current diagnostic range |
|
||||
| `s` then motion | enter Select mode and extend the selection with that motion |
|
||||
| `s` `o` `w` | select word |
|
||||
| `s` `o` `l` | select line |
|
||||
| `s` `o` `i` | select current indent block |
|
||||
| `s` `o` `p` | select current parameter/argument |
|
||||
| `s` `o` `f` | select current function or syntactic enclosing form where available |
|
||||
| `s` `o` `d` | select current diagnostic range |
|
||||
|
||||
Physical keyboards may expose `%` as an alias for `m m`. The mobile canonical
|
||||
path stays `m m` because `%` is awkward on software keyboards and QWERTZ.
|
||||
|
||||
@@ -28,6 +28,7 @@ Rows are redgate TSV requirements: `ring<TAB>id<TAB>summary [tag]`.
|
||||
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]
|
||||
1 018 Select mode SHALL keep bare movement keys as selection-extending motions and provide a non-conflicting mobile object-selection rail for word, line, indent, parameter, enclosing form, and diagnostic ranges. [mobile]
|
||||
|
||||
## ui
|
||||
|
||||
|
||||
+18
@@ -33,6 +33,7 @@ const PrefixRail = enum {
|
||||
none,
|
||||
insert_space,
|
||||
match,
|
||||
select_object,
|
||||
go,
|
||||
repeat,
|
||||
delete,
|
||||
@@ -568,6 +569,7 @@ pub const Client = struct {
|
||||
.none => if (self.pending_count != 0) "count pending" else "",
|
||||
.insert_space => "insert-space: n normal Space literal text commits space+text",
|
||||
.match => "match: m jump s inside a around ( { [ quotes",
|
||||
.select_object => "select-object: w word l line i indent p param f form d diagnostic",
|
||||
.go => "go: d definition r references e diagnostic a parameter",
|
||||
.repeat => "repeat: digits count . repeat-last",
|
||||
.delete => "delete: d line h previous-char l char",
|
||||
@@ -1198,6 +1200,7 @@ pub const Client = struct {
|
||||
if (std.mem.eql(u8, text, "b")) return self.repeatSelectionProtocol("command move_word_back", self.takeRepeat());
|
||||
if (std.mem.eql(u8, text, "e")) return self.repeatSelectionProtocol("command move_word_end", self.takeRepeat());
|
||||
if (std.mem.eql(u8, text, "m")) return self.openPrefix(.match);
|
||||
if (std.mem.eql(u8, text, "o")) return self.openPrefix(.select_object);
|
||||
if (std.mem.eql(u8, text, "g")) return self.openPrefix(.go);
|
||||
if (text.len == 1) {
|
||||
if (self.objectRangeForKey(text[0])) |range| {
|
||||
@@ -1256,6 +1259,9 @@ pub const Client = struct {
|
||||
.match => self.applyMatchRail(event) catch |err| {
|
||||
self.message = @errorName(err);
|
||||
},
|
||||
.select_object => self.applySelectObjectRail(event) catch |err| {
|
||||
self.message = @errorName(err);
|
||||
},
|
||||
.go => try self.applyGoRail(event),
|
||||
.repeat => self.applyKnownRailOrMessage(event, "repeat rail ready"),
|
||||
.delete => try self.applyDeleteRail(event),
|
||||
@@ -1878,6 +1884,18 @@ pub const Client = struct {
|
||||
self.applyKnownRailOrMessage(event, "go rail ready");
|
||||
}
|
||||
|
||||
fn applySelectObjectRail(self: *Client, event: input.Event) !void {
|
||||
const text = eventText(event) orelse return self.unknownPrefixOrInput("select object");
|
||||
if (text.len == 1) {
|
||||
const range = try self.objectRangeForKey(text[0]);
|
||||
try self.session.selectRange(range.start, range.end);
|
||||
self.mode = .select;
|
||||
self.message = "selected object";
|
||||
return;
|
||||
}
|
||||
self.unknownPrefixOrInput("select object");
|
||||
}
|
||||
|
||||
const ParameterDirection = enum { next, previous };
|
||||
|
||||
fn moveParameter(self: *Client, direction: ParameterDirection) !void {
|
||||
|
||||
@@ -552,6 +552,7 @@ SCENARIOS = [
|
||||
Scenario("counted-move-inserts-at-count", 56, 12, "short", "attached-keyboard", "counts", "truecolor", "file", setup_short, (b"3", b"l", b"i", b"X", b"\x1b", b" ", b"w", b" ", b"q"), "abcXdef", ("1│", "☻")),
|
||||
Scenario("percent-match-jump", 56, 12, "brackets", "attached-keyboard", "match-jump", "truecolor", "file", setup_brackets, (b"%", b"i", b"X", b"\x1b", b" ", b"w", b" ", b"q"), "(abX)", ("1│", "☻")),
|
||||
Scenario("select-mode-motions", 56, 12, "short", "attached-keyboard", "select", "truecolor", "file", setup_short, (b"L", b"s", b"H", b"L", b"n", b" ", b"q"), "abcdef\n", ("attr:selection", "░", "mode:normal")),
|
||||
Scenario("select-object-word-rail", 56, 12, "short", "attached-keyboard", "select-object", "truecolor", "file", setup_short, (b"s", b"o", b"w", b"n", b" ", b"q"), "abcdef\n", ("attr:selection", "mode:normal")),
|
||||
Scenario("first-nonblank-line-motion", 56, 12, "indented", "attached-keyboard", "line-edges", "truecolor", "file", setup_indented, (b"L", b"^", b"i", b"X", b"\x1b", b" ", b"w", b" ", b"q"), " Xitem", ("1│", "☻", "mode:normal")),
|
||||
Scenario("horizontal-cursor-scroll", 24, 8, "wide-line", "attached-keyboard", "horizontal-scroll", "truecolor", "file", setup_long_line, (b"L", b" ", b"q"), "abcdefghijklmnopqrstuvwxyz0123456789\n", ("0123456789", "☻", "mode:normal")),
|
||||
Scenario("vertical-motion-preferred-column", 56, 12, "ragged", "attached-keyboard", "motion", "truecolor", "file", setup_ragged, (b"L", b"j", b"j", b"i", b"X", b"\x1b", b" ", b"w", b" ", b"q"), "abcdef\nxy\n123456X", ("1│", "3│", "☻", "mode:normal")),
|
||||
|
||||
Reference in New Issue
Block a user