summaryrefslogtreecommitdiff
path: root/src/lsp/lsp.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/lsp/lsp.zig')
-rw-r--r--src/lsp/lsp.zig29
1 files changed, 28 insertions, 1 deletions
diff --git a/src/lsp/lsp.zig b/src/lsp/lsp.zig
index a4489552..90d4fc6b 100644
--- a/src/lsp/lsp.zig
+++ b/src/lsp/lsp.zig
@@ -12,7 +12,8 @@
//! look.zig already resolves and what n/N already steps, so a multi-result
//! answer IS helix's picker and a single result IS a jump, with no picker UI
//! written for it. Free text (hover, a rename's diff) rides the same buffer as
-//! plain lines.
+//! plain lines. A path under `Req.root` is written relative to it and any
+//! other keeps its full absolute self — see `rel`.
//!
//! `query` is the ONLY thing an implementation supplies. Swapping backends is
//! swapping this one function, which is also how the three competing
@@ -95,8 +96,34 @@ pub const Req = struct {
root: []const u8 = "",
};
+/// How a row SPELLS a path: relative to `base` if it lives UNDER it, its full
+/// absolute self otherwise.
+///
+/// `base` is `Req.root` — the directory of the file the query was asked about
+/// — which is also the directory the results buffer is opened in, so a row
+/// shortened here reads as the name that window would have typed and still
+/// resolves when looked. `gr` over one file was otherwise the same
+/// forty-character absolute prefix repeated down the whole pane, with the part
+/// you came to read pushed off the right edge.
+///
+/// UNDER, not "shorter": a path outside that tree is left absolute rather than
+/// walked up to with `../`. An absolute path resolves from anywhere and says
+/// where it is; `../../..` says neither, and the moment the row is read
+/// somewhere other than beside its own buffer it is wrong.
+///
+/// This is `look.grep`'s `shown` rule, spelled a second time — see the note
+/// there; the two want to become one function.
+pub fn rel(base: []const u8, path: []const u8) []const u8 {
+ if (base.len == 0) return path;
+ const home = std.mem.trimEnd(u8, base, "/");
+ if (path.len > home.len and std.mem.startsWith(u8, path, home) and path[home.len] == '/')
+ return path[home.len + 1 ..];
+ return path;
+}
+
/// Emit one `path:LINE:COL text` row. Line and column are 1-based, the way
/// every other row in a `+Search` buffer is (and the way look.zig parses one).
+/// `path` has already been through `rel`: the caller holds the base.
pub fn row(
out: *std.Io.Writer,
path: []const u8,