summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/look.zig26
-rw-r--r--src/ninep/ctl.zig6
2 files changed, 20 insertions, 12 deletions
diff --git a/src/look.zig b/src/look.zig
index afb5b760..454074c8 100644
--- a/src/look.zig
+++ b/src/look.zig
@@ -1218,17 +1218,24 @@ 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 `…`.
+/// The most of a looked-at path or text a miss repeats; past it, its
+/// middle gives up to `…` (the Rerror cutter's rule), so the file's name at
+/// the end stays.
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];
+ return pardes.ctlfs.fitErr(text, buf[0..miss_path_cap]);
+}
+
+test "a miss names a long path by its start and its end, its middle given up to …" {
+ var cut: [miss_path_cap + "…".len]u8 = undefined;
+ const long = "/home/someone/" ++ "deep/" ** 80 ++ "the-file.zig";
+ const said = missText(long, &cut);
+ try std.testing.expect(said.len <= miss_path_cap);
+ try std.testing.expect(std.mem.startsWith(u8, said, "/home/someone/"));
+ try std.testing.expect(std.mem.endsWith(u8, said, "/the-file.zig"));
+ try std.testing.expect(std.mem.indexOf(u8, said, "…") != null);
+ try std.testing.expectEqualStrings("short/path.txt", missText("short/path.txt", &cut));
}
fn missedLine(p: *Pardes, id: usize, path: []const u8, line: anytype) void {
@@ -1402,7 +1409,8 @@ fn lookAddress(p: *Pardes, id: usize, path: []const u8, expr: []const u8) void {
const pane = p.panes[target] orelse return;
const f = pane.file orelse {
if (by_serial and pane.isTerminal()) return lookTerminalAddress(p, id, target, expr);
- return missed(p, id, "{s} is no text to address", .{path[0..@min(path.len, 64)]});
+ var cut: [miss_path_cap + "…".len]u8 = undefined;
+ return missed(p, id, "{s} is no text to address", .{missText(path, &cut)});
};
if (!by_serial and path.len > 0 and (f.output != null or !std.mem.endsWith(u8, f.path, std.fs.path.basename(path)))) return;
var a: Addr = .{ .text = f.content, .lim = null, .expr = expr };
diff --git a/src/ninep/ctl.zig b/src/ninep/ctl.zig
index 4fab699a..27361124 100644
--- a/src/ninep/ctl.zig
+++ b/src/ninep/ctl.zig
@@ -1449,7 +1449,7 @@ test "the root look's file:/re/ goes on from the dot, and a miss leaves the dot
try testing.expectEqualStrings(" 0 3 ", rd(p, dot, 0, 64).bytes);
}
-test "a look's miss repeats the path whole up to 256 bytes, then cuts it with an ellipsis" {
+test "a look's miss repeats the path whole up to 256 bytes, then gives up its middle to an ellipsis" {
const gpa = testing.allocator;
const p = try withFile(gpa, "x\n");
defer p.deinit();
@@ -1458,9 +1458,9 @@ test "a look's miss repeats the path whole up to 256 bytes, then cuts it with an
var line: [512]u8 = undefined;
_ = wr(p, root, try std.fmt.bufPrint(&line, "{s}\n", .{long}));
try testing.expect(th.logHas(p, try std.fmt.bufPrint(&line, "look: no match for \"{s}\"\n", .{long})));
- const huge = "é" ** 150; // 300 bytes: cut at 256, between characters
+ const huge = "é" ** 150; // 300 bytes: its middle cut to fit 256, between characters
_ = wr(p, root, huge ++ "\n");
- try testing.expect(th.logHas(p, "look: no match for \"" ++ "é" ** 128 ++ "…\"\n"));
+ try testing.expect(th.logHas(p, "look: no match for \"" ++ "é" ** 63 ++ "…" ++ "é" ** 63 ++ "\"\n"));
}
test "exec runs a builtin at the pane and records the pane it acted on" {