summaryrefslogtreecommitdiff
path: root/src/look.zig
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-09-29 04:45:20 -0300
committerGabriel Schneider <[email protected]>2026-10-01 00:12:15 -0300
commitbda5b5f621d0edd8e26f9700043ab21cae18f329 (patch)
treeb183df1b137f405a9dcecfe32769e374d2da5c50 /src/look.zig
parent85d5467023a9db801d8ea2538e9611b71cd10d9d (diff)
downloadpardes-bda5b5f621d0edd8e26f9700043ab21cae18f329.tar.gz
pardes-bda5b5f621d0edd8e26f9700043ab21cae18f329.zip
A looked word selects its next place in its own pane, as acme's look3
A plain word looked at (a look write, a right click, an ML record written back) opened another identically named +Search pane each time, until the panes ran out, and never wrapped. As acme's look3 searches the text for it (look.c:210), it now selects the word's next place in that pane after the dot, wrapping at the end, and opens nothing. LookWord list, a new root setting, keeps the +Search listing (search is the default); the rsearch snapshot and an output test that walk the listing say LookWord list. (The leader-path check over every builtin gets a comptime branch quota, as one more builtin took the GUI build past the default.) Co-Authored-By: Claude Opus 5.5 <[email protected]>
Diffstat (limited to 'src/look.zig')
-rw-r--r--src/look.zig19
1 files changed, 19 insertions, 0 deletions
diff --git a/src/look.zig b/src/look.zig
index 5d60e8b3..86238413 100644
--- a/src/look.zig
+++ b/src/look.zig
@@ -1229,6 +1229,24 @@ fn settleLine(p: *Pardes, id: usize, path: []const u8, at: Spot, before: usize,
}
}
+/// A plain word looked at in a pane, as acme's look3 does with one that
+/// names no file (look.c:210, search): its next place in that pane after
+/// the dot, wrapping to the top, is selected there. No +Search pane
+/// (`LookWord list` lists every place in one instead).
+fn lookWord(p: *Pardes, id: usize, pane: *Pane, word: []const u8) void {
+ const ninep_pane = @import("ninep/pane.zig");
+ const f = pane.file orelse return;
+ const text = f.content;
+ const from: usize = @min(ninep_pane.dotOf(pane).q1, text.len);
+ const at = std.mem.indexOfPos(u8, text, from, word) orelse (std.mem.indexOf(u8, text[0..@min(text.len, from + word.len -| 1)], word) orelse {
+ var cut: [miss_path_cap + "…".len]u8 = undefined;
+ return missed(p, id, "no match for \"{s}\"", .{missText(word, &cut)});
+ });
+ clearNavigationSelection(p, pane);
+ ninep_pane.setDot(pane, .{ .q0 = @intCast(at), .q1 = @intCast(at + word.len) });
+ p.active = id;
+}
+
/// `file:addr` or `:addr`, acme's look.c:450-543: a colon followed by an
/// address character (addr.c:28, isaddrc) that is not a line spot this
/// parser already reads (`file:12`, `file:12:5`). Not a URL.
@@ -1315,6 +1333,7 @@ pub fn lookAt(p: *Pardes, id: usize, operand: []const u8) void {
switch (found) {
.none => {
if (pane.image != null or pane.body.mode == .tty) return;
+ if (p.settings.look_word == .search and pane.file != null) return lookWord(p, id, pane, trimmed);
const rows = runSearch(p, id, trimmed, .text, .cursor, false) catch |err| {
p.reportError(id, "search", err);
return;