From 07781fa9c673fb793be8cc39b568ae4db04533ab Mon Sep 17 00:00:00 2001 From: Gabriel Schneider Date: Wed, 30 Sep 2026 13:32:35 -0300 Subject: Lspwhy explains the recorded last query in its own file and place, wherever it is run Lspwhy kept the last query's kind and argument, but ran from another pane it asked in that pane's file at its cursor. So it narrated a different lookup from the one that failed. When the pane the query was asked in is still open, Lspwhy now asks in it, at the query's offset, whichever pane it is run from. With that pane gone, it falls back to the pane it is run in. Co-Authored-By: Claude Opus 5.5 --- src/pardes.zig | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/pardes.zig b/src/pardes.zig index f61ba797..d8124588 100644 --- a/src/pardes.zig +++ b/src/pardes.zig @@ -1112,7 +1112,7 @@ test "first document fallback splits like Tty from the originating pane" { }; } -test "Lspwhy after a Hover asks to explain that hover, at its place" { +test "Lspwhy after a Hover asks to explain that hover, in its file at its place, run from any pane" { if (!lsp.supports.contains(.hover)) return error.SkipZigTest; const p = try Pardes.init(std.testing.allocator, .{ .tty_only = true }); defer p.deinit(); @@ -1131,12 +1131,16 @@ test "Lspwhy after a Hover asks to explain that hover, at its place" { pane.body.cur_row = 0; pane.body.cur_col = 0; p.lsp_wait = null; - p.lspRequest(0, .explain, ""); + // Run from another file's pane: still the hover's file and place. + const other = p.freeSlot().?; + _ = try p.openTutorView(other); + p.lspRequest(other, .explain, ""); var seen = false; while (p.nextEffect()) |e| if (e == .lsp) { try std.testing.expectEqual(lsp.Kind.explain, e.lsp.kind); try std.testing.expectEqualStrings("hover ", e.lsp.arg.slice()); try std.testing.expectEqual(hover_at, e.lsp.offset); + try std.testing.expectEqual(@as(u8, 0), e.lsp.pane); seen = true; }; try std.testing.expect(seen); @@ -6315,8 +6319,12 @@ pub const Pardes = struct { pub const SavePath = Effect.Buf(effect_path_cap); - pub fn lspRequest(p: *Pardes, id: usize, kind: lsp.Kind, arg: []const u8) void { + pub fn lspRequest(p: *Pardes, asked: usize, kind: lsp.Kind, arg: []const u8) void { if (!normal.multiOnce(p)) return; // one question per keystroke, from the primary + // Lspwhy narrates the last query where it was asked -- that pane's + // file, place and argument -- from wherever it is run. + const last_pane: ?usize = if (kind == .explain) (if (p.lsp_last) |last| p.paneBySerial(last.serial) else null) else null; + const id = last_pane orelse asked; var said: [128]u8 = undefined; if (!lsp.supports.contains(kind)) return p.reportFailure(id, std.fmt.bufPrint(&said, "{s}: no language server here answers it", .{lspWord(kind)}) catch "no language server answers it"); @@ -6346,7 +6354,7 @@ pub const Pardes = struct { if (kind == .explain) { if (p.lsp_last) |last| { sent = std.fmt.bufPrint(&explained, "{s} {s}", .{ @tagName(last.kind), last.arg.slice() }) catch ""; - if (last.serial == pane.serial) at = last.offset; + if (last_pane != null) at = last.offset; } } else if (kind != .status) p.lsp_last = .{ .kind = kind, .arg = .from(arg), .serial = pane.serial, .offset = @intCast(off) }; p.lsp_seq +%= 1; -- cgit v1.3