From 24dbdf73f92cd0a4b5ba130abe182cbcf9b3e472 Mon Sep 17 00:00:00 2001 From: Gabriel Schneider Date: Thu, 1 Oct 2026 06:47:48 -0300 Subject: `@pN:` looks at pane N, its trailing colon dropped as any look's is, and a line past the end is said one way: `:N has no line N`, for `:N` as for `file:N` lookAt dropped a trailing `:` from what it read but resolved the target from the text as written, so `@p33:` was `no match for "@p33:"`. And `:99999` said `address out of range` while `file:99999` said `has no line 99999`: a bare line number past the end now says the latter too. Co-Authored-By: Claude Opus 5.5 --- src/ninep/ctl.zig | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'src/ninep/ctl.zig') diff --git a/src/ninep/ctl.zig b/src/ninep/ctl.zig index 1bf916a9..70ed51a7 100644 --- a/src/ninep/ctl.zig +++ b/src/ninep/ctl.zig @@ -4149,3 +4149,19 @@ test "Edit on an image pane is refused as a data write there is, EINVAL, before try testing.expectEqualStrings(data.reply.ename, edit.reply.ename); try testing.expectEqual(E.INVAL, wr(p, Node.of(doc.serial, .name), "/tmp/other.ppm\n").errno()); } + +test "`@pN:` looks at pane N as `a.txt:` looks at a.txt, and a line past the end is said one way, `:N` or `file:N`" { + const p = try withFile(testing.allocator, "one\ntwo\n"); + defer p.deinit(); + const s = serialOf(p); + var buf: [64]u8 = undefined; + p.look_missed = false; + pardes.look.lookAt(p, 0, try std.fmt.bufPrint(&buf, "@p{d}:", .{s})); + try testing.expect(!p.look_missed); + const f = pane_files.fileOf(p.panes[0].?).?; + for ([_][]const u8{ ":99999", try std.fmt.bufPrint(&buf, "{s}:99999", .{f.path}) }) |looked| { + pardes.look.lookAt(p, 0, looked); + const said = p.panes[0].?.msg[0..p.panes[0].?.msg_len]; + try testing.expect(std.mem.endsWith(u8, said, "/test.txt:99999 has no line 99999")); + } +} -- cgit v1.3