diff options
| author | Gabriel Schneider <[email protected]> | 2026-09-29 01:45:24 -0300 |
|---|---|---|
| committer | Gabriel Schneider <[email protected]> | 2026-10-01 00:12:15 -0300 |
| commit | eeac8cdf456148f02546f69dc197c6e9dca7876d (patch) | |
| tree | aa3ffac5b2687e2d300c7e8944a45aaeab36c545 /src/look.zig | |
| parent | 8322d6507a854fc41bba42b9e8b8672d33cfe18b (diff) | |
| download | pardes-eeac8cdf456148f02546f69dc197c6e9dca7876d.tar.gz pardes-eeac8cdf456148f02546f69dc197c6e9dca7876d.zip | |
A look's miss repeats the path whole, up to 256 bytes
The miss message clipped what was looked at to 48 bytes, mid-word, and a
path past 160 bytes turned the has-no-line message into a bare no match.
Both now carry up to 256 bytes, cut on a character boundary with an
ellipsis past that.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Diffstat (limited to 'src/look.zig')
| -rw-r--r-- | src/look.zig | 35 |
1 files changed, 28 insertions, 7 deletions
diff --git a/src/look.zig b/src/look.zig index 9dfd912f..5d60e8b3 100644 --- a/src/look.zig +++ b/src/look.zig @@ -1181,14 +1181,32 @@ pub fn followPdfLink(p: *Pardes, id: usize, probe: *const panes.Pdf.WordProbe) v /// A look that found nothing: said on the message row, logged as an `err` /// record, and marked so that /look reads back nothing (ninep/ctl.zig run). +/// The most of a looked-at path or text a miss repeats; past it, cut on a +/// character boundary and ended with `…`. +const miss_path_cap = 256; + +fn missText(text: []const u8, buf: *[miss_path_cap + "…".len]u8) []const u8 { + if (text.len <= miss_path_cap) return text; + var n: usize = miss_path_cap; + while (n > 0 and text[n] & 0xC0 == 0x80) n -= 1; + @memcpy(buf[0..n], text[0..n]); + @memcpy(buf[n..][0.."…".len], "…"); + return buf[0 .. n + "…".len]; +} + +fn missedLine(p: *Pardes, id: usize, path: []const u8, line: anytype) void { + var cut: [miss_path_cap + "…".len]u8 = undefined; + missed(p, id, "{s} has no line {d}", .{ missText(path, &cut), line }); +} + fn missed(p: *Pardes, id: usize, comptime fmt: []const u8, args: anytype) void { p.look_missed = true; - var said: [160]u8 = undefined; + var said: [miss_path_cap + 64]u8 = undefined; const why = std.fmt.bufPrint(&said, fmt, args) catch "no match"; - var msg: [176]u8 = undefined; + var msg: [said.len + 8]u8 = undefined; p.setMessage(id, std.fmt.bufPrint(&msg, "Look: {s}", .{why}) catch "Look: no match"); const serial = if (p.panes[id]) |pane| pane.serial else 0; - var rec: [200]u8 = undefined; + var rec: [said.len + 32]u8 = undefined; pardes.ctlfs.events.notePath(p, "err", std.fmt.bufPrint(&rec, "{d} look: {s}", .{ serial, why }) catch return); } @@ -1201,7 +1219,7 @@ fn settleLine(p: *Pardes, id: usize, path: []const u8, at: Spot, before: usize, if (at.line > panes.File.nlines(p.gpa, f)) { if (opened) |free| p.removePane(free, null) catch {}; if (p.panes[before] != null) p.active = before; - return missed(p, id, "{s} has no line {d}", .{ path, at.line }); + return missedLine(p, id, path, at.line); } if (at.line > 0 and at.col == 0 and at.end_line == 0) { const start = modal.lineStartOffset(f.content, at.line - 1); @@ -1290,7 +1308,7 @@ pub fn lookAt(p: *Pardes, id: usize, operand: []const u8) void { // A line past the end of an open pane is a miss (the target's line is // already clamped, so the one written is asked). if (found == .pane and found.pane.id < MAX_PANES) if (p.panes[found.pane.id]) |shown| if (shown.file) |*f| if (pl.at.line > panes.File.nlines(p.gpa, f)) - return missed(p, id, "{s} has no line {d}", .{ trimmed, pl.at.line }); + return missedLine(p, id, trimmed, pl.at.line); // A miss changes nothing, the selection included; anything else starts // from a clean one. if (found != .none) clearNavigationSelection(p, pane); @@ -1301,7 +1319,10 @@ pub fn lookAt(p: *Pardes, id: usize, operand: []const u8) void { p.reportError(id, "search", err); return; }; - if (rows == 0) return missed(p, id, "no match for \"{s}\"", .{@import("Messages.zig").clip(trimmed, 48)}); + if (rows == 0) { + var cut: [miss_path_cap + "…".len]u8 = undefined; + return missed(p, id, "no match for \"{s}\"", .{missText(trimmed, &cut)}); + } clearNavigationSelection(p, pane); const at = pane.search_row; _ = searchStep(p, id, 1); @@ -1347,7 +1368,7 @@ pub fn lookAt(p: *Pardes, id: usize, operand: []const u8) void { // touches nothing. if (openPaneTarget(p, target.path, target.at)) |open| if (p.panes[open.pane.id].?.file) |*f| if (target.at.line > panes.File.nlines(p.gpa, f)) - return missed(p, id, "{s} has no line {d}", .{ target.path, target.at.line }); + return missedLine(p, id, target.path, target.at.line); // focus an existing pane on this path (rescrolled), else open const before = p.active; var opened: ?usize = null; |
