refactor: [hx] move and extend word sharing common code

This commit is contained in:
Igor Támara 2025-10-30 15:44:14 -05:00 committed by CJ van den Berg
parent c3bd6b6bc3
commit 8d2355dcb8
2 changed files with 49 additions and 87 deletions

View file

@ -1904,7 +1904,7 @@ pub const Editor = struct {
self.collapse_cursors(); self.collapse_cursors();
} }
fn with_cursors_const_repeat(self: *Self, root: Buffer.Root, move: cursor_operator_const, ctx: Context) error{Stop}!void { pub fn with_cursors_const_repeat(self: *Self, root: Buffer.Root, move: cursor_operator_const, ctx: Context) error{Stop}!void {
var repeat: usize = 1; var repeat: usize = 1;
_ = ctx.args.match(.{tp.extract(&repeat)}) catch false; _ = ctx.args.match(.{tp.extract(&repeat)}) catch false;
while (repeat > 0) : (repeat -= 1) { while (repeat > 0) : (repeat -= 1) {
@ -2138,7 +2138,7 @@ pub const Editor = struct {
} }
const cursor_predicate = *const fn (root: Buffer.Root, cursor: *Cursor, metrics: Buffer.Metrics) bool; const cursor_predicate = *const fn (root: Buffer.Root, cursor: *Cursor, metrics: Buffer.Metrics) bool;
const cursor_operator_const = *const fn (root: Buffer.Root, cursor: *Cursor, metrics: Buffer.Metrics) error{Stop}!void; pub const cursor_operator_const = *const fn (root: Buffer.Root, cursor: *Cursor, metrics: Buffer.Metrics) error{Stop}!void;
const cursor_operator_const_arg = *const fn (root: Buffer.Root, cursor: *Cursor, ctx: Context, metrics: Buffer.Metrics) error{Stop}!void; const cursor_operator_const_arg = *const fn (root: Buffer.Root, cursor: *Cursor, ctx: Context, metrics: Buffer.Metrics) error{Stop}!void;
pub const cursel_operator_mut_once_arg = *const fn (root: Buffer.Root, cursel: *CurSel, ctx: Context, metrics: Buffer.Metrics) error{Stop}!void; pub const cursel_operator_mut_once_arg = *const fn (root: Buffer.Root, cursel: *CurSel, ctx: Context, metrics: Buffer.Metrics) error{Stop}!void;
const cursor_view_operator_const = *const fn (root: Buffer.Root, cursor: *Cursor, view: *const View, metrics: Buffer.Metrics) error{Stop}!void; const cursor_view_operator_const = *const fn (root: Buffer.Root, cursor: *Cursor, view: *const View, metrics: Buffer.Metrics) error{Stop}!void;
@ -3232,7 +3232,7 @@ 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 { pub fn move_cursor_word_left_vim(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);
move_cursor_left_until(root, cursor, is_word_boundary_left_vim, metrics); move_cursor_left_until(root, cursor, is_word_boundary_left_vim, metrics);
} }

View file

@ -220,126 +220,62 @@ const cmds_ = struct {
pub const extend_line_below_meta: Meta = .{ .arguments = &.{.integer}, .description = "Select current line, if already selected, extend to next line" }; pub const extend_line_below_meta: Meta = .{ .arguments = &.{.integer}, .description = "Select current line, if already selected, extend to next line" };
pub fn move_next_word_start(_: *void, ctx: Ctx) Result { pub fn move_next_word_start(_: *void, ctx: Ctx) Result {
const mv = tui.mainview() orelse return; try move_to_word(ctx, Editor.move_cursor_word_right_vim);
const ed = mv.get_active_editor() orelse return;
const root = try ed.buf_root();
for (ed.cursels.items) |*cursel_| if (cursel_.*) |*cursel| {
cursel.selection = null;
};
ed.with_selections_const_repeat(root, Editor.move_cursor_word_right_vim, ctx) catch {};
ed.clamp();
} }
pub const move_next_word_start_meta: Meta = .{ .description = "Move next word start", .arguments = &.{.integer} }; pub const move_next_word_start_meta: Meta = .{ .description = "Move next word start", .arguments = &.{.integer} };
pub fn extend_next_word_start(_: *void, ctx: Ctx) Result { pub fn extend_next_word_start(_: *void, ctx: Ctx) Result {
const mv = tui.mainview() orelse return; try extend_to_word(ctx, Editor.move_cursor_word_right_vim);
const ed = mv.get_active_editor() orelse return;
const root = try ed.buf_root();
ed.with_selections_const_repeat(root, Editor.move_cursor_word_right_vim, ctx) catch {};
ed.clamp();
} }
pub const extend_next_word_start_meta: Meta = .{ .description = "Extend next word start", .arguments = &.{.integer} }; pub const extend_next_word_start_meta: Meta = .{ .description = "Extend next word start", .arguments = &.{.integer} };
pub fn move_next_long_word_start(_: *void, ctx: Ctx) Result { pub fn move_next_long_word_start(_: *void, ctx: Ctx) Result {
const mv = tui.mainview() orelse return; try move_to_word(ctx, move_cursor_long_word_right);
const ed = mv.get_active_editor() orelse return;
const root = try ed.buf_root();
for (ed.cursels.items) |*cursel_| if (cursel_.*) |*cursel| {
cursel.selection = null;
};
ed.with_selections_const_repeat(root, move_cursor_long_word_right, ctx) catch {};
ed.clamp();
} }
pub const move_next_long_word_start_meta: Meta = .{ .description = "Move next long word start", .arguments = &.{.integer} }; pub const move_next_long_word_start_meta: Meta = .{ .description = "Move next long word start", .arguments = &.{.integer} };
pub fn extend_next_long_word_start(_: *void, ctx: Ctx) Result { pub fn extend_next_long_word_start(_: *void, ctx: Ctx) Result {
const mv = tui.mainview() orelse return; try extend_to_word(ctx, move_cursor_long_word_right);
const ed = mv.get_active_editor() orelse return;
const root = try ed.buf_root();
ed.with_selections_const_repeat(root, move_cursor_long_word_right, ctx) catch {};
ed.clamp();
} }
pub const extend_next_long_word_start_meta: Meta = .{ .description = "Extend next long word start", .arguments = &.{.integer} }; pub const extend_next_long_word_start_meta: Meta = .{ .description = "Extend next long word start", .arguments = &.{.integer} };
pub fn move_prev_word_start(_: *void, ctx: Ctx) Result { pub fn move_prev_word_start(_: *void, ctx: Ctx) Result {
const mv = tui.mainview() orelse return; try move_to_word(ctx, move_cursor_word_left_helix);
const ed = mv.get_active_editor() orelse return;
const root = try ed.buf_root();
for (ed.cursels.items) |*cursel_| if (cursel_.*) |*cursel| {
cursel.selection = null;
};
ed.with_selections_const_repeat(root, move_cursor_word_left_helix, ctx) catch {};
ed.clamp();
} }
pub const move_prev_word_start_meta: Meta = .{ .description = "Move previous word start", .arguments = &.{.integer} }; pub const move_prev_word_start_meta: Meta = .{ .description = "Move previous word start", .arguments = &.{.integer} };
pub fn extend_prev_word_start(_: *void, ctx: Ctx) Result {
try extend_to_word(ctx, move_cursor_word_left_helix);
}
pub const extend_prev_word_start_meta: Meta = .{ .description = "Extend previous word start", .arguments = &.{.integer} };
pub fn move_prev_long_word_start(_: *void, ctx: Ctx) Result { pub fn move_prev_long_word_start(_: *void, ctx: Ctx) Result {
const mv = tui.mainview() orelse return; try move_to_word(ctx, move_cursor_long_word_left);
const ed = mv.get_active_editor() orelse return;
const root = try ed.buf_root();
for (ed.cursels.items) |*cursel_| if (cursel_.*) |*cursel| {
cursel.selection = null;
};
ed.with_selections_const_repeat(root, move_cursor_long_word_left, ctx) catch {};
ed.clamp();
} }
pub const move_prev_long_word_start_meta: Meta = .{ .description = "Move previous long word start", .arguments = &.{.integer} }; pub const move_prev_long_word_start_meta: Meta = .{ .description = "Move previous long word start", .arguments = &.{.integer} };
pub fn extend_prev_long_word_start(_: *void, ctx: Ctx) Result {
try extend_to_word(ctx, move_cursor_long_word_left);
}
pub const extend_prev_long_word_start_meta: Meta = .{ .description = "Extend previous word start", .arguments = &.{.integer} };
pub fn move_next_word_end(_: *void, ctx: Ctx) Result { pub fn move_next_word_end(_: *void, ctx: Ctx) Result {
const mv = tui.mainview() orelse return; try move_to_word(ctx, move_cursor_word_right_end_helix);
const ed = mv.get_active_editor() orelse return;
const root = try ed.buf_root();
for (ed.cursels.items) |*cursel_| if (cursel_.*) |*cursel| {
cursel.selection = null;
};
ed.with_selections_const_repeat(root, move_cursor_word_right_end_helix, ctx) catch {};
ed.clamp();
} }
pub const move_next_word_end_meta: Meta = .{ .description = "Move next word end", .arguments = &.{.integer} }; pub const move_next_word_end_meta: Meta = .{ .description = "Move next word end", .arguments = &.{.integer} };
pub fn extend_next_word_end(_: *void, ctx: Ctx) Result { pub fn extend_next_word_end(_: *void, ctx: Ctx) Result {
const mv = tui.mainview() orelse return; try extend_to_word(ctx, move_cursor_word_right_end_helix);
const ed = mv.get_active_editor() orelse return;
const root = try ed.buf_root();
ed.with_selections_const_repeat(root, move_cursor_word_right_end_helix, ctx) catch {};
ed.clamp();
} }
pub const extend_next_word_end_meta: Meta = .{ .description = "Extend next word end", .arguments = &.{.integer} }; pub const extend_next_word_end_meta: Meta = .{ .description = "Extend next word end", .arguments = &.{.integer} };
pub fn move_next_long_word_end(_: *void, ctx: Ctx) Result { pub fn move_next_long_word_end(_: *void, ctx: Ctx) Result {
const mv = tui.mainview() orelse return; try move_to_word(ctx, move_cursor_long_word_right_end);
const ed = mv.get_active_editor() orelse return;
const root = try ed.buf_root();
for (ed.cursels.items) |*cursel_| if (cursel_.*) |*cursel| {
cursel.selection = null;
};
ed.with_selections_const_repeat(root, move_cursor_long_word_right_end, ctx) catch {};
ed.clamp();
} }
pub const move_next_long_word_end_meta: Meta = .{ .description = "Move next long word end", .arguments = &.{.integer} }; pub const move_next_long_word_end_meta: Meta = .{ .description = "Move next long word end", .arguments = &.{.integer} };
pub fn extend_next_long_word_end(_: *void, ctx: Ctx) Result { pub fn extend_next_long_word_end(_: *void, ctx: Ctx) Result {
const mv = tui.mainview() orelse return; try extend_to_word(ctx, move_cursor_long_word_right_end);
const ed = mv.get_active_editor() orelse return;
const root = try ed.buf_root();
ed.with_selections_const_repeat(root, move_cursor_long_word_right_end, ctx) catch {};
ed.clamp();
} }
pub const extend_next_long_word_end_meta: Meta = .{ .description = "Extend next long word end", .arguments = &.{.integer} }; pub const extend_next_long_word_end_meta: Meta = .{ .description = "Extend next long word end", .arguments = &.{.integer} };
@ -494,6 +430,32 @@ const cmds_ = struct {
pub const replace_with_character_helix_meta: Meta = .{ .description = "Replace with character" }; pub const replace_with_character_helix_meta: Meta = .{ .description = "Replace with character" };
}; };
fn move_to_word(ctx: command.Context, move: Editor.cursor_operator_const) command.Result {
const mv = tui.mainview() orelse return;
const ed = mv.get_active_editor() orelse return;
const root = try ed.buf_root();
// NOR mode moves n words selecting the last one
var repeat: usize = 0;
_ = ctx.args.match(.{tp.extract(&repeat)}) catch false;
if (repeat > 1) ed.with_cursors_const_repeat(root, move, command.fmt(.{repeat - 1})) catch {};
for (ed.cursels.items) |*cursel_| if (cursel_.*) |*cursel| {
cursel.selection = null;
};
ed.with_selections_const_repeat(root, move, command.fmt(.{1})) catch {};
ed.clamp();
}
fn extend_to_word(ctx: command.Context, move: Editor.cursor_operator_const) command.Result {
const mv = tui.mainview() orelse return;
const ed = mv.get_active_editor() orelse return;
const root = try ed.buf_root();
ed.with_selections_const_repeat(root, move, ctx) catch {};
ed.clamp();
}
fn to_char_helix(ctx: command.Context, move: Editor.cursel_operator_mut_once_arg) command.Result { fn to_char_helix(ctx: command.Context, move: Editor.cursel_operator_mut_once_arg) command.Result {
const mv = tui.mainview() orelse return; const mv = tui.mainview() orelse return;
const ed = mv.get_active_editor() orelse return; const ed = mv.get_active_editor() orelse return;