diff options
| author | Gabriel Schneider <[email protected]> | 2026-08-09 06:54:27 -0300 |
|---|---|---|
| committer | Gabriel Schneider <[email protected]> | 2026-08-10 09:17:07 -0300 |
| commit | 599dd82f96b9d091aae78300aa6c3fbc81f9eb69 (patch) | |
| tree | 532d29eb0d79896cd730fb324df4866056306506 /src/output_pane.zig | |
| parent | 628aa40f13e9bbd313b51ab625f193110aad8dd0 (diff) | |
| download | pardes-599dd82f96b9d091aae78300aa6c3fbc81f9eb69.tar.gz pardes-599dd82f96b9d091aae78300aa6c3fbc81f9eb69.zip | |
review pass: fix the eaten Tab, drop the duplicated code, cover the gaps
Diffstat (limited to 'src/output_pane.zig')
| -rw-r--r-- | src/output_pane.zig | 69 |
1 files changed, 69 insertions, 0 deletions
diff --git a/src/output_pane.zig b/src/output_pane.zig index bce3d503..1bf14b7c 100644 --- a/src/output_pane.zig +++ b/src/output_pane.zig @@ -236,6 +236,75 @@ pub fn open(p: *Pardes, id: usize, dir: []const u8, from: Origin, arg: []const u return pane; } +/// Land a freshly produced list of rows in the buffer it belongs in — the one +/// rule every results buffer follows, whichever side of the core made them. +/// +/// The SAME command asked again REFILLS the list it already opened rather than +/// stacking a byte-identical twin under the pane. That was runSearch's rule +/// from the start (right-clicking a word in four places is one +Search walked +/// four times) and language answers turned out to need it far more urgently: +/// Tab after a dot makes a query an ordinary typing keystroke, and without the +/// refill twenty of them fill every slot and the key is eaten for the rest of +/// the session — see docs/lsp.md. +/// +/// What "the same command" means comes off the ORIGIN. A search is identified +/// by its PATTERN, so `foo`, `bar`, `foo` re-arms foo's own buffer and leaves +/// bar's open; a language query is asked about a different symbol every time +/// with the same (usually empty) arg, so the arg cannot tell two apart and the +/// KIND is the natural unit — a second `gr` replaces the first list. Same +/// directory only, because the rows are written relative to it, and never the +/// asking pane itself (a `/` inside a +Search writes its own rows). +/// +/// `content` is gpa-owned: adopted by the buffer, or freed here when there is +/// nowhere to put it. `anchor` is the row n/N step from, null for the top. +pub fn fillResults(p: *Pardes, id: usize, dir: []const u8, from: Origin, arg: []const u8, content: []u8, anchor: ?usize) void { + const pane = p.panes[id] orelse { + p.gpa.free(content); + return; + }; + const by_arg = std.meta.activeTag(from) != .query; + for (p.panes, 0..) |slot, i| { + if (i == id) continue; + const rp = slot orelse continue; + const rf = if (rp.file) |*f| f else continue; + const o = if (rf.output) |*x| x else continue; + if (!std.meta.eql(o.from, from)) continue; + if (by_arg and !std.mem.eql(u8, o.arg(), arg)) continue; + if (!std.mem.eql(u8, std.fs.path.dirname(rf.path) orelse "", dir)) continue; + setArg(o, arg); + // a refill that changes NOTHING keeps its place: a right click on an + // already-armed word is an `n`, and throwing the list back to the top + // only to scroll down to the stepped row is a jump with no information + // in it. + const same = std.mem.eql(u8, rf.content, content); + file_pane.setContent(p, rf, content); + if (!same) rf.scroll = 0; + p.active = id; + if (traits(from).steps) { + pane.search_pane = i; + pane.search_row = anchor; + } + return; + } + const free = p.freeSlot() orelse { + p.gpa.free(content); + return; + }; + const np = open(p, free, dir, from, arg, content) catch { + p.gpa.free(content); + return; + }; + p.placeDoc(id, free, np); + p.active = id; + // prose is not a list of locations: n/N over a hover blurb would step to + // nowhere, so only stepping buffers arm the stepper — and WHICH command + // filled it is the buffer's own record, not a field on the asking pane. + if (traits(from).steps) { + pane.search_pane = free; + pane.search_row = anchor; + } +} + /// The Jumplist builtin: the focus history (Pardes.jumps) written out as text, /// one row per location, oldest first — the same `location text` shape every /// results buffer here has, which is what buys n/N stepping and Look-on-a-row |
