feat(editor): implement vim-style word movement for cursor navigation

This commit is contained in:
lulvz 2025-02-02 13:08:15 +00:00
parent 4b8ba080d7
commit a3864224dd
2 changed files with 20 additions and 14 deletions

View file

@ -10,7 +10,7 @@
"line_numbers": "relative", "line_numbers": "relative",
"cursor": "block", "cursor": "block",
"press": [ "press": [
["b", "move_word_left"], ["b", "move_word_left_vim"],
["w", "move_word_right_vim"], ["w", "move_word_right_vim"],
["e", "move_word_right"], ["e", "move_word_right"],
["x", "delete_forward"], ["x", "delete_forward"],

View file

@ -1945,8 +1945,6 @@ pub const Editor = struct {
'=' => true, '=' => true,
'"' => true, '"' => true,
'\'' => true, '\'' => true,
'\t' => true,
'\n' => true,
'/' => true, '/' => true,
'\\' => true, '\\' => true,
'*' => true, '*' => true,
@ -1976,11 +1974,7 @@ pub const Editor = struct {
} }
fn is_white_space(c: []const u8) bool { fn is_white_space(c: []const u8) bool {
if (c.len == 0) return true; return (c.len == 0) or (c[0] == ' ');
return switch (c[0]) {
' ' => true,
else => false
};
} }
fn is_white_space_at_cursor(root: Buffer.Root, cursor: *const Cursor, metrics: Buffer.Metrics) bool { fn is_white_space_at_cursor(root: Buffer.Root, cursor: *const Cursor, metrics: Buffer.Metrics) bool {
@ -1992,13 +1986,12 @@ pub const Editor = struct {
var next = cursor.*; var next = cursor.*;
next.move_left(root, metrics) catch return true; next.move_left(root, metrics) catch return true;
// right now this doesn't work const next_is_white_space = is_white_space_at_cursor(root, &next, metrics);
// ["enter_vim_mode"], abc if(next_is_white_space) return true;
// jumping from the last " forward once using this command goes to the end of the line
// it should go to the start of abc
const curr_is_non_word = is_non_word_char_at_cursor_vim(root, cursor, metrics); const curr_is_non_word = is_non_word_char_at_cursor_vim(root, cursor, metrics);
const prev_is_non_word = is_non_word_char_at_cursor_vim(root, &next, metrics); const next_is_non_word = is_non_word_char_at_cursor_vim(root, &next, metrics);
return curr_is_non_word != prev_is_non_word; return curr_is_non_word != next_is_non_word;
} }
fn is_non_word_boundary_left(root: Buffer.Root, cursor: *const Cursor, metrics: Buffer.Metrics) bool { fn is_non_word_boundary_left(root: Buffer.Root, cursor: *const Cursor, metrics: Buffer.Metrics) bool {
@ -2619,6 +2612,11 @@ pub const Editor = struct {
move_cursor_left_until(root, cursor, is_word_boundary_left, metrics); move_cursor_left_until(root, cursor, is_word_boundary_left, metrics);
} }
fn move_cursor_word_left_vim(root: Buffer.Root, cursor: *Cursor, metrics: Buffer.Metrics) error{Stop}!void {
try move_cursor_left(root, cursor, metrics);
move_cursor_left_until(root, cursor, is_word_boundary_left_vim, metrics);
}
fn move_cursor_word_left_space(root: Buffer.Root, cursor: *Cursor, metrics: Buffer.Metrics) error{Stop}!void { fn move_cursor_word_left_space(root: Buffer.Root, cursor: *Cursor, metrics: Buffer.Metrics) error{Stop}!void {
try move_cursor_left(root, cursor, metrics); try move_cursor_left(root, cursor, metrics);
var next = cursor.*; var next = cursor.*;
@ -2661,6 +2659,14 @@ pub const Editor = struct {
} }
pub const move_word_left_meta = .{ .description = "Move cursor left by word" }; pub const move_word_left_meta = .{ .description = "Move cursor left by word" };
pub fn move_word_left_vim(self: *Self, _: Context) Result {
const root = try self.buf_root();
self.with_cursors_const(root, move_cursor_word_left_vim) catch {};
self.clamp();
}
pub const move_word_left_vim_meta = .{ .description = "Move cursor left by word (vim)" };
pub fn move_word_right(self: *Self, _: Context) Result { pub fn move_word_right(self: *Self, _: Context) Result {
const root = try self.buf_root(); const root = try self.buf_root();
self.with_cursors_const(root, move_cursor_word_right) catch {}; self.with_cursors_const(root, move_cursor_word_right) catch {};