summaryrefslogtreecommitdiff
path: root/test/lspmock.zig
diff options
context:
space:
mode:
Diffstat (limited to 'test/lspmock.zig')
-rw-r--r--test/lspmock.zig31
1 files changed, 28 insertions, 3 deletions
diff --git a/test/lspmock.zig b/test/lspmock.zig
index 7b379b49..001c3488 100644
--- a/test/lspmock.zig
+++ b/test/lspmock.zig
@@ -97,6 +97,20 @@ fn range(a: std.mem.Allocator, line: u32, from: u32, to: u32) []const u8 {
var root_uri: [512]u8 = undefined;
var root_uri_len: usize = 0;
+/// The documents the editor has opened here (didOpen), as zls keeps its
+/// store: a rename answers in each of them, and in no file it never saw.
+var opened: [8][512]u8 = undefined;
+var opened_len: [8]usize = @splat(0);
+var opened_n: usize = 0;
+
+fn noteOpened(uri: []const u8) void {
+ for (opened[0..opened_n], opened_len[0..opened_n]) |*o, n| if (std.mem.eql(u8, o[0..n], uri)) return;
+ if (opened_n == opened.len or uri.len > opened[0].len) return;
+ @memcpy(opened[opened_n][0..uri.len], uri);
+ opened_len[opened_n] = uri.len;
+ opened_n += 1;
+}
+
pub fn main(init: std.process.Init) !void {
_ = init;
if (getenv("LSPMOCK_MODE")) |m| {
@@ -187,6 +201,7 @@ fn handle(a: std.mem.Allocator, raw: []const u8) void {
notify(a, "$/progress", "{{\"token\":\"t1\",\"value\":{{\"kind\":\"end\"}}}}", .{});
return;
}
+ if (std.mem.eql(u8, method, "textDocument/didOpen")) noteOpened(reqUri(params));
if (id == null) return; // didOpen/didChange/$/cancelRequest: nothing to say
if (mode == .mute) return; // swallow every request after the handshake
@@ -227,10 +242,20 @@ fn handle(a: std.mem.Allocator, raw: []const u8) void {
q, root_uri[0..root_uri_len], range(a, 1, 7, 10),
});
} else if (std.mem.eql(u8, method, "textDocument/rename")) {
+ // In every document it has seen: lib.rs's definition, main.rs's two
+ // calls (any other file reads as main.rs's shape).
const nn = str(get(params, "newName")) orelse "renamed";
- reply(a, rid, "{{\"changes\":{{\"{s}\":[{{\"range\":{s},\"newText\":\"{s}\"}},{{\"range\":{s},\"newText\":\"{s}\"}}]}}}}", .{
- uri, range(a, 3, 12, 15), nn, range(a, 4, 12, 15), nn,
- });
+ var changes: std.ArrayList(u8) = .empty;
+ for (opened[0..opened_n], opened_len[0..opened_n], 0..) |*o, n, k| {
+ const doc = o[0..n];
+ const edits = if (std.mem.endsWith(u8, doc, "/lib.rs"))
+ std.fmt.allocPrint(a, "[{{\"range\":{s},\"newText\":\"{s}\"}}]", .{ range(a, 1, 7, 10), nn }) catch return
+ else
+ std.fmt.allocPrint(a, "[{{\"range\":{s},\"newText\":\"{s}\"}},{{\"range\":{s},\"newText\":\"{s}\"}}]", .{ range(a, 3, 12, 15), nn, range(a, 4, 12, 15), nn }) catch return;
+ changes.print(a, "{s}\"{s}\":{s}", .{ if (k > 0) "," else "", doc, edits }) catch return;
+ }
+ if (opened_n == 0) changes.print(a, "\"{s}\":[{{\"range\":{s},\"newText\":\"{s}\"}},{{\"range\":{s},\"newText\":\"{s}\"}}]", .{ uri, range(a, 3, 12, 15), nn, range(a, 4, 12, 15), nn }) catch return;
+ reply(a, rid, "{{\"changes\":{{{s}}}}}", .{changes.items});
} else if (std.mem.eql(u8, method, "textDocument/formatting")) {
reply(a, rid, "[{{\"range\":{s},\"newText\":\"// formatted by mock\\n\"}}]", .{range(a, 0, 0, 0)});
} else if (std.mem.eql(u8, method, "textDocument/codeAction")) {