diff options
| author | Gabriel Schneider <[email protected]> | 2026-10-01 06:22:44 -0300 |
|---|---|---|
| committer | Gabriel Schneider <[email protected]> | 2026-10-01 07:16:43 -0300 |
| commit | 85b60dedb6bdb192abd11b2d58ca7c0e8c944b18 (patch) | |
| tree | 13bc6a9f1f1551088c992a29cb365f5d0a63b239 /src/host_io.zig | |
| parent | fb330ce04c4eec4de317637d26310b74e2ee5923 (diff) | |
| download | pardes-85b60dedb6bdb192abd11b2d58ca7c0e8c944b18.tar.gz pardes-85b60dedb6bdb192abd11b2d58ca7c0e8c944b18.zip | |
A Rename, references and the like tell the server of every open file of its language first, so a rename reaches files it had not seen and the preview lists them
zls renames only in the documents in its store, and syncDoc told it of
a file only when a query was asked from it, so renaming in progress.zig
left main.zig unchanged and broken, with no preview. For a query whose
answer can reach other files (rename, references, implementation,
workspace symbols, calls and type hierarchy), the host snapshots every
other open file and the client syncs those its server answers for
first. The mock server answers a rename in each document it was told
of; lsp-rename-files opens main.rs by a look, renames from lib.rs, and
its preview lists both.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Diffstat (limited to 'src/host_io.zig')
| -rw-r--r-- | src/host_io.zig | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/src/host_io.zig b/src/host_io.zig index f944e1cb..9e9a37ed 100644 --- a/src/host_io.zig +++ b/src/host_io.zig @@ -143,12 +143,19 @@ pub const Lsp = struct { source: [:0]u8, arg: []u8, root: []u8, + /// The other open files, for a query that can reach them. + others: []pardes.lsp.Doc = &.{}, pub fn free(job: *Job, gpa: std.mem.Allocator) void { gpa.free(job.path); gpa.free(job.source); gpa.free(job.arg); gpa.free(job.root); + for (job.others) |doc| { + gpa.free(doc.path); + gpa.free(doc.source); + } + gpa.free(job.others); gpa.destroy(job); } }; @@ -169,6 +176,7 @@ pub const Lsp = struct { errdefer gpa.free(arg); const declared_root = if (file) |f| std.fs.path.dirname(f.path) orelse "/" else pane.cwdSlice(); const root = try gpa.dupe(u8, filesystem.localPath(declared_root) orelse declared_root); + errdefer gpa.free(root); job.* = .{ .id = req.id, .kind = req.kind, @@ -178,6 +186,32 @@ pub const Lsp = struct { .arg = arg, .root = root, }; + // ponytail: a copy of every open file per such query; a server + // already told of one is sent nothing more (syncDoc). + if (pardes.lsp.reachesOtherFiles(req.kind)) { + var others: std.ArrayList(pardes.lsp.Doc) = .empty; + errdefer { + for (others.items) |doc| { + gpa.free(doc.path); + gpa.free(doc.source); + } + others.deinit(gpa); + } + for (core.panes, 0..) |slot, i| { + const other = slot orelse continue; + if (i == req.pane) continue; + const f = other.file orelse continue; + if (f.output != null) continue; + const local = filesystem.localPath(f.path) orelse continue; + const other_path = try gpa.dupe(u8, local); + const other_source = gpa.dupeZ(u8, f.content) catch |err| { + gpa.free(other_path); + return err; + }; + try others.append(gpa, .{ .path = other_path, .source = other_source }); + } + job.others = try others.toOwnedSlice(gpa); + } return job; } @@ -197,6 +231,7 @@ pub const Lsp = struct { .offset = job.offset, .arg = job.arg, .root = job.root, + .others = job.others, }, &out.writer) catch { deliver(ctx, job.id, null); return; |
