diff options
Diffstat (limited to 'src/pardes.zig')
| -rw-r--r-- | src/pardes.zig | 52 |
1 files changed, 49 insertions, 3 deletions
diff --git a/src/pardes.zig b/src/pardes.zig index eb9aa11f..f0d22d57 100644 --- a/src/pardes.zig +++ b/src/pardes.zig @@ -1112,6 +1112,36 @@ test "first document fallback splits like Tty from the originating pane" { }; } +test "Lspwhy after a Hover asks to explain that hover, at its place" { + if (!lsp.supports.contains(.hover)) return error.SkipZigTest; + const p = try Pardes.init(std.testing.allocator, .{ .tty_only = true }); + defer p.deinit(); + const pane = try p.setTestFile("const a = 1;\nconst b = a;\n"); + const f = &pane.file.?; + p.gpa.free(f.path); + f.path = try p.gpa.dupe(u8, "/tmp/x.zig"); + while (p.nextEffect()) |_| {} + pane.body.cur_row = 1; + pane.body.cur_col = 10; + p.lspRequest(0, .hover, ""); + var hover_at: u32 = 0; + while (p.nextEffect()) |e| if (e == .lsp) { + hover_at = e.lsp.offset; + }; + pane.body.cur_row = 0; + pane.body.cur_col = 0; + p.lsp_wait = null; + p.lspRequest(0, .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); + seen = true; + }; + try std.testing.expect(seen); +} + test "the Tutor pane is named +Tutor in the session's directory, never a bare path at the root" { const p = try Pardes.init(std.testing.allocator, .{ .tty_only = true }); defer p.deinit(); @@ -3553,7 +3583,9 @@ pub const Effect = union(enum) { write_dump, set_clipboard, read_clipboard, - lsp: struct { id: u32, kind: lsp.Kind, pane: u8, offset: u32, arg: Buf(128) }, + /// `arg` up to 128 bytes, or for `explain` the query it explains, + /// `<kind> <arg>`. + lsp: struct { id: u32, kind: lsp.Kind, pane: u8, offset: u32, arg: Buf(160) }, /// Snapshot the matching request with pipeRequest(id), then run it away /// from the UI/event loop and answer with pipe_resp. pipe: struct { id: u32 }, @@ -4351,6 +4383,9 @@ pub const Pardes = struct { can_ask: bool = false, lsp_seq: u32 = 0, + /// The last query asked (Lspwhy explains it): its kind, argument, and + /// the pane and place it was asked at. + lsp_last: ?struct { kind: lsp.Kind, arg: Effect.Buf(128), serial: u32, offset: u32 } = null, lsp_wait: ?struct { id: u32, kind: lsp.Kind, @@ -6295,6 +6330,17 @@ pub const Pardes = struct { .row = @intCast(@max(0, pane.body.cur_row)), .col = @intCast(@max(0, pane.body.cur_col)), }) else 0; + // Lspwhy asks the last query again, narrated: its kind and argument, + // at its place when asked from its pane. None yet: a definition. + var explained: [160]u8 = undefined; + var sent = arg; + var at = off; + 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; + } + } else if (kind != .status) p.lsp_last = .{ .kind = kind, .arg = .from(arg), .serial = pane.serial, .offset = @intCast(off) }; p.lsp_seq +%= 1; // A 9P write that asked it is answered once the answer is in. if (p.fs.serving) p.fs.lsp_answer_at = turn.lsp_answers; @@ -6312,8 +6358,8 @@ pub const Pardes = struct { .id = p.lsp_seq, .kind = kind, .pane = @intCast(id), - .offset = @intCast(off), - .arg = .from(arg), + .offset = @intCast(at), + .arg = .from(sent), } }); } |
