refactor(find): use dynamic input buffer in find mode and improve some edge cases

This commit is contained in:
CJ van den Berg 2024-07-05 19:53:13 +02:00
parent 128182a448
commit 66df590541
2 changed files with 37 additions and 38 deletions

View file

@ -1280,7 +1280,7 @@ pub const Editor = struct {
self.match_done_token = self.match_token;
}
fn init_matches_update(self: *Self) void {
pub fn init_matches_update(self: *Self) void {
self.cancel_all_matches();
self.match_token += 1;
}
@ -3046,9 +3046,9 @@ pub const Editor = struct {
}
};
const root = try self.buf_root();
defer tp.self_pid().send(.{ "A", "done", self.match_token }) catch {};
defer self.add_match_done();
var ctx: Ctx = .{ .self = self };
self.init_matches_update() catch {};
self.init_matches_update();
try root.find_all_ranges(query, &ctx, Ctx.cb, self.a);
}

View file

@ -14,14 +14,13 @@ const ed = @import("../../editor.zig");
const Allocator = @import("std").mem.Allocator;
const json = @import("std").json;
const eql = @import("std").mem.eql;
const ArrayList = @import("std").ArrayList;
const Self = @This();
a: Allocator,
buf: [1024]u8 = undefined,
input: []u8 = "",
last_buf: [1024]u8 = undefined,
last_input: []u8 = "",
input: ArrayList(u8),
last_input: ArrayList(u8),
start_view: ed.View,
start_cursor: ed.Cursor,
editor: *ed.Editor,
@ -32,6 +31,8 @@ pub fn create(a: Allocator, _: command.Context) !*Self {
const self: *Self = try a.create(Self);
self.* = .{
.a = a,
.input = ArrayList(u8).init(a),
.last_input = ArrayList(u8).init(a),
.start_view = editor.view,
.start_cursor = editor.get_primary().cursor,
.editor = editor,
@ -39,8 +40,7 @@ pub fn create(a: Allocator, _: command.Context) !*Self {
if (editor.get_primary().selection) |sel| ret: {
const text = editor.get_selection(sel, self.a) catch break :ret;
defer self.a.free(text);
@memcpy(self.buf[0..text.len], text);
self.input = self.buf[0..text.len];
try self.input.appendSlice(text);
}
return self;
};
@ -48,6 +48,8 @@ pub fn create(a: Allocator, _: command.Context) !*Self {
}
pub fn deinit(self: *Self) void {
self.input.deinit();
self.last_input.deinit();
self.a.destroy(self);
}
@ -68,8 +70,8 @@ pub fn receive(self: *Self, _: tp.pid_ref, m: tp.message) error{Exit}!bool {
defer {
if (tui.current().mini_mode) |*mini_mode| {
mini_mode.text = self.input;
mini_mode.cursor = self.input.len;
mini_mode.text = self.input.items;
mini_mode.cursor = self.input.items.len;
}
}
@ -98,7 +100,7 @@ fn mapPress(self: *Self, keypress: u32, egc: u32, modifiers: u32) !void {
mod.CTRL => switch (keynormal) {
'Q' => self.cmd("quit", .{}),
'V' => self.cmd("system_paste", .{}),
'U' => self.input = "",
'U' => self.input.clearRetainingCapacity(),
'G' => self.cancel(),
'C' => self.cancel(),
'L' => self.cmd("scroll_view_center", .{}),
@ -108,7 +110,7 @@ fn mapPress(self: *Self, keypress: u32, egc: u32, modifiers: u32) !void {
'I' => self.insert_bytes("\t"),
key.SPACE => self.cancel(),
key.ENTER => self.insert_bytes("\n"),
key.BACKSPACE => self.input = "",
key.BACKSPACE => self.input.clearRetainingCapacity(),
else => {},
},
mod.ALT => switch (keynormal) {
@ -137,9 +139,7 @@ fn mapPress(self: *Self, keypress: u32, egc: u32, modifiers: u32) !void {
key.F10 => self.cmd("theme_next", .{}),
key.ESC => self.cancel(),
key.ENTER => self.confirm(),
key.BACKSPACE => if (self.input.len > 0) {
self.input = self.input[0 .. self.input.len - 1];
},
key.BACKSPACE => _ = self.input.popOrNull(),
key.LCTRL, key.RCTRL => self.cmd("enable_fast_scroll", .{}),
key.LALT, key.RALT => self.cmd("enable_fast_scroll", .{}),
else => if (!key.synthesized_p(keypress))
@ -159,31 +159,31 @@ fn mapRelease(self: *Self, keypress: u32, _: u32, _: u32) !void {
}
fn insert_code_point(self: *Self, c: u32) !void {
if (self.input.len + 16 > self.buf.len)
try self.flush_input();
const bytes = ucs32_to_utf8(&[_]u32{c}, self.buf[self.input.len..]) catch |e| return tp.exit_error(e, @errorReturnTrace());
self.input = self.buf[0 .. self.input.len + bytes];
var buf: [16]u8 = undefined;
const bytes = ucs32_to_utf8(&[_]u32{c}, &buf) catch |e| return tp.exit_error(e, @errorReturnTrace());
try self.input.appendSlice(buf[0 .. bytes]);
}
fn insert_bytes(self: *Self, bytes: []const u8) !void {
if (self.input.len + 16 > self.buf.len)
try self.flush_input();
const newlen = self.input.len + bytes.len;
@memcpy(self.buf[self.input.len..newlen], bytes);
self.input = self.buf[0..newlen];
try self.input.appendSlice(bytes);
}
var find_cmd_id: ?command.ID = null;
fn flush_input(self: *Self) !void {
if (self.input.len > 0) {
if (eql(u8, self.input, self.last_input))
if (self.input.items.len > 0) {
if (eql(u8, self.input.items, self.last_input.items))
return;
@memcpy(self.last_buf[0..self.input.len], self.input);
self.last_input = self.last_buf[0..self.input.len];
self.last_input.clearRetainingCapacity();
try self.last_input.appendSlice(self.input.items);
self.editor.find_operation = .goto_next_match;
self.editor.get_primary().cursor = self.start_cursor;
try self.editor.find_in_buffer(self.input);
const primary = self.editor.get_primary();
primary.selection = null;
primary.cursor = self.start_cursor;
try self.editor.find_in_buffer(self.input.items);
} else {
self.editor.get_primary().selection = null;
self.editor.init_matches_update();
}
}
@ -193,7 +193,7 @@ fn cmd(self: *Self, name_: []const u8, ctx: command.Context) tp.result {
}
fn confirm(self: *Self) void {
self.editor.push_find_history(self.input);
self.editor.push_find_history(self.input.items);
self.cmd("exit_mini_mode", .{}) catch {};
}
@ -209,9 +209,9 @@ fn find_history_prev(self: *Self) void {
if (pos > 0) self.history_pos = pos - 1;
} else {
self.history_pos = history.items.len - 1;
if (self.input.len > 0)
self.editor.push_find_history(self.editor.a.dupe(u8, self.input) catch return);
if (eql(u8, history.items[self.history_pos.?], self.input) and self.history_pos.? > 0)
if (self.input.items.len > 0)
self.editor.push_find_history(self.editor.a.dupe(u8, self.input.items) catch return);
if (eql(u8, history.items[self.history_pos.?], self.input.items) and self.history_pos.? > 0)
self.history_pos = self.history_pos.? - 1;
}
self.load_history(self.history_pos.?);
@ -229,8 +229,7 @@ fn find_history_next(self: *Self) void {
fn load_history(self: *Self, pos: usize) void {
if (self.editor.find_history) |*history| {
const new = history.items[pos];
@memcpy(self.buf[0..new.len], new);
self.input = self.buf[0..new.len];
self.input.clearRetainingCapacity();
self.input.appendSlice(history.items[pos]) catch {};
}
}