diff --git a/src/tui/editor.zig b/src/tui/editor.zig index 09e232c..065e223 100644 --- a/src/tui/editor.zig +++ b/src/tui/editor.zig @@ -351,6 +351,9 @@ pub const Editor = struct { diag_hints: usize = 0, completions: std.ArrayListUnmanaged(u8) = .empty, + completion_row: usize = 0, + completion_col: usize = 0, + completion_is_complete: bool = true, enable_auto_save: bool, enable_format_on_save: bool, @@ -1148,6 +1151,7 @@ pub const Editor = struct { self.render_diagnostics(theme, hl_row, ctx_.cell_map) catch {}; self.render_column_highlights() catch {}; self.render_cursors(theme, ctx_.cell_map) catch {}; + self.render_completions(theme) catch |e| self.logger.err("completion", e); } fn render_cursors(self: *Self, theme: *const Widget.Theme, cell_map: CellMap) !void { @@ -1579,6 +1583,57 @@ pub const Editor = struct { }; } + fn render_completions(self: *Self, theme: *const Widget.Theme) !void { + const frame = tracy.initZone(@src(), .{ .name = "completions" }); + defer frame.deinit(); + const primary = self.get_primary(); + const completion_point: Cursor = .{ .row = self.completion_row, .col = self.completion_col }; + if (!primary.cursor.eql(completion_point)) return; + const pos = self.screen_cursor(&completion_point) orelse return; + + var i: usize = 0; + var iter: []const u8 = self.completions.items; + while (iter.len > 0) : (i += 1) { + const len = cbor.decodeArrayHeader(&iter) catch return error.BadArray; + if (len != 22) return error.BadLength; + + var label: []const u8 = ""; + // var insert_: Selection = .{}; + // var replace_: Selection = .{}; + + try cbor.skipValue(&iter); // file_path + try cbor.skipValue(&iter); // row + try cbor.skipValue(&iter); // col + try cbor.skipValue(&iter); // is_incomplete + if (!try cbor.matchValue(&iter, cbor.extract_cbor(&label))) return error.BadLabel; // label + try cbor.skipValue(&iter); // label_detail + try cbor.skipValue(&iter); // label_description + try cbor.skipValue(&iter); // kind + try cbor.skipValue(&iter); // detail + try cbor.skipValue(&iter); // documentation + try cbor.skipValue(&iter); // documentation_kind + try cbor.skipValue(&iter); // sortText + try cbor.skipValue(&iter); // insertTextFormat + try cbor.skipValue(&iter); // textEdit_newText + try cbor.skipValue(&iter); // if (try cbor.matchValue(&iter, cbor.extract(&insert_.begin.row))) return error.BadInsertBeginRow; // insert.begin.row + try cbor.skipValue(&iter); // if (try cbor.matchValue(&iter, cbor.extract(&insert_.begin.col))) return error.BadInsertBeginCol; // insert.begin.col + try cbor.skipValue(&iter); // if (try cbor.matchValue(&iter, cbor.extract(&insert_.end.row))) return error.BadInsertEndRow; // insert.end.row + try cbor.skipValue(&iter); // if (try cbor.matchValue(&iter, cbor.extract(&insert_.end.col))) return error.BadInsertEndCol; // insert.end.col + try cbor.skipValue(&iter); // if (try cbor.matchValue(&iter, cbor.extract(&replace_.begin.row))) return error.BadReplaceBeginRow; // replace.begin.row + try cbor.skipValue(&iter); // if (try cbor.matchValue(&iter, cbor.extract(&replace_.begin.col))) return error.BadReplaceBeginCol; // replace.begin.col + try cbor.skipValue(&iter); // if (try cbor.matchValue(&iter, cbor.extract(&replace_.end.row))) return error.BadReplaceEndRow; // replace.end.row + try cbor.skipValue(&iter); // if (try cbor.matchValue(&iter, cbor.extract(&replace_.end.col))) return error.BadReplaceEndCol; // replace.end.col + + if (i == 0) { + self.plane.cursor_move_yx(@intCast(pos.row), @intCast(pos.col)) catch return; + self.plane.set_style(theme.editor_hint); + _ = self.plane.putstr(label) catch {}; + } + } + + self.logger.print("completions: {d}", .{i}); + } + fn style_cache_lookup(theme: *const Widget.Theme, cache: *StyleCache, scope: []const u8, id: u32) ?Widget.Theme.Token { return if (cache.get(id)) |sty| ret: { break :ret sty; @@ -5652,10 +5707,13 @@ pub const Editor = struct { } 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)) { + self.completions.clearRetainingCapacity(); + self.completion_row = row; + self.completion_col = col; + } try self.completions.appendSlice(self.allocator, msg.buf); - _ = row; - _ = col; - _ = is_incomplete; + self.completion_is_complete = is_incomplete; } pub fn select(self: *Self, ctx: Context) Result {