summaryrefslogtreecommitdiff
path: root/src/lsp/lsp_zls.zig
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-09-15 18:27:49 -0300
committerGabriel Schneider <[email protected]>2026-10-01 00:12:14 -0300
commit4a3c5a48224cf542429504e8728e10c802e1fd52 (patch)
tree92b9b0922d8e37abd0af68cc014433449be29f05 /src/lsp/lsp_zls.zig
parentf3a9a1a9005024923f32e1acae5ecd509e9bbfd2 (diff)
downloadpardes-4a3c5a48224cf542429504e8728e10c802e1fd52.tar.gz
pardes-4a3c5a48224cf542429504e8728e10c802e1fd52.zip
Highlight exact source occurrences in LSP references and goto results
Diffstat (limited to 'src/lsp/lsp_zls.zig')
-rw-r--r--src/lsp/lsp_zls.zig34
1 files changed, 31 insertions, 3 deletions
diff --git a/src/lsp/lsp_zls.zig b/src/lsp/lsp_zls.zig
index 47e6a165..68538125 100644
--- a/src/lsp/lsp_zls.zig
+++ b/src/lsp/lsp_zls.zig
@@ -512,7 +512,7 @@ fn rowForToken(arena: std.mem.Allocator, base: []const u8, th: Analyser.TokenWit
if (th.token >= tree.tokens.len) return;
const r = offsets.tokenToRange(tree, th.token, enc);
const path = lsp.rel(base, th.handle.uri.toFsPath(arena) catch return);
- try lsp.spanRow(out, path, r.start.line, r.start.character, r.end.line, r.end.character, lineAt(tree.source, r.start.line));
+ try lsp.sourceSpanRow(out, path, r.start.line, r.start.character, r.end.line, r.end.character, lineAt(tree.source, r.start.line));
}
// ---------------------------------------------------------------- goto
@@ -667,7 +667,7 @@ fn goto(
const t2 = &nd.handle.tree;
const rr = offsets.nodeToRange(t2, nd.node, enc);
const path = lsp.rel(base, nd.handle.uri.toFsPath(arena) catch continue);
- try lsp.spanRow(out, path, rr.start.line, rr.start.character, rr.end.line, rr.end.character, lineAt(t2.source, rr.start.line));
+ try lsp.sourceSpanRow(out, path, rr.start.line, rr.start.character, rr.end.line, rr.end.character, lineAt(t2.source, rr.start.line));
},
}
}
@@ -1165,7 +1165,7 @@ fn references(
try lsp.edit(out, at, at + want.len);
} else {
const r = offsets.tokenToRange(tree, tok, enc);
- try lsp.spanRow(out, path, r.start.line, r.start.character, r.end.line, r.end.character, lines.?.line(r.start.line));
+ try lsp.sourceSpanRow(out, path, r.start.line, r.start.character, r.end.line, r.end.character, lines.?.line(r.start.line));
}
}
}
@@ -1474,3 +1474,31 @@ test "LSP ZLS rename refuses a partial edit set beyond its row budget" {
}
}
}
+
+test "LSP source snippets retain native definition and reference indentation" {
+ const source = "const Outer = struct {\n" ++
+ "\t const value: u32 = 1;\n" ++
+ "\t fn use() void {\n" ++
+ "\t\t_ = value;\n" ++
+ "\t }\n" ++
+ "};\n";
+ const gpa = std.testing.allocator;
+ for ([_]lsp.Kind{ .definition, .declaration, .references }) |kind| {
+ var arena: std.heap.ArenaAllocator = .init(gpa);
+ defer arena.deinit();
+ var out: std.Io.Writer.Allocating = .init(gpa);
+ defer out.deinit();
+ try query(gpa, arena.allocator(), .{
+ .kind = kind,
+ .path = "/source-snippet.zig",
+ .root = "/",
+ .source = source,
+ .offset = @intCast(std.mem.lastIndexOf(u8, source, "value").?),
+ }, &out.writer);
+ const definition = "source-snippet.zig:2:10-14 \t const value: u32 = 1;\n";
+ try std.testing.expectEqualStrings(if (kind == .references)
+ definition ++ "source-snippet.zig:4:7-11 \t\t_ = value;\n"
+ else
+ definition, out.written());
+ }
+}