fix: guess completion insertion range by back scanning for trigger chars or word breaks

closes #484
This commit is contained in:
CJ van den Berg 2026-02-03 19:37:51 +01:00
parent 59de78723e
commit 75fa4408fa
Signed by: neurocyte
GPG key ID: 8EB1E1BB660E3FB9
2 changed files with 28 additions and 13 deletions

View file

@ -4995,6 +4995,32 @@ pub const Editor = struct {
_ = self.pop_tabstop();
}
fn is_trigger_left(root: Buffer.Root, cursor: *const Cursor, metrics: Buffer.Metrics, triggers: []const TriggerSymbol) bool {
if (cursor.col == 0) return true;
var next = cursor.*;
next.move_left(root, metrics) catch return true;
const egc_left, _, _ = next.egc_at(root, metrics) catch return true;
switch (egc_left[0]) {
' ', '\t' => return true,
else => |c| for (triggers) |t| if (c == t.char) return true,
}
return false;
}
pub fn guest_completion_range(self: *Self) Selection {
var cursel = self.get_primary().*;
var sel = Selection.from_cursor(&cursel.cursor);
if (cursel.cursor.col == 0) return sel;
const root = self.buf_root() catch return sel;
while (!is_trigger_left(root, &sel.begin, self.metrics, self.get_event_triggers(.insert).items))
move_cursor_left(root, &sel.begin, self.metrics) catch return sel;
if (tui.config().completion_insert_mode == .replace)
move_cursor_word_right(root, &sel.end, self.metrics) catch return sel;
return sel;
}
fn replicate_selection(self: *Self, sel: Selection) void {
if (sel.begin.row != sel.end.row) return;
const primary = self.get_primary();

View file

@ -314,19 +314,8 @@ fn get_replacement_selection(editor: *ed.Editor, insert_: ?Selection, replace_:
var sel = if (pos) |p|
p.from_pos(editor.buf_root() catch return ed.Selection.from_cursor(&editor.get_primary().cursor), editor.metrics)
else blk: {
if (query) |sel| break :blk sel;
var cursel = editor.get_primary().*;
var sel = ed.Selection.from_cursor(&cursel.cursor);
if (cursel.cursor.col == 0) break :blk sel;
const root_ = editor.buf_root() catch break :blk sel;
ed.Editor.move_cursor_word_left(root_, &sel.begin, editor.metrics) catch break :blk sel;
if (tui.config().completion_insert_mode == .replace) {
sel.end = sel.begin;
ed.Editor.move_cursor_word_right(root_, &sel.end, editor.metrics) catch break :blk sel;
}
break :blk sel;
};
else
query orelse editor.guest_completion_range();
sel.normalize();
const cursor = editor.get_primary().cursor;
return switch (tui.config().completion_insert_mode) {