diff options
| author | Gabriel Schneider <[email protected]> | 2026-09-30 13:34:46 -0300 |
|---|---|---|
| committer | Gabriel Schneider <[email protected]> | 2026-10-01 00:12:17 -0300 |
| commit | c4504325deefd4a8fb905db95b4e8b5003fb2a6a (patch) | |
| tree | 7fdb4599d56e422517ac0f7be2cdf18b66f5a7bf | |
| parent | 07781fa9c673fb793be8cc39b568ae4db04533ab (diff) | |
| download | pardes-c4504325deefd4a8fb905db95b4e8b5003fb2a6a.tar.gz pardes-c4504325deefd4a8fb905db95b4e8b5003fb2a6a.zip | |
Lspinfo, Lspwhy and the other +Lsp answers share one +Lsp pane per directory
Each query kind found its own output pane by its origin. So Lspinfo and
Lspwhy, which both write `<dir>/+Lsp`, opened two panes of the same name
in one directory, and so could a code action list or a format diff. The
language server's prose now shares one +Lsp per directory, the way the
file searches share one +Search, and each answer replaces the last.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
| -rw-r--r-- | src/Output.zig | 25 |
1 files changed, 24 insertions, 1 deletions
diff --git a/src/Output.zig b/src/Output.zig index 545637b3..3541fa57 100644 --- a/src/Output.zig +++ b/src/Output.zig @@ -164,6 +164,23 @@ test "stacked empty previews distinguish separators from trailing newlines" { try std.testing.expect(!locations.sameInput("x.c:1:1 \n", "x.c:1:1\n", &rows, .stacked)); } +test "Lspinfo and Lspwhy fill one +Lsp in a directory" { + const p = try Pardes.init(std.testing.allocator, .{ .tty_only = true }); + defer p.deinit(); + _ = try p.setTestFile("x\n"); + try fillResults(p, 0, "/work", .{ .query = .status }, "", try p.gpa.dupe(u8, "servers\n"), null); + try fillResults(p, 0, "/work", .{ .query = .explain }, "", try p.gpa.dupe(u8, "why\n"), null); + var lsp_panes: usize = 0; + for (p.panes) |slot| { + const f = (slot orelse continue).file orelse continue; + if (std.mem.eql(u8, f.path, "/work/+Lsp")) { + lsp_panes += 1; + try std.testing.expectEqualStrings("why\n", f.content); + } + } + try std.testing.expectEqual(@as(usize, 1), lsp_panes); +} + test "plain output does not opt into location decoration" { const report = rowDecoration(.{ .from = .{ .cmd = .LocationsConfig } }, "LocationsConfig context:5 tscontext:on"); try std.testing.expectEqualDeep(RowDecoration{}, report); @@ -439,6 +456,12 @@ fn fileSearch(from: Origin) bool { return from != .search and std.mem.eql(u8, traits(from).name, config.search_buffer); } +/// A language server's prose (Lspinfo, Lspwhy, a code action list, a +/// format diff): one `+Lsp` a directory holds for all of them. +fn lspProse(from: Origin) bool { + return from == .query and std.mem.eql(u8, traits(from).name, config.lsp_buffer); +} + pub fn fillResults(p: *Pardes, id: usize, dir: []const u8, from: Origin, arg: []const u8, content: []u8, initial_anchor: ?usize) !void { var result_content = content; errdefer p.gpa.free(result_content); @@ -483,7 +506,7 @@ pub fn fillResults(p: *Pardes, id: usize, dir: []const u8, from: Origin, arg: [] const rp = slot orelse continue; const rf = if (rp.file) |*f| f else continue; const o = if (rf.output) |*x| x else continue; - const shared = fileSearch(from) and fileSearch(o.from); + const shared = (fileSearch(from) and fileSearch(o.from)) or (lspProse(from) and lspProse(o.from)); if (i == id and !shared) continue; if (!shared and !std.meta.eql(o.from, from)) continue; if (!shared and by_arg and !std.mem.eql(u8, o.arg(), arg)) continue; |
