refactor: use flow clipboard in hx mode

hx users will envy flow clipboard history :P, fortunately it's possible
to use F4 to shift modes
This commit is contained in:
Igor Támara 2025-10-13 17:09:03 -05:00 committed by CJ van den Berg
parent 7faea783f3
commit eb05939b81

View file

@ -391,7 +391,16 @@ const cmds_ = struct {
pub const select_to_char_right_helix_meta: Meta = .{ .description = "Move to char right" }; pub const select_to_char_right_helix_meta: Meta = .{ .description = "Move to char right" };
pub fn copy_helix(_: *void, _: Ctx) Result { pub fn copy_helix(_: *void, _: Ctx) Result {
try copy_internal_helix(); const mv = tui.mainview() orelse return;
const ed = mv.get_active_editor() orelse return;
const root = ed.buf_root() catch return;
tui.clipboard_clear_all();
for (ed.cursels.items) |*cursel_| if (cursel_.*) |*cursel| if (cursel.selection) |sel|
tui.clipboard_add_chunk(try Editor.copy_selection(root, sel, tui.clipboard_allocator(), ed.metrics));
ed.logger.print("copy: {d} selections", .{ed.cursels.items.len});
} }
pub const copy_helix_meta: Meta = .{ .description = "Copy selection to clipboard (helix)" }; pub const copy_helix_meta: Meta = .{ .description = "Copy selection to clipboard (helix)" };
@ -604,72 +613,37 @@ const pasting_function = @TypeOf(insert_before);
fn paste_helix(ctx: command.Context, do_paste: pasting_function) command.Result { fn paste_helix(ctx: command.Context, do_paste: pasting_function) 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;
var text: []const u8 = undefined; var text_: []const u8 = undefined;
if (!(ctx.args.buf.len > 0 and try ctx.args.match(.{tp.extract(&text)}))) { const clipboard: []const []const u8 = if (ctx.args.buf.len > 0 and try ctx.args.match(.{tp.extract(&text_)}))
if (tui.get_clipboard()) |text_| text = text_ else return; &[_][]const u8{text_}
} else
tui.clipboard_get_history() orelse return;
ed.logger.print("paste: {d} bytes", .{text.len});
const b = try ed.buf_for_update(); const b = try ed.buf_for_update();
var root = b.root; var root = b.root;
if (std.mem.indexOf(u8, text, serial_separator)) |_| {
// Chunks from clipboard are paired to selections // Chunks from clipboard are paired to selections
// If more selections than chunks in the clipboard, the exceding selections // If more selections than chunks in the clipboard, the exceding selections
// use the last chunk in the clipboard // use the last chunk in the clipboard
var pos: usize = 0;
for (ed.cursels.items) |*cursel_| if (cursel_.*) |*cursel| { var bytes: usize = 0;
if (std.mem.indexOfPos(u8, text, pos, serial_separator)) |next| { for (ed.cursels.items, 0..) |*cursel_, idx| if (cursel_.*) |*cursel| {
root = try do_paste(ed, root, cursel, text[pos..next], b.allocator); if (idx < clipboard.len) {
pos = next + serial_separator.len; root = try do_paste(ed, root, cursel, clipboard[idx], b.allocator);
bytes += clipboard[idx].len;
} else { } else {
root = try do_paste(ed, root, cursel, text[pos..], b.allocator); bytes += clipboard[clipboard.len - 1].len;
root = try do_paste(ed, root, cursel, clipboard[clipboard.len - 1], b.allocator);
} }
}; };
} else { ed.logger.print("paste: {d} bytes", .{bytes});
// The clipboard has only one chunk, which is pasted in all selections
for (ed.cursels.items) |*cursel_| if (cursel_.*) |*cursel| {
root = try do_paste(ed, root, cursel, text, b.allocator);
};
}
try ed.update_buf(root); try ed.update_buf(root);
ed.clamp(); ed.clamp();
ed.need_render(); ed.need_render();
} }
fn copy_internal_helix() command.Result {
const mv = tui.mainview() orelse return;
const editor = mv.get_active_editor() orelse return;
const root = editor.buf_root() catch return;
var first = true;
var text = std.ArrayListUnmanaged(u8).empty;
defer text.deinit(editor.allocator);
for (editor.cursels.items) |*cursel_| if (cursel_.*) |*cursel| {
if (cursel.selection) |sel| {
const copy_text = try Editor.copy_selection(root, sel, editor.allocator, editor.metrics);
if (first) {
first = false;
} else {
try text.appendSlice(editor.allocator, serial_separator);
}
try text.appendSlice(editor.allocator, copy_text);
editor.allocator.free(copy_text);
}
};
if (text.items.len > 0) {
if (text.items.len > 100) {
editor.logger.print("copy:{f}...", .{std.ascii.hexEscape(text.items[0..100], .lower)});
} else {
editor.logger.print("copy:{f}", .{std.ascii.hexEscape(text.items, .lower)});
}
editor.set_clipboard_internal(try text.toOwnedSlice(editor.allocator));
}
}
fn move_cursor_carriage_return(root: Buffer.Root, cursel: CurSel, cursor: *Cursor, metrics: Buffer.Metrics) error{Stop}!void { 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)) { if (is_cursel_from_extend_line_below(cursel)) {
//The cursor is already beginning next line //The cursor is already beginning next line