From 39149c051a79e7d5148522b9851768a8e5b2ab54 Mon Sep 17 00:00:00 2001 From: Gabriel Schneider Date: Wed, 30 Sep 2026 17:33:18 -0300 Subject: A terminal's word looks refill the directory's one +Search, as +Lsp is shared, rather than stacking one per word Each word looked for in a terminal (clicked, or written to look), where no file of that name was, opened another +Search in the same directory, one per word, until the column filled. Such a search now refills the directory's +Search, as the file searches and the +Lsp answers already share theirs. A `/` search keeps a +Search per pattern, which n and N walk across (psearch.snap), so the sharing is marked on the word look alone (Pardes.word_look). Co-Authored-By: Claude Opus 5.5 --- src/Output.zig | 25 ++++++++++++++++++++++++- src/look.zig | 2 ++ src/pardes.zig | 3 +++ 3 files changed, 29 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/Output.zig b/src/Output.zig index 3541fa57..01797cbe 100644 --- a/src/Output.zig +++ b/src/Output.zig @@ -164,6 +164,24 @@ test "stacked empty previews distinguish separators from trailing newlines" { try std.testing.expect(!locations.sameInput("x.c:1:1 \n", "x.c:1:1\n", &rows, .stacked)); } +test "two words looked for in a terminal share the directory's one +Search" { + const p = try Pardes.init(std.testing.allocator, .{ .tty_only = true }); + defer p.deinit(); + const term = for (p.panes, 0..) |slot, id| { + if (slot) |pane| if (pane.isTerminal()) break id; + } else return error.SkipZigTest; + p.word_look = true; + defer p.word_look = false; + try fillResults(p, term, "/work", .search, "foo", try p.gpa.dupe(u8, "a.txt:1:1 foo\n"), null); + try fillResults(p, term, "/work", .search, "bar", try p.gpa.dupe(u8, "a.txt:2:1 bar\n"), null); + var searches: usize = 0; + for (p.panes) |slot| { + const f = (slot orelse continue).file orelse continue; + searches += @intFromBool(std.mem.eql(u8, f.path, "/work/+Search")); + } + try std.testing.expectEqual(@as(usize, 1), searches); +} + test "Lspinfo and Lspwhy fill one +Lsp in a directory" { const p = try Pardes.init(std.testing.allocator, .{ .tty_only = true }); defer p.deinit(); @@ -506,7 +524,12 @@ pub fn fillResults(p: *Pardes, id: usize, dir: []const u8, from: Origin, arg: [] const rp = slot orelse continue; const rf = if (rp.file) |*f| f else continue; const o = if (rf.output) |*x| x else continue; - const shared = (fileSearch(from) and fileSearch(o.from)) or (lspProse(from) and lspProse(o.from)); + // A file search's rows share the directory's one +Search, and so do + // a terminal's word looks (a look of a word no file names, clicked + // or written): the next word refills it rather than stacking + // another. A `/` search keeps a +Search each, which n and N walk. + const terminal_word = p.word_look and from == .search and pane.isTerminal() and o.from == .search; + const shared = (fileSearch(from) and fileSearch(o.from)) or terminal_word or (lspProse(from) and lspProse(o.from)); if (i == id and !shared) continue; if (!shared and !std.meta.eql(o.from, from)) continue; if (!shared and by_arg and !std.mem.eql(u8, o.arg(), arg)) continue; diff --git a/src/look.zig b/src/look.zig index 0f99722d..e22f5705 100644 --- a/src/look.zig +++ b/src/look.zig @@ -1346,6 +1346,8 @@ fn lookUnresolved(p: *Pardes, id: usize, pane: *Pane, trimmed: []const u8, text: if (pane.image != null or (pane.body.mode == .tty and !p.fs.serving)) return; if (text.len == 0) return; if (p.settings.look_word == .search and pane.file != null) return lookWord(p, id, pane, text); + p.word_look = true; + defer p.word_look = false; const rows = runSearch(p, id, text, .text, .cursor, false) catch |err| { p.reportError(id, "search", err); return; diff --git a/src/pardes.zig b/src/pardes.zig index dc2ec59f..8c6ad5bb 100644 --- a/src/pardes.zig +++ b/src/pardes.zig @@ -4296,6 +4296,9 @@ pub const Pardes = struct { /// (exec.placeNew): closed at the step's end, once whatever made them /// is done with them. unplaced: std.StaticBitSet(MAX_PANES) = .initEmpty(), + /// A look's word search is running (look.lookUnresolved): from a + /// terminal its rows refill the directory's one +Search (Output). + word_look: bool = false, /// The running word came from the workspace's or a column's tag, which /// have no directory of their own: it runs in the session's /// (`sessionDir`), as acme's row and column tags do. -- cgit v1.3