feat: configure editor completion triggers from LSP info

This commit is contained in:
CJ van den Berg 2025-12-26 16:02:25 +01:00
parent fe2ea13024
commit 3dcdb64f83
Signed by: neurocyte
GPG key ID: 8EB1E1BB660E3FB9
4 changed files with 36 additions and 10 deletions

View file

@ -542,9 +542,8 @@ pub const Editor = struct {
tp.extract_cbor(&cursels_cbor),
}))
return error.RestoreStateMatch;
self.insert_triggers.deinit(self.allocator);
self.clear_event_triggers();
self.insert_triggers = .fromOwnedSlice(insert_triggers);
self.delete_triggers.deinit(self.allocator);
self.delete_triggers = .fromOwnedSlice(delete_triggers);
self.refresh_tab_width();
if (op == .open_file)
@ -614,8 +613,7 @@ pub const Editor = struct {
for (self.diagnostics.items) |*d| d.deinit(self.allocator);
self.diagnostics.deinit(self.allocator);
self.completions.deinit(self.allocator);
self.insert_triggers.deinit(self.allocator);
self.delete_triggers.deinit(self.allocator);
self.clear_event_triggers();
if (self.syntax) |syn| syn.destroy(tui.query_cache());
self.cancel_all_tabstops();
self.cursels.deinit(self.allocator);
@ -6234,9 +6232,31 @@ pub const Editor = struct {
};
}
fn clear_event_triggers(self: *Self) void {
self.insert_triggers.deinit(self.allocator);
self.delete_triggers.deinit(self.allocator);
self.insert_triggers = .empty;
self.delete_triggers = .empty;
}
pub fn update_completion_triggers(self: *Self) void {
self.clear_event_triggers();
if (self.file_type) |ft| if (ft.language_server) |ls| if (ls.len > 0) {
const lsp_arg0 = ls[0];
const info = (tui.mainview() orelse return).lsp_info.table.get(lsp_arg0) orelse return;
self.add_completion_triggers(info.trigger_characters.items);
};
}
fn add_default_symbol_triggers(self: *Self) void {
const chars: []const []const u8 = &.{"."};
self.add_completion_triggers(chars);
}
fn add_completion_triggers(self: *Self, triggers: []const []const u8) void {
const id = command.get_name_id("completion");
self.add_symbol_trigger('.', id, .insert) catch {};
for (triggers) |char| if (char.len > 0)
self.add_symbol_trigger(char[0], id, .insert) catch {};
}
pub fn add_symbol_trigger(self: *Self, char: u8, command_: command.ID, event: TriggerEvent) error{OutOfMemory}!void {

View file

@ -3,6 +3,10 @@ table: Table,
const Table = std.StringHashMapUnmanaged(Info);
pub const Info = struct {
trigger_characters: std.ArrayList([]const u8) = .empty,
};
pub fn init(allocator: std.mem.Allocator) @This() {
return .{
.allocator = allocator,
@ -60,10 +64,6 @@ pub fn add(self: *@This(), lsp_arg0: []const u8, iter: *[]const u8) error{ Inval
return value;
}
pub const Info = struct {
trigger_characters: std.ArrayList([]const u8) = .empty,
};
pub fn write_state(self: *@This(), writer: *std.Io.Writer) error{WriteFailed}!void {
try cbor.writeArrayHeader(writer, self.table.count());
var iter = self.table.iterator();

View file

@ -1994,3 +1994,9 @@ pub fn vcs_content_update(self: *Self, m: tp.message) void {
editor.vcs_content_update() catch {};
}
}
pub fn trigger_characters_update(self: *Self, m: tp.message) void {
self.lsp_info.add_from_event(m.buf) catch return;
const editor = self.get_active_editor() orelse return;
editor.update_completion_triggers();
}

View file

@ -534,7 +534,7 @@ fn receive_safe(self: *Self, from: tp.pid_ref, m: tp.message) !void {
return if (mainview()) |mv| mv.vcs_content_update(m);
if (try m.match(.{ "PRJ", "triggerCharacters", tp.more }))
return if (mainview()) |mv| mv.lsp_info.add_from_event(m.buf);
return if (mainview()) |mv| mv.trigger_characters_update(m);
if (try m.match(.{ "PRJ", tp.more })) // drop late project manager query responses
return;