diff --git a/src/project_manager.zig b/src/project_manager.zig index 0b27dc9..180cd5b 100644 --- a/src/project_manager.zig +++ b/src/project_manager.zig @@ -248,6 +248,13 @@ pub fn completion(file_path: []const u8, row: usize, col: usize) (ProjectManager return send(.{ "completion", project, file_path, row, col }); } +pub fn symbols(file_path: []const u8) (ProjectManagerError || ProjectError)!void { + const project = tp.env.get().str("project"); + if (project.len == 0) + return error.NoProject; + return send(.{ "symbols", project, file_path }); +} + pub fn rename_symbol(file_path: []const u8, row: usize, col: usize) (ProjectManagerError || ProjectError)!void { const project = tp.env.get().str("project"); if (project.len == 0) @@ -441,6 +448,9 @@ const Process = struct { self.references(from, project_directory, path, row, col) catch |e| return from.forward_error(e, @errorReturnTrace()) catch error.ClientFailed; } else if (try cbor.match(m.buf, .{ "highlight_references", tp.extract(&project_directory), tp.extract(&path), tp.extract(&row), tp.extract(&col) })) { self.highlight_references(from, project_directory, path, row, col) catch |e| return from.forward_error(e, @errorReturnTrace()) catch error.ClientFailed; + } else if (try cbor.match(m.buf, .{ "symbols", tp.extract(&project_directory), tp.extract(&path) })) { + self.logger.print("received to continue symbols", .{}); + self.symbols(from, project_directory, path) catch |e| return from.forward_error(e, @errorReturnTrace()) catch error.ClientFailed; } else if (try cbor.match(m.buf, .{ "completion", tp.extract(&project_directory), tp.extract(&path), tp.extract(&row), tp.extract(&col) })) { self.completion(from, project_directory, path, row, col) catch |e| return from.forward_error(e, @errorReturnTrace()) catch error.ClientFailed; } else if (try cbor.match(m.buf, .{ "rename_symbol", tp.extract(&project_directory), tp.extract(&path), tp.extract(&row), tp.extract(&col) })) { @@ -677,6 +687,13 @@ const Process = struct { return project.highlight_references(from, file_path, row, col); } + fn symbols(self: *Process, from: tp.pid_ref, project_directory: []const u8, file_path: []const u8) (ProjectError || Project.InvalidMessageError || Project.LspOrClientError || cbor.Error)!void { + const frame = tracy.initZone(@src(), .{ .name = module_name ++ ".symbols" }); + defer frame.deinit(); + const project = self.projects.get(project_directory) orelse return error.NoProject; + return project.symbols(from, file_path); + } + fn completion(self: *Process, from: tp.pid_ref, project_directory: []const u8, file_path: []const u8, row: usize, col: usize) (ProjectError || Project.InvalidMessageError || Project.LspOrClientError || cbor.Error)!void { const frame = tracy.initZone(@src(), .{ .name = module_name ++ ".completion" }); defer frame.deinit(); diff --git a/src/tui/mainview.zig b/src/tui/mainview.zig index 9505888..928ff7a 100644 --- a/src/tui/mainview.zig +++ b/src/tui/mainview.zig @@ -54,6 +54,8 @@ buffer_manager: Buffer.Manager, find_in_files_state: enum { init, adding, done } = .done, file_list_type: FileListType = .find_in_files, panel_height: ?usize = null, +symbols: std.ArrayListUnmanaged(u8) = .empty, +symbols_complete: bool = true, const FileListType = enum { diagnostics, @@ -107,11 +109,17 @@ pub fn deinit(self: *Self, allocator: std.mem.Allocator) void { self.close_all_panel_views(); self.commands.deinit(); self.widgets.deinit(allocator); + self.symbols.deinit(allocator); self.floating_views.deinit(); self.buffer_manager.deinit(); allocator.destroy(self); } +// Receives the file_path to identify symbols to clear +pub fn clear_symbols(self: *Self, _: []const u8) void { + self.symbols.clearRetainingCapacity(); +} + pub fn receive(self: *Self, from_: tp.pid_ref, m: tp.message) error{Exit}!bool { var path: []const u8 = undefined; var begin_line: usize = undefined; @@ -941,6 +949,67 @@ const cmds = struct { }, }; + pub fn add_document_symbol_done(self: *Self, ctx: Ctx) Result { + const logger = log.logger("buffer"); + defer logger.deinit(); + var file_path: []const u8 = undefined; + + if (!try ctx.args.match(.{ + tp.extract(&file_path), + })) return error.InvalidAddDiagnosticArgument; + file_path = project_manager.normalize_file_path(file_path); + if (self.get_active_editor()) |editor| if (std.mem.eql(u8, file_path, editor.file_path orelse "")) { + self.symbols_complete = true; + logger.print("Fetched {} symbols", .{self.symbols.items.len}); + }; + } + pub const add_document_symbol_done_meta: Meta = .{ + .arguments = &.{ + .string, // file_path + }, + }; + + pub fn add_document_symbol(self: *Self, ctx: Ctx) Result { + const logger = log.logger("buffer"); + defer logger.deinit(); + var file_path: []const u8 = undefined; + var name: []const u8 = undefined; + var parent: []const u8 = undefined; + var kind: u8 = 0; + if (!try ctx.args.match(.{ + tp.extract(&file_path), + tp.extract(&name), + tp.extract(&parent), + tp.extract(&kind), + tp.more, + })) return error.InvalidAddDiagnosticArgument; + file_path = project_manager.normalize_file_path(file_path); + if (self.get_active_editor()) |editor| if (std.mem.eql(u8, file_path, editor.file_path orelse "")) { + logger.print("received symbol '{s}'", .{name}); + self.symbols_complete = false; + try self.symbols.appendSlice(self.allocator, ctx.args.buf); + }; + } + pub const add_document_symbol_meta: Meta = .{ + .arguments = &.{ + .string, // file_path + .string, // name + .string, // parent_name + .integer, // kind + .integer, // range.start.line + .integer, // range.start.column + .integer, // range.end.line + .integer, // range.end.column + .array, // tags + .integer, // selectionRange.start.line + .integer, // selectionRange.start.column + .integer, // selectionRange.end.line + .integer, // selectionRange.end.column + .boolean, // deprecated + .string, //detail + }, + }; + pub fn add_completion_done(self: *Self, ctx: Ctx) Result { var file_path: []const u8 = undefined; var row: usize = undefined;