feat: [hx] Add F, T, t, f select and extension movements

This commit is contained in:
Igor Támara 2025-10-27 17:49:59 -05:00 committed by CJ van den Berg
parent 65665fb28b
commit f5efe8e94f
3 changed files with 157 additions and 17 deletions

View file

@ -66,11 +66,13 @@
["alt+|", "shell_pipe_to"], ["alt+|", "shell_pipe_to"],
["alt+!", "shell_append_output"], ["alt+!", "shell_append_output"],
["T", "till_prev_char"], ["F", "move_to_char", "select_to_char_left_helix"],
["F", "move_to_char", "move_to_char_left"], ["T", "move_to_char", "select_till_char_left_helix"],
["W", "move_next_long_word_start"], ["W", "move_next_long_word_start"],
["B", "move_prev_long_word_start"], ["B", "move_prev_long_word_start"],
["E", "move_next_long_word_end"], ["E", "move_next_long_word_end"],
["t", "move_to_char", "select_till_char_right_helix"],
["f", "move_to_char", "select_to_char_right_helix"],
["I", ["enter_mode", "insert"], ["smart_move_begin"]], ["I", ["enter_mode", "insert"], ["smart_move_begin"]],
["A", ["enter_mode", "insert"], ["move_end"]], ["A", ["enter_mode", "insert"], ["move_end"]],
@ -116,9 +118,6 @@
["k", "move_up"], ["k", "move_up"],
["l", "move_right"], ["l", "move_right"],
["t", "find_till_char"],
["f", "move_to_char", "select_to_char_right_helix"],
["home", "move_begin"], ["home", "move_begin"],
["end", "move_end"], ["end", "move_end"],
["kp_home", "move_begin"], ["kp_home", "move_begin"],
@ -354,12 +353,13 @@
["~", "switch_case"], ["~", "switch_case"],
["T", "extend_till_prev_char"], ["F", "move_to_char", "extend_to_char_left_helix"],
["F", "move_to_char", "select_to_char_left_vim"], ["T", "move_to_char", "extend_till_char_left_helix"],
["W", "extend_next_long_word_start"], ["W", "extend_next_long_word_start"],
["B", "extend_prev_long_word_start"], ["B", "extend_prev_long_word_start"],
["E", "extend_next_long_word_end"], ["E", "extend_next_long_word_end"],
["t", "move_to_char", "extend_till_char_right_helix"],
["f", "move_to_char", "extend_to_char_right_helix"],
["G", "goto_line"], ["G", "goto_line"],
@ -415,9 +415,6 @@
["kp_right", "select_right"], ["kp_right", "select_right"],
["%", "select_all"], ["%", "select_all"],
["t", "extend_till_char"],
["f", "move_to_char", "select_to_char_right_helix"],
["`", "switch_to_lowercase"], ["`", "switch_to_lowercase"],
["home", "extend_to_line_start"], ["home", "extend_to_line_start"],

View file

@ -2094,7 +2094,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; 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;
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;
const cursel_operator_const = *const fn (root: Buffer.Root, cursel: *CurSel) error{Stop}!void; const cursel_operator_const = *const fn (root: Buffer.Root, cursel: *CurSel) error{Stop}!void;
const cursor_operator = *const fn (root: Buffer.Root, cursor: *Cursor, allocator: Allocator) error{Stop}!Buffer.Root; const cursor_operator = *const fn (root: Buffer.Root, cursor: *Cursor, allocator: Allocator) error{Stop}!Buffer.Root;

View file

@ -372,15 +372,46 @@ const cmds_ = struct {
} }
pub const select_left_helix_meta: Meta = .{ .description = "Select left", .arguments = &.{.integer} }; pub const select_left_helix_meta: Meta = .{ .description = "Select left", .arguments = &.{.integer} };
pub fn select_to_char_left_helix(_: *void, ctx: Ctx) Result {
try to_char_helix(ctx, &select_cursel_to_char_left_helix);
}
pub const select_to_char_left_helix_meta: Meta = .{ .description = "Select to char left" };
pub fn select_till_char_left_helix(_: *void, ctx: Ctx) Result {
try to_char_helix(ctx, &select_cursel_till_char_left_helix);
}
pub const select_till_char_left_helix_meta: Meta = .{ .description = "Select until char left" };
pub fn extend_to_char_left_helix(_: *void, ctx: Ctx) Result {
try to_char_helix(ctx, &extend_cursel_to_char_left_helix);
}
pub const extend_to_char_left_helix_meta: Meta = .{ .description = "Extend Selection to char left" };
pub fn extend_till_char_left_helix(_: *void, ctx: Ctx) Result {
try to_char_helix(ctx, &extend_cursel_till_char_left_helix);
}
pub const extend_till_char_left_helix_meta: Meta = .{ .description = "Extend Selection until char left" };
pub fn select_till_char_right_helix(_: *void, ctx: Ctx) Result {
try to_char_helix(ctx, &select_cursel_till_char_right_helix);
}
pub const select_till_char_right_helix_meta: Meta = .{ .description = "Select until char right" };
pub fn select_to_char_right_helix(_: *void, ctx: Ctx) Result { pub fn select_to_char_right_helix(_: *void, ctx: Ctx) Result {
const mv = tui.mainview() orelse return; try to_char_helix(ctx, &select_cursel_to_char_right_helix);
const ed = mv.get_active_editor() orelse return;
const root = ed.buf_root() catch return;
try ed.with_cursels_const_once_arg(root, &select_cursel_to_char_right_helix, ctx);
ed.clamp();
} }
pub const select_to_char_right_helix_meta: Meta = .{ .description = "Select to char right" }; pub const select_to_char_right_helix_meta: Meta = .{ .description = "Select to char right" };
pub fn extend_till_char_right_helix(_: *void, ctx: Ctx) Result {
try to_char_helix(ctx, &extend_cursel_till_char_right_helix);
}
pub const extend_till_char_right_helix_meta: Meta = .{ .description = "Extend Selection until char right" };
pub fn extend_to_char_right_helix(_: *void, ctx: Ctx) Result {
try to_char_helix(ctx, &extend_cursel_to_char_right_helix);
}
pub const extend_to_char_right_helix_meta: Meta = .{ .description = "Extend Selection to char right" };
pub fn copy_helix(_: *void, _: Ctx) Result { pub fn copy_helix(_: *void, _: Ctx) 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;
@ -411,6 +442,101 @@ const cmds_ = struct {
pub const paste_clipboard_before_meta: Meta = .{ .description = "Paste from clipboard before selection" }; pub const paste_clipboard_before_meta: Meta = .{ .description = "Paste from clipboard before selection" };
}; };
fn to_char_helix(ctx: command.Context, move: Editor.cursel_operator_mut_once_arg) command.Result {
const mv = tui.mainview() orelse return;
const ed = mv.get_active_editor() orelse return;
const root = ed.buf_root() catch return;
try ed.with_cursels_const_once_arg(root, move, ctx);
ed.clamp();
}
fn select_cursel_to_char_left_helix(root: Buffer.Root, cursel: *CurSel, ctx: command.Context, metrics: Buffer.Metrics) error{Stop}!void {
var moving_cursor: Cursor = cursel.*.cursor;
var begin = cursel.*.cursor;
move_cursor_to_char_left_beyond_eol(root, &moving_cursor, metrics, ctx) catch return;
// Character found, selecting
Editor.move_cursor_right(root, &begin, metrics) catch {
//At end of file, it's ok
};
moving_cursor.target = moving_cursor.col;
const sel = try cursel.enable_selection(root, metrics);
sel.begin = begin;
sel.end = moving_cursor;
cursel.cursor = moving_cursor;
}
fn extend_cursel_to_char_left_helix(root: Buffer.Root, cursel: *CurSel, ctx: command.Context, metrics: Buffer.Metrics) error{Stop}!void {
var moving_cursor: Cursor = cursel.*.cursor;
const begin = if (cursel.*.selection) |sel| sel.end else cursel.*.cursor;
move_cursor_to_char_left_beyond_eol(root, &moving_cursor, metrics, ctx) catch return;
//Character found, selecting
moving_cursor.target = moving_cursor.col;
const sel = try cursel.enable_selection(root, metrics);
if (sel.empty())
sel.begin = begin;
sel.end = moving_cursor;
cursel.cursor = moving_cursor;
}
fn select_cursel_till_char_left_helix(root: Buffer.Root, cursel: *CurSel, ctx: command.Context, metrics: Buffer.Metrics) error{Stop}!void {
var moving_cursor: Cursor = cursel.*.cursor;
var begin = cursel.*.cursor;
move_cursor_till_char_left_beyond_eol(root, &moving_cursor, metrics, ctx) catch return;
Editor.move_cursor_right(root, &begin, metrics) catch {
//At end of file, it's ok
};
// Character found, selecting
moving_cursor.target = moving_cursor.col;
const sel = try cursel.enable_selection(root, metrics);
sel.begin = begin;
sel.end = moving_cursor;
cursel.cursor = moving_cursor;
}
fn extend_cursel_till_char_left_helix(root: Buffer.Root, cursel: *CurSel, ctx: command.Context, metrics: Buffer.Metrics) error{Stop}!void {
var moving_cursor: Cursor = cursel.*.cursor;
const begin = if (cursel.*.selection) |sel| sel.end else cursel.*.cursor;
move_cursor_till_char_left_beyond_eol(root, &moving_cursor, metrics, ctx) catch return;
//Character found, selecting
moving_cursor.target = moving_cursor.col;
const sel = try cursel.enable_selection(root, metrics);
if (sel.empty())
sel.begin = begin;
sel.end = moving_cursor;
cursel.cursor = moving_cursor;
}
fn select_cursel_till_char_right_helix(root: Buffer.Root, cursel: *CurSel, ctx: command.Context, metrics: Buffer.Metrics) error{Stop}!void {
var moving_cursor: Cursor = cursel.*.cursor;
const begin = cursel.*.cursor;
move_cursor_to_char_right_beyond_eol(root, &moving_cursor, metrics, ctx) catch return;
//Character found, selecting
moving_cursor.target = moving_cursor.col;
const sel = try cursel.enable_selection(root, metrics);
sel.begin = begin;
sel.end = moving_cursor;
cursel.cursor = moving_cursor;
}
fn extend_cursel_till_char_right_helix(root: Buffer.Root, cursel: *CurSel, ctx: command.Context, metrics: Buffer.Metrics) error{Stop}!void {
var moving_cursor: Cursor = cursel.*.cursor;
const begin = cursel.*.cursor;
move_cursor_to_char_right_beyond_eol(root, &moving_cursor, metrics, ctx) catch return;
//Character found, selecting
moving_cursor.target = moving_cursor.col;
const sel = try cursel.enable_selection(root, metrics);
if (sel.empty())
sel.begin = begin;
sel.end = moving_cursor;
cursel.cursor = moving_cursor;
}
fn select_cursel_to_char_right_helix(root: Buffer.Root, cursel: *CurSel, ctx: command.Context, metrics: Buffer.Metrics) error{Stop}!void { fn select_cursel_to_char_right_helix(root: Buffer.Root, cursel: *CurSel, ctx: command.Context, metrics: Buffer.Metrics) error{Stop}!void {
var moving_cursor: Cursor = cursel.*.cursor; var moving_cursor: Cursor = cursel.*.cursor;
const begin = cursel.*.cursor; const begin = cursel.*.cursor;
@ -427,6 +553,23 @@ fn select_cursel_to_char_right_helix(root: Buffer.Root, cursel: *CurSel, ctx: co
cursel.cursor = moving_cursor; cursel.cursor = moving_cursor;
} }
fn extend_cursel_to_char_right_helix(root: Buffer.Root, cursel: *CurSel, ctx: command.Context, metrics: Buffer.Metrics) error{Stop}!void {
var moving_cursor: Cursor = cursel.*.cursor;
const begin = cursel.*.cursor;
move_cursor_to_char_right_beyond_eol(root, &moving_cursor, metrics, ctx) catch return;
//Character found, selecting
Editor.move_cursor_right(root, &moving_cursor, metrics) catch {
// We might be at end of file
};
moving_cursor.target = moving_cursor.col;
const sel = try cursel.enable_selection(root, metrics);
if (sel.empty())
sel.begin = begin;
sel.end = moving_cursor;
cursel.cursor = moving_cursor;
}
fn move_cursor_find_egc_beyond_eol(root: Buffer.Root, cursor: *Cursor, ctx: command.Context, metrics: Buffer.Metrics, move: find_char_function) error{Stop}!void { fn move_cursor_find_egc_beyond_eol(root: Buffer.Root, cursor: *Cursor, ctx: command.Context, metrics: Buffer.Metrics, move: find_char_function) error{Stop}!void {
move(root, cursor, metrics, ctx); move(root, cursor, metrics, ctx);
} }