refactor: hx paste(before, replace, after)

Code simplification and zig idiomatics to improve code readability.
This commit is contained in:
Igor Támara 2025-10-13 15:19:27 -05:00 committed by CJ van den Berg
parent f288d24e13
commit 7faea783f3
3 changed files with 57 additions and 56 deletions

View file

@ -131,7 +131,7 @@
["g s", "smart_move_begin"], ["g s", "smart_move_begin"],
["g d", "goto_definition"], ["g d", "goto_definition"],
["g y", "goto_type_definition"], ["g y", "goto_type_definition"],
["g r", "goto_reference"], ["g r", "references"],
["g i", "goto_implementation"], ["g i", "goto_implementation"],
["g t", "goto_window_top"], ["g t", "goto_window_top"],
["g c", "goto_window_center"], ["g c", "goto_window_center"],
@ -426,7 +426,7 @@
["g s", "smart_move_begin"], ["g s", "smart_move_begin"],
["g d", "goto_definition"], ["g d", "goto_definition"],
["g y", "goto_type_definition"], ["g y", "goto_type_definition"],
["g r", "goto_reference"], ["g r", "references"],
["g i", "goto_implementation"], ["g i", "goto_implementation"],
["g t", "goto_window_top"], ["g t", "goto_window_top"],
["g c", "goto_window_center"], ["g c", "goto_window_center"],

View file

@ -2229,7 +2229,7 @@ pub const Editor = struct {
return false; return false;
} }
fn is_eol_right(root: Buffer.Root, cursor: *const Cursor, metrics: Buffer.Metrics) bool { pub fn is_eol_right(root: Buffer.Root, cursor: *const Cursor, metrics: Buffer.Metrics) bool {
const line_width = root.line_width(cursor.row, metrics) catch return true; const line_width = root.line_width(cursor.row, metrics) catch return true;
if (cursor.col >= line_width) if (cursor.col >= line_width)
return true; return true;
@ -2252,15 +2252,6 @@ pub const Editor = struct {
return false; return false;
} }
pub fn move_cursor_carriage_return(root: Buffer.Root, cursor: *Cursor, metrics: Buffer.Metrics) error{Stop}!void {
if (is_eol_right(root, cursor, metrics)) {
try move_cursor_right(root, cursor, metrics);
} else {
try move_cursor_down(root, cursor, metrics);
try move_cursor_begin(root, cursor, metrics);
}
}
pub fn move_cursor_left(root: Buffer.Root, cursor: *Cursor, metrics: Buffer.Metrics) error{Stop}!void { pub fn move_cursor_left(root: Buffer.Root, cursor: *Cursor, metrics: Buffer.Metrics) error{Stop}!void {
try cursor.move_left(root, metrics); try cursor.move_left(root, metrics);
} }
@ -2317,7 +2308,7 @@ pub const Editor = struct {
if (is_eol_vim(root, cursor, metrics)) try move_cursor_left_vim(root, cursor, metrics); if (is_eol_vim(root, cursor, metrics)) try move_cursor_left_vim(root, cursor, metrics);
} }
fn move_cursor_down(root: Buffer.Root, cursor: *Cursor, metrics: Buffer.Metrics) !void { pub fn move_cursor_down(root: Buffer.Root, cursor: *Cursor, metrics: Buffer.Metrics) !void {
cursor.move_down(root, metrics) catch |e| switch (e) { cursor.move_down(root, metrics) catch |e| switch (e) {
error.Stop => cursor.move_end(root, metrics), error.Stop => cursor.move_end(root, metrics),
}; };

View file

@ -408,7 +408,6 @@ const cmds_ = struct {
pub fn paste_clipboard_before(_: *void, ctx: Ctx) Result { pub fn paste_clipboard_before(_: *void, ctx: Ctx) Result {
try paste_helix(ctx, insert_before); try paste_helix(ctx, insert_before);
} }
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" };
}; };
@ -443,85 +442,75 @@ fn move_cursor_word_right_end_helix(root: Buffer.Root, cursor: *Cursor, metrics:
try cursor.move_right(root, metrics); try cursor.move_right(root, metrics);
} }
fn insert_before(editor: *Editor, root: Buffer.Root, cursel: *CurSel, s: []const u8, allocator: Allocator) !Buffer.Root { fn insert_before(editor: *Editor, root: Buffer.Root, cursel: *CurSel, text: []const u8, allocator: Allocator) !Buffer.Root {
var root_: Buffer.Root = root; var root_: Buffer.Root = root;
const cursor: *Cursor = &cursel.cursor; const cursor: *Cursor = &cursel.cursor;
cursel.check_selection(root, editor.metrics); cursel.check_selection(root, editor.metrics);
if (s[s.len - 1] == '\n') { if (cursel.selection) |sel_| {
if (cursel.selection) |*sel_| { var sel = sel_;
sel_.*.normalize(); sel.normalize();
cursor.move_to(root, sel_.*.begin.row, sel_.*.begin.col, editor.metrics) catch {}; cursor.move_to(root, sel.begin.row, sel.begin.col, editor.metrics) catch {};
} else {
if (text[text.len - 1] == '\n') {
cursor.move_begin(); cursor.move_begin();
} }
} else { } else if (text[text.len - 1] == '\n') {
if (cursel.selection) |*sel_| { cursor.move_begin();
sel_.*.normalize();
cursor.move_to(root, sel_.*.begin.row, sel_.*.begin.col, editor.metrics) catch {};
}
} }
cursel.disable_selection_normal(); cursel.disable_selection_normal();
const begin = cursel.cursor; const begin = cursel.cursor;
cursor.row, cursor.col, root_ = try root_.insert_chars(cursor.row, cursor.col, text, allocator, editor.metrics);
cursor.row, cursor.col, root_ = try root_.insert_chars(cursor.row, cursor.col, s, allocator, editor.metrics);
cursor.target = cursor.col; cursor.target = cursor.col;
editor.nudge_insert(.{ .begin = begin, .end = cursor.* }, cursel, s.len);
cursel.selection = Selection{ .begin = begin, .end = cursor.* }; cursel.selection = Selection{ .begin = begin, .end = cursor.* };
editor.nudge_insert(.{ .begin = begin, .end = cursor.* }, cursel, text.len);
return root_; return root_;
} }
fn insert_replace_selection(editor: *Editor, root: Buffer.Root, cursel: *CurSel, s: []const u8, allocator: Allocator) !Buffer.Root { fn insert_replace_selection(editor: *Editor, root: Buffer.Root, cursel: *CurSel, text: []const u8, allocator: Allocator) !Buffer.Root {
// replaces the selection, if no selection, replaces the current
// character and sets the selection to the replacement text
var root_: Buffer.Root = root; var root_: Buffer.Root = root;
cursel.check_selection(root, editor.metrics); cursel.check_selection(root, editor.metrics);
if (cursel.selection) |_| { if (cursel.selection == null) {
root_ = try editor.delete_selection(root, cursel, allocator); // Select current character to replace it
} else { Editor.with_selection_const(root, move_noop, cursel, editor.metrics) catch {};
// Replace current character when no explicit selection
try Editor.with_selection_const(root, move_noop, cursel, editor.metrics);
root_ = try editor.delete_selection(root, cursel, allocator);
} }
root_ = editor.delete_selection(root, cursel, allocator) catch root;
const cursor = &cursel.cursor; const cursor = &cursel.cursor;
const begin = cursel.cursor; const begin = cursel.cursor;
cursor.row, cursor.col, root_ = try root_.insert_chars(cursor.row, cursor.col, text, allocator, editor.metrics);
cursor.row, cursor.col, root_ = try root_.insert_chars(cursor.row, cursor.col, s, allocator, editor.metrics);
cursor.target = cursor.col; cursor.target = cursor.col;
editor.nudge_insert(.{ .begin = begin, .end = cursor.* }, cursel, s.len);
cursel.selection = Selection{ .begin = begin, .end = cursor.* }; cursel.selection = Selection{ .begin = begin, .end = cursor.* };
editor.nudge_insert(.{ .begin = begin, .end = cursor.* }, cursel, text.len);
return root_; return root_;
} }
fn insert_after(editor: *Editor, root: Buffer.Root, cursel: *CurSel, s: []const u8, allocator: Allocator) !Buffer.Root { fn insert_after(editor: *Editor, root: Buffer.Root, cursel: *CurSel, text: []const u8, allocator: Allocator) !Buffer.Root {
var root_: Buffer.Root = root; var root_: Buffer.Root = root;
const cursor = &cursel.cursor; const cursor = &cursel.cursor;
cursel.check_selection(root, editor.metrics); cursel.check_selection(root, editor.metrics);
if (s[s.len - 1] == '\n') { if (text[text.len - 1] == '\n') {
if (cursel.selection) |*sel_| { move_cursor_carriage_return(root, cursel.*, cursor, editor.metrics) catch {};
sel_.*.normalize();
if (sel_.*.end.row == sel_.*.begin.row or sel_.*.end.col != 0) {
cursel.disable_selection_normal();
Editor.move_cursor_carriage_return(root, cursor, editor.metrics) catch {};
}
} else {
cursel.disable_selection_normal();
Editor.move_cursor_carriage_return(root, cursor, editor.metrics) catch {};
}
} else { } else {
if (cursel.selection) |*sel_| { if (cursel.selection) |sel_| {
sel_.*.normalize(); var sel = sel_;
cursor.move_to(root, sel_.*.end.row, sel_.*.end.col, editor.metrics) catch {}; sel.normalize();
cursor.move_to(root, sel.end.row, sel.end.col, editor.metrics) catch {};
} else { } else {
cursor.move_right(root_, editor.metrics) catch {}; cursor.move_right(root_, editor.metrics) catch {};
} }
cursel.disable_selection_normal();
} }
cursel.disable_selection_normal();
const begin = cursel.cursor; const begin = cursel.cursor;
cursor.row, cursor.col, root_ = try root_.insert_chars(cursor.row, cursor.col, s, allocator, editor.metrics); cursor.row, cursor.col, root_ = try root_.insert_chars(cursor.row, cursor.col, text, allocator, editor.metrics);
cursor.target = cursor.col; cursor.target = cursor.col;
editor.nudge_insert(.{ .begin = begin, .end = cursor.* }, cursel, s.len);
cursel.selection = Selection{ .begin = begin, .end = cursor.* }; cursel.selection = Selection{ .begin = begin, .end = cursor.* };
editor.nudge_insert(.{ .begin = begin, .end = cursor.* }, cursel, text.len);
return root_; return root_;
} }
@ -668,6 +657,7 @@ fn copy_internal_helix() command.Result {
try text.appendSlice(editor.allocator, serial_separator); try text.appendSlice(editor.allocator, serial_separator);
} }
try text.appendSlice(editor.allocator, copy_text); try text.appendSlice(editor.allocator, copy_text);
editor.allocator.free(copy_text);
} }
}; };
if (text.items.len > 0) { if (text.items.len > 0) {
@ -680,6 +670,26 @@ fn copy_internal_helix() command.Result {
} }
} }
fn move_cursor_carriage_return(root: Buffer.Root, cursel: CurSel, cursor: *Cursor, metrics: Buffer.Metrics) error{Stop}!void {
if (is_cursel_from_extend_line_below(cursel)) {
//The cursor is already beginning next line
return;
}
if (!Editor.is_eol_right(root, cursor, metrics)) {
try Editor.move_cursor_end(root, cursor, metrics);
}
try Editor.move_cursor_right(root, cursor, metrics);
}
fn is_cursel_from_extend_line_below(cursel: CurSel) bool {
if (cursel.selection) |sel_| {
var sel = sel_;
sel.normalize();
return sel.end.row != sel.begin.row and sel.end.col == 0;
}
return false;
}
const private = @This(); const private = @This();
// exports for unittests // exports for unittests
pub const test_internal = struct { pub const test_internal = struct {