diff options
Diffstat (limited to 'src/lsp/lsp.zig')
| -rw-r--r-- | src/lsp/lsp.zig | 29 |
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, |
