Compare commits
8 commits
2ea9acea47
...
56238c776d
| Author | SHA1 | Date | |
|---|---|---|---|
| 56238c776d | |||
| 5cf52171f2 | |||
| d298e1ed4c | |||
| 2296930f4d | |||
| 8767dc9dc1 | |||
| f590d7cec8 | |||
| b14ff8ac52 | |||
| 74d033cb72 |
5 changed files with 60 additions and 43 deletions
|
|
@ -1250,7 +1250,7 @@ pub fn completion(self: *Self, from: tp.pid_ref, file_path: []const u8, row: usi
|
|||
pub fn receive(self_: @This(), response: tp.message) (CompletionError || cbor.Error)!void {
|
||||
var result: []const u8 = undefined;
|
||||
if (try cbor.match(response.buf, .{ "child", tp.string, "result", tp.null_ })) {
|
||||
try send_content_msg_empty(self_.from.ref(), "hover", self_.file_path, self_.row, self_.col);
|
||||
send_completion_done(self_.from.ref(), self_.file_path, self_.row, self_.col);
|
||||
} else if (try cbor.match(response.buf, .{ "child", tp.string, "result", tp.array })) {
|
||||
if (try cbor.match(response.buf, .{ tp.any, tp.any, tp.any, tp.extract_cbor(&result) }))
|
||||
try send_completion_items(self_.from.ref(), self_.file_path, self_.row, self_.col, result, false);
|
||||
|
|
@ -1343,9 +1343,7 @@ fn send_completion_list(to: tp.pid_ref, file_path: []const u8, row: usize, col:
|
|||
return if (items.len > 0)
|
||||
send_completion_items(to, file_path, row, col, items, is_incomplete)
|
||||
else
|
||||
to.send(.{ "cmd", "add_completion_done", .{ file_path, row, col } }) catch |e| {
|
||||
std.log.err("send add_completion_done failed: {t}", .{e});
|
||||
};
|
||||
send_completion_done(to, file_path, row, col);
|
||||
}
|
||||
|
||||
pub const CompletionItemError = error{
|
||||
|
|
@ -1361,6 +1359,10 @@ fn send_completion_items(to: tp.pid_ref, file_path: []const u8, row: usize, col:
|
|||
if (!(try cbor.matchValue(&iter, cbor.extract_cbor(&item)))) return error.InvalidCompletionItem;
|
||||
try send_completion_item(to, file_path, row, col, item, if (len > 1) true else is_incomplete);
|
||||
}
|
||||
send_completion_done(to, file_path, row, col);
|
||||
}
|
||||
|
||||
fn send_completion_done(to: tp.pid_ref, file_path: []const u8, row: usize, col: usize) void {
|
||||
return to.send(.{ "cmd", "add_completion_done", .{ file_path, row, col } }) catch |e| {
|
||||
std.log.err("send add_completion_done failed: {t}", .{e});
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1508,9 +1508,6 @@ pub fn refresh_from_file(self: *Self) LoadFromFileError!void {
|
|||
}
|
||||
|
||||
pub fn store_to_string_cached(self: *Self, root: *const Node, eol_mode: EolMode) [:0]const u8 {
|
||||
std.log.debug("BEGIN store_to_string_cached 0x{x}", .{root.to_ref()});
|
||||
defer std.log.debug("END store_to_string_cached 0x{x}", .{root.to_ref()});
|
||||
|
||||
if (get_cached_text(self.cache, root.to_ref(), eol_mode)) |text| return text;
|
||||
var s: std.Io.Writer.Allocating = std.Io.Writer.Allocating.initCapacity(self.external_allocator, root.weights_sum().len) catch @panic("OOM store_to_string_cached");
|
||||
root.store(&s.writer, eol_mode) catch @panic("store_to_string_cached");
|
||||
|
|
@ -1519,9 +1516,6 @@ pub fn store_to_string_cached(self: *Self, root: *const Node, eol_mode: EolMode)
|
|||
|
||||
pub fn store_last_save_to_string_cached(self: *Self, eol_mode: EolMode) ?[]const u8 {
|
||||
const root = self.last_save orelse return null;
|
||||
std.log.debug("BEGIN store_last_save_to_string_cached 0x{x}", .{root.to_ref()});
|
||||
defer std.log.debug("END store_last_save_to_string_cached 0x{x}", .{root.to_ref()});
|
||||
|
||||
if (get_cached_text(self.last_save_cache, root.to_ref(), eol_mode)) |text| return text;
|
||||
var s: std.Io.Writer.Allocating = std.Io.Writer.Allocating.initCapacity(self.external_allocator, root.weights_sum().len) catch @panic("OOM store_last_save_to_string_cached");
|
||||
root.store(&s.writer, eol_mode) catch @panic("store_last_save_to_string_cached");
|
||||
|
|
@ -1530,20 +1524,12 @@ pub fn store_last_save_to_string_cached(self: *Self, eol_mode: EolMode) ?[]const
|
|||
|
||||
fn get_cached_text(cache_: ?StringCache, ref: Node.Ref, eol_mode: EolMode) ?[:0]const u8 {
|
||||
const cache = cache_ orelse return null;
|
||||
return if (cache.ref == ref and cache.eol_mode == eol_mode) blk: {
|
||||
std.log.debug("fetched string cache 0x{x}", .{cache.ref});
|
||||
break :blk cache.text;
|
||||
} else blk: {
|
||||
std.log.debug("cache miss for 0x{x} (was 0x{x})", .{ ref, cache.ref });
|
||||
break :blk null;
|
||||
};
|
||||
return if (cache.ref == ref and cache.eol_mode == eol_mode) cache.text else null;
|
||||
}
|
||||
|
||||
fn store_cached_text(self: *Self, cache: *?StringCache, ref: Node.Ref, eol_mode: EolMode, text: [:0]const u8) [:0]const u8 {
|
||||
if (cache.*) |*c| {
|
||||
std.log.debug("0x{x} updated string cache 0x{x} -> 0x{x}", .{ @intFromPtr(self), c.ref, ref });
|
||||
if (cache.*) |*c|
|
||||
c.deinit(self.external_allocator);
|
||||
} else std.log.debug("0x{x} stored string cache 0x{x}", .{ @intFromPtr(self), ref });
|
||||
cache.* = .{
|
||||
.ref = ref,
|
||||
.eol_mode = eol_mode,
|
||||
|
|
@ -1559,7 +1545,6 @@ const StringCache = struct {
|
|||
code_folded: ?[:0]const u8 = null,
|
||||
|
||||
fn deinit(self: *@This(), allocator: std.mem.Allocator) void {
|
||||
std.log.debug("cleared string cache 0x{x}", .{self.ref});
|
||||
allocator.free(self.text);
|
||||
if (self.code_folded) |text| allocator.free(text);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -440,9 +440,15 @@ pub const Editor = struct {
|
|||
is_complete: bool = true,
|
||||
|
||||
const empty: @This() = .{};
|
||||
const pending: @This() = .empty;
|
||||
const done: ?@This() = null;
|
||||
|
||||
fn pending(row: usize, col: usize) @This() {
|
||||
return .{
|
||||
.row = row,
|
||||
.col = col,
|
||||
};
|
||||
}
|
||||
|
||||
fn deinit(self: *@This(), allocator: std.mem.Allocator) void {
|
||||
self.data.deinit(allocator);
|
||||
self.* = .empty;
|
||||
|
|
@ -3559,7 +3565,7 @@ pub const Editor = struct {
|
|||
try move_cursor_right(root, cursor, metrics);
|
||||
}
|
||||
|
||||
fn move_cursor_word_left(root: Buffer.Root, cursor: *Cursor, metrics: Buffer.Metrics) error{Stop}!void {
|
||||
pub fn move_cursor_word_left(root: Buffer.Root, cursor: *Cursor, metrics: Buffer.Metrics) error{Stop}!void {
|
||||
try move_cursor_left(root, cursor, metrics);
|
||||
move_cursor_left_until(root, cursor, is_word_boundary_left, metrics);
|
||||
}
|
||||
|
|
@ -4202,8 +4208,13 @@ pub const Editor = struct {
|
|||
root = try self.indent_cursor(root, sel.end, true, allocator);
|
||||
if (sel_from_start)
|
||||
sel_.begin.col = 0;
|
||||
cursel.cursor.clamp_to_buffer(root, self.metrics);
|
||||
return root;
|
||||
} else return try self.indent_cursor(root_, cursel.cursor, self.cursels.items.len > 1, allocator);
|
||||
} else {
|
||||
const root = try self.indent_cursor(root_, cursel.cursor, self.cursels.items.len > 1, allocator);
|
||||
cursel.cursor.clamp_to_buffer(root, self.metrics);
|
||||
return root;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn indent(self: *Self, ctx: Context) Result {
|
||||
|
|
@ -6285,10 +6296,14 @@ pub const Editor = struct {
|
|||
|
||||
pub fn completion(self: *Self, _: Context) Result {
|
||||
const mv = tui.mainview() orelse return;
|
||||
if (self.completions_request) |_|
|
||||
self.completions_refresh_pending = true
|
||||
else
|
||||
self.completions_request = .pending;
|
||||
const cursor = self.get_primary().cursor;
|
||||
if (self.completions_request) |request| {
|
||||
if (request.row != cursor.row or request.col != cursor.col)
|
||||
self.completions_refresh_pending = true;
|
||||
return;
|
||||
} else {
|
||||
self.completions_request = .pending(cursor.row, cursor.col);
|
||||
}
|
||||
if (!mv.is_any_panel_view_showing())
|
||||
self.clamp_offset(mv.get_panel_height());
|
||||
return self.pm_with_primary_cursor_pos(project_manager.completion);
|
||||
|
|
|
|||
|
|
@ -151,6 +151,9 @@ fn maybe_update_query(self: *Type, cursor: Buffer.Cursor) error{OutOfMemory}!voi
|
|||
if (!std.mem.eql(u8, query, last))
|
||||
try update_query_text(self, cursor);
|
||||
} else try update_query_text(self, cursor);
|
||||
|
||||
if (self.match_count == 0)
|
||||
tp.self_pid().send(.{ "cmd", "completion" }) catch |e| self.logger.err(module_name, e);
|
||||
}
|
||||
|
||||
fn update_query_text(self: *Type, cursor: ed.Cursor) error{OutOfMemory}!void {
|
||||
|
|
@ -298,15 +301,30 @@ const Range = struct { start: Position, end: Position };
|
|||
const Position = struct { line: usize, character: usize };
|
||||
|
||||
pub fn get_query_selection(editor: *ed.Editor, values: Values) ?Buffer.Selection {
|
||||
return get_replacement_selection(editor, values.insert, values.replace);
|
||||
return get_replacement_selection(editor, values.insert, values.replace, null);
|
||||
}
|
||||
|
||||
fn get_replacement_selection(editor: *ed.Editor, insert_: ?Buffer.Selection, replace_: ?Buffer.Selection) Buffer.Selection {
|
||||
fn get_replacement_selection(editor: *ed.Editor, insert_: ?Buffer.Selection, replace_: ?Buffer.Selection, query: ?Buffer.Selection) Buffer.Selection {
|
||||
const pos = switch (tui.config().completion_insert_mode) {
|
||||
.replace => replace_ orelse insert_ orelse return ed.Selection.from_cursor(&editor.get_primary().cursor),
|
||||
.insert => insert_ orelse replace_ orelse return ed.Selection.from_cursor(&editor.get_primary().cursor),
|
||||
.replace => replace_ orelse insert_,
|
||||
.insert => insert_ orelse 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;
|
||||
};
|
||||
var sel = pos.from_pos(editor.buf_root() catch return ed.Selection.from_cursor(&editor.get_primary().cursor), editor.metrics);
|
||||
sel.normalize();
|
||||
const cursor = editor.get_primary().cursor;
|
||||
return switch (tui.config().completion_insert_mode) {
|
||||
|
|
@ -315,8 +333,8 @@ fn get_replacement_selection(editor: *ed.Editor, insert_: ?Buffer.Selection, rep
|
|||
};
|
||||
}
|
||||
|
||||
fn get_insert_selection(editor: *ed.Editor, values: Values) Buffer.Selection {
|
||||
return get_replacement_selection(editor, values.insert, values.replace);
|
||||
fn get_insert_selection(editor: *ed.Editor, values: Values, query: ?Buffer.Selection) Buffer.Selection {
|
||||
return get_replacement_selection(editor, values.insert, values.replace, query);
|
||||
}
|
||||
|
||||
pub fn complete(self: *Type, _: ?*Type.ButtonType) !void {
|
||||
|
|
@ -326,7 +344,7 @@ pub fn complete(self: *Type, _: ?*Type.ButtonType) !void {
|
|||
fn select(menu: **Type.MenuType, button: *Type.ButtonType, _: Type.Pos) void {
|
||||
const self = menu.*.opts.ctx;
|
||||
const values = get_values(button.opts.label);
|
||||
const sel = get_insert_selection(self.value.editor, values);
|
||||
const sel = get_insert_selection(self.value.editor, values, self.value.query);
|
||||
const text = if (values.insertText.len > 0)
|
||||
values.insertText
|
||||
else if (values.textEdit_newText.len > 0)
|
||||
|
|
@ -372,11 +390,6 @@ const cmds = struct {
|
|||
const Result = command.Result;
|
||||
|
||||
pub fn update_completion(self: *Type, _: Ctx) Result {
|
||||
if (self.value.editor.completions.data.items.len == 0) {
|
||||
tp.self_pid().send(.{ "cmd", "palette_menu_cancel" }) catch |e| self.logger.err(module_name, e);
|
||||
return;
|
||||
}
|
||||
|
||||
clear_entries(self);
|
||||
self.longest_hint = try load_entries(self);
|
||||
try update_query_text(self, self.value.editor.get_primary().cursor);
|
||||
|
|
|
|||
|
|
@ -328,16 +328,18 @@ pub fn Create(options: type) type {
|
|||
};
|
||||
|
||||
var matches: std.ArrayList(Match) = .empty;
|
||||
var match_count: usize = 0;
|
||||
|
||||
for (self.entries.items) |*entry| {
|
||||
const match = searcher.scoreMatches(entry.label, query);
|
||||
if (match.score) |_| match_count += 1;
|
||||
(try matches.addOne(self.allocator)).* = .{
|
||||
.entry = entry,
|
||||
.score = match.score orelse 0,
|
||||
.matches = try self.allocator.dupe(usize, match.matches),
|
||||
};
|
||||
}
|
||||
if (matches.items.len == 0) return 0;
|
||||
if (matches.items.len == 0) return match_count;
|
||||
|
||||
const less_fn = struct {
|
||||
fn less_fn(_: void, lhs: Match, rhs: Match) bool {
|
||||
|
|
@ -358,7 +360,7 @@ pub fn Create(options: type) type {
|
|||
if (self.items < self.view_rows)
|
||||
try options.add_menu_entry(self, match.entry, match.matches);
|
||||
}
|
||||
return matches.items.len;
|
||||
return match_count;
|
||||
}
|
||||
|
||||
fn cmd(_: *Self, name_: []const u8, ctx: command.Context) tp.result {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue