refactor: allow updating of completions
This commit is contained in:
parent
725862a394
commit
94aa462a8d
4 changed files with 70 additions and 20 deletions
|
|
@ -418,10 +418,9 @@ pub const Editor = struct {
|
||||||
diag_info: usize = 0,
|
diag_info: usize = 0,
|
||||||
diag_hints: usize = 0,
|
diag_hints: usize = 0,
|
||||||
|
|
||||||
completions: std.ArrayListUnmanaged(u8) = .empty,
|
completions: CompletionState = .empty,
|
||||||
completion_row: usize = 0,
|
completions_request: ?CompletionState = .done,
|
||||||
completion_col: usize = 0,
|
completions_refresh_pending: bool = false,
|
||||||
completion_is_complete: bool = true,
|
|
||||||
|
|
||||||
changes: std.ArrayList(Diff) = .empty,
|
changes: std.ArrayList(Diff) = .empty,
|
||||||
|
|
||||||
|
|
@ -438,6 +437,22 @@ pub const Editor = struct {
|
||||||
} = null,
|
} = null,
|
||||||
} = null,
|
} = null,
|
||||||
|
|
||||||
|
const CompletionState = struct {
|
||||||
|
data: std.ArrayListUnmanaged(u8) = .empty,
|
||||||
|
row: usize = 0,
|
||||||
|
col: usize = 0,
|
||||||
|
is_complete: bool = true,
|
||||||
|
|
||||||
|
const empty: @This() = .{};
|
||||||
|
const pending: @This() = .empty;
|
||||||
|
const done: ?@This() = null;
|
||||||
|
|
||||||
|
fn deinit(self: *@This(), allocator: std.mem.Allocator) void {
|
||||||
|
self.data.deinit(allocator);
|
||||||
|
self.* = .empty;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const StyleCache = std.AutoHashMap(u32, ?Widget.Theme.Token);
|
const StyleCache = std.AutoHashMap(u32, ?Widget.Theme.Token);
|
||||||
|
|
||||||
const Context = command.Context;
|
const Context = command.Context;
|
||||||
|
|
@ -626,6 +641,7 @@ pub const Editor = struct {
|
||||||
for (self.diagnostics.items) |*d| d.deinit(self.allocator);
|
for (self.diagnostics.items) |*d| d.deinit(self.allocator);
|
||||||
self.diagnostics.deinit(self.allocator);
|
self.diagnostics.deinit(self.allocator);
|
||||||
self.completions.deinit(self.allocator);
|
self.completions.deinit(self.allocator);
|
||||||
|
if (self.completions_request) |*p| p.deinit(self.allocator);
|
||||||
self.changes.deinit(self.allocator);
|
self.changes.deinit(self.allocator);
|
||||||
self.clear_event_triggers();
|
self.clear_event_triggers();
|
||||||
if (self.syntax) |syn| syn.destroy(tui.query_cache());
|
if (self.syntax) |syn| syn.destroy(tui.query_cache());
|
||||||
|
|
@ -6251,7 +6267,10 @@ pub const Editor = struct {
|
||||||
|
|
||||||
pub fn completion(self: *Self, _: Context) Result {
|
pub fn completion(self: *Self, _: Context) Result {
|
||||||
const mv = tui.mainview() orelse return;
|
const mv = tui.mainview() orelse return;
|
||||||
self.completions.clearRetainingCapacity();
|
if (self.completions_request) |_|
|
||||||
|
self.completions_refresh_pending = true
|
||||||
|
else
|
||||||
|
self.completions_request = .pending;
|
||||||
if (!mv.is_any_panel_view_showing())
|
if (!mv.is_any_panel_view_showing())
|
||||||
self.clamp_offset(mv.get_panel_height());
|
self.clamp_offset(mv.get_panel_height());
|
||||||
return self.pm_with_primary_cursor_pos(project_manager.completion);
|
return self.pm_with_primary_cursor_pos(project_manager.completion);
|
||||||
|
|
@ -6556,13 +6575,31 @@ pub const Editor = struct {
|
||||||
pub const run_trigger_meta: Meta = .{ .arguments = &.{ .integer, .string } };
|
pub const run_trigger_meta: Meta = .{ .arguments = &.{ .integer, .string } };
|
||||||
|
|
||||||
pub fn add_completion(self: *Self, row: usize, col: usize, is_incomplete: bool, msg: tp.message) Result {
|
pub fn add_completion(self: *Self, row: usize, col: usize, is_incomplete: bool, msg: tp.message) Result {
|
||||||
if (!(row == self.completion_row and col == self.completion_col)) {
|
const request = if (self.completions_request) |*p| p else return;
|
||||||
self.completions.clearRetainingCapacity();
|
request.row = row;
|
||||||
self.completion_row = row;
|
request.col = col;
|
||||||
self.completion_col = col;
|
try request.data.appendSlice(self.allocator, msg.buf);
|
||||||
|
request.is_complete = is_incomplete;
|
||||||
}
|
}
|
||||||
try self.completions.appendSlice(self.allocator, msg.buf);
|
|
||||||
self.completion_is_complete = is_incomplete;
|
pub fn add_completion_done(self: *Self) anyerror!bool {
|
||||||
|
self.completions.deinit(self.allocator);
|
||||||
|
self.completions = .empty;
|
||||||
|
if (self.completions_request) |*request| {
|
||||||
|
self.completions.deinit(self.allocator);
|
||||||
|
self.completions = request.*;
|
||||||
|
self.completions_request = .done;
|
||||||
|
}
|
||||||
|
|
||||||
|
const update_completion = "update_completion";
|
||||||
|
if (command.get_id(update_completion)) |cmd_id|
|
||||||
|
try command.execute(cmd_id, update_completion, .{});
|
||||||
|
|
||||||
|
if (self.completions_refresh_pending) {
|
||||||
|
self.completions_refresh_pending = false;
|
||||||
|
try self.completion(.{});
|
||||||
|
}
|
||||||
|
return self.completions.data.items.len > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_completion_replacement_selection(self: *Self, replace: Selection) ?Selection {
|
pub fn get_completion_replacement_selection(self: *Self, replace: Selection) ?Selection {
|
||||||
|
|
|
||||||
|
|
@ -1198,7 +1198,8 @@ const cmds = struct {
|
||||||
var file_path_buf: [std.fs.max_path_bytes]u8 = undefined;
|
var file_path_buf: [std.fs.max_path_bytes]u8 = undefined;
|
||||||
file_path = project_manager.normalize_file_path(file_path, &file_path_buf);
|
file_path = project_manager.normalize_file_path(file_path, &file_path_buf);
|
||||||
if (self.get_active_editor()) |editor| if (std.mem.eql(u8, file_path, editor.file_path orelse "")) {
|
if (self.get_active_editor()) |editor| if (std.mem.eql(u8, file_path, editor.file_path orelse "")) {
|
||||||
if (editor.completions.items.len > 0) {
|
const have_completions = try editor.add_completion_done();
|
||||||
|
if (have_completions) {
|
||||||
switch (tui.config().completion_style) {
|
switch (tui.config().completion_style) {
|
||||||
.palette => try tui.open_overlay(@import("mode/overlay/completion_palette.zig").Type),
|
.palette => try tui.open_overlay(@import("mode/overlay/completion_palette.zig").Type),
|
||||||
.dropdown => try tui.open_overlay(@import("mode/overlay/completion_dropdown.zig").Type),
|
.dropdown => try tui.open_overlay(@import("mode/overlay/completion_dropdown.zig").Type),
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,7 @@ pub const ValueType = struct {
|
||||||
cursor: ed.Cursor = .{},
|
cursor: ed.Cursor = .{},
|
||||||
view: ed.View = .{},
|
view: ed.View = .{},
|
||||||
replace: ?Buffer.Selection = null,
|
replace: ?Buffer.Selection = null,
|
||||||
|
commands: command.Collection(cmds) = undefined,
|
||||||
};
|
};
|
||||||
pub const defaultValue: ValueType = .{};
|
pub const defaultValue: ValueType = .{};
|
||||||
|
|
||||||
|
|
@ -48,7 +49,7 @@ pub fn load_entries(self: *Type) !usize {
|
||||||
|
|
||||||
const editor = tui.get_active_editor() orelse return error.NotFound;
|
const editor = tui.get_active_editor() orelse return error.NotFound;
|
||||||
self.value.start = editor.get_primary().*;
|
self.value.start = editor.get_primary().*;
|
||||||
var iter: []const u8 = editor.completions.items;
|
var iter: []const u8 = editor.completions.data.items;
|
||||||
while (iter.len > 0) {
|
while (iter.len > 0) {
|
||||||
var cbor_item: []const u8 = undefined;
|
var cbor_item: []const u8 = undefined;
|
||||||
if (!try cbor.matchValue(&iter, cbor.extract_cbor(&cbor_item))) return error.BadCompletion;
|
if (!try cbor.matchValue(&iter, cbor.extract_cbor(&cbor_item))) return error.BadCompletion;
|
||||||
|
|
@ -88,8 +89,8 @@ pub fn load_entries(self: *Type) !usize {
|
||||||
return @max(max_description, if (max_label_len > label.len + 3) 0 else label.len + 3 - max_label_len);
|
return @max(max_description, if (max_label_len > label.len + 3) 0 else label.len + 3 - max_label_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deinit(_: *Type) void {
|
pub fn deinit(self: *Type) void {
|
||||||
//
|
self.value.commands.deinit();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn handle_event(self: *Type, _: tp.pid_ref, m: tp.message) tp.result {
|
pub fn handle_event(self: *Type, _: tp.pid_ref, m: tp.message) tp.result {
|
||||||
|
|
@ -107,6 +108,7 @@ pub fn handle_event(self: *Type, _: tp.pid_ref, m: tp.message) tp.result {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn initial_query(self: *Type, allocator: std.mem.Allocator) error{OutOfMemory}![]const u8 {
|
pub fn initial_query(self: *Type, allocator: std.mem.Allocator) error{OutOfMemory}![]const u8 {
|
||||||
|
try self.value.commands.init(self);
|
||||||
const editor = tui.get_active_editor() orelse return allocator.dupe(u8, "");
|
const editor = tui.get_active_editor() orelse return allocator.dupe(u8, "");
|
||||||
self.value.cursor = editor.get_primary().cursor;
|
self.value.cursor = editor.get_primary().cursor;
|
||||||
self.value.view = editor.view;
|
self.value.view = editor.view;
|
||||||
|
|
@ -125,10 +127,7 @@ pub fn update_query(self: *Type, query: []const u8) void {
|
||||||
self.value.cursor = primary.cursor;
|
self.value.cursor = primary.cursor;
|
||||||
self.value.view = editor.view;
|
self.value.view = editor.view;
|
||||||
if (self.value.replace) |*s| s.* = .{ .begin = s.begin, .end = self.value.cursor };
|
if (self.value.replace) |*s| s.* = .{ .begin = s.begin, .end = self.value.cursor };
|
||||||
if (query.len > 0) {
|
tp.self_pid().send(.{ "cmd", "completion" }) catch |e| self.logger.err(module_name, e);
|
||||||
const last_char = query[query.len - 1];
|
|
||||||
editor.run_triggers(primary, last_char, .insert);
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -331,3 +330,16 @@ pub fn cancel(_: *Type) !void {
|
||||||
const mv = tui.mainview() orelse return;
|
const mv = tui.mainview() orelse return;
|
||||||
mv.cancel_info_content() catch {};
|
mv.cancel_info_content() catch {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const cmds = struct {
|
||||||
|
pub const Target = Type;
|
||||||
|
const Ctx = command.Context;
|
||||||
|
const Meta = command.Metadata;
|
||||||
|
const Result = command.Result;
|
||||||
|
|
||||||
|
pub fn update_completion(self: *Type, _: Ctx) Result {
|
||||||
|
clear_entries(self);
|
||||||
|
_ = try load_entries(self);
|
||||||
|
}
|
||||||
|
pub const update_completion_meta: Meta = .{};
|
||||||
|
};
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ pub fn load_entries(palette: *Type) !usize {
|
||||||
|
|
||||||
const editor = tui.get_active_editor() orelse return error.NotFound;
|
const editor = tui.get_active_editor() orelse return error.NotFound;
|
||||||
palette.value.start = editor.get_primary().*;
|
palette.value.start = editor.get_primary().*;
|
||||||
var iter: []const u8 = editor.completions.items;
|
var iter: []const u8 = editor.completions.data.items;
|
||||||
while (iter.len > 0) {
|
while (iter.len > 0) {
|
||||||
var cbor_item: []const u8 = undefined;
|
var cbor_item: []const u8 = undefined;
|
||||||
if (!try cbor.matchValue(&iter, cbor.extract_cbor(&cbor_item))) return error.BadCompletion;
|
if (!try cbor.matchValue(&iter, cbor.extract_cbor(&cbor_item))) return error.BadCompletion;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue