diff options
| author | Gabriel Schneider <[email protected]> | 2026-09-28 19:59:47 -0300 |
|---|---|---|
| committer | Gabriel Schneider <[email protected]> | 2026-10-01 00:12:15 -0300 |
| commit | 1f8de151e382755c1ce597f166ea4552e7f7e8d1 (patch) | |
| tree | 1ed05b6c528dd9db099a249504fdc3b4083fb72f /src/ninep | |
| parent | 16fe974c7426925f1b7ffc516f149cc1f4ffa390 (diff) | |
| download | pardes-1f8de151e382755c1ce597f166ea4552e7f7e8d1.tar.gz pardes-1f8de151e382755c1ce597f166ea4552e7f7e8d1.zip | |
A look with a blank in its pattern addresses, file:N selects the line, and a miss is said, logged and reads back empty
Round 6: look calc.py:/return a/ was a word search, since a blank ended the address; calc.py:99 past the end focused the file and said nothing; and /look still read back the pane before a miss. A pattern after the colon may now hold blanks; file:N selects the line, newline included, as acme's does; a line past the end opens and focuses nothing; and every miss (no match, a bad address, a line past the end) says so, logs err <serial> look: why, keeps the selection, and leaves look reading back empty. Documented, with file:0/re/ for the first match, since acme evaluates the address from the file's dot. Five goldens change: a look at file:N now selects the line.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Diffstat (limited to 'src/ninep')
| -rw-r--r-- | src/ninep/ctl.zig | 15 |
1 files changed, 15 insertions, 0 deletions
diff --git a/src/ninep/ctl.zig b/src/ninep/ctl.zig index b11692e0..edf81cd9 100644 --- a/src/ninep/ctl.zig +++ b/src/ninep/ctl.zig @@ -69,10 +69,13 @@ fn run(p: *Pardes, id: usize, exec: bool, text: []const u8) void { const before = Serials.snapshot(p); // An exec answers the pane it went to: a command pane it reused, or // the terminal it typed into. + p.look_missed = false; const went: ?usize = if (exec) pardes.exec.execute(p, id, text) else blk: { look.lookAt(p, id, text); break :blk null; }; + // A look that found nothing answers nothing, not the pane before it. + if (!exec and p.look_missed) return; const after = Serials.snapshot(p); var created = false; for (after.list[0..after.len]) |serial| if (std.mem.indexOfScalar(u32, before.list[0..before.len], serial) == null) { @@ -892,6 +895,18 @@ test "a look takes acme's :addr and file:addr, and a miss changes nothing" { try testing.expectEqual(Status.ok, wr(p, look_node, "foo\n").reply.status); var own: [16]u8 = undefined; try testing.expectEqualStrings(try std.fmt.bufPrint(&own, "{d}\n", .{serial}), rd(p, look_node, 0, 64).bytes); + // A pattern with a blank in it; 0/re/ searches from the top, whatever dot is. + try testing.expectEqual(Status.ok, wr(p, look_node, ":/foo y/\n").reply.status); + try testing.expectEqualStrings(" 6 11 ", rd(p, dot, 0, 64).bytes); + try testing.expectEqual(Status.ok, wr(p, look_node, try std.fmt.bufPrint(&line, "{s}:0/foo/\n", .{path})).reply.status); + try testing.expectEqualStrings(" 0 3 ", rd(p, dot, 0, 64).bytes); + // file:N selects the line; a line past the end moves nothing and reads back empty. + try testing.expectEqual(Status.ok, wr(p, look_node, try std.fmt.bufPrint(&line, "{s}:2\n", .{path})).reply.status); + try testing.expectEqualStrings(" 12 16 ", rd(p, dot, 0, 64).bytes); + try testing.expectEqual(Status.ok, wr(p, look_node, try std.fmt.bufPrint(&line, "{s}:99\n", .{path})).reply.status); + try testing.expectEqualStrings(" 12 16 ", rd(p, dot, 0, 64).bytes); + try testing.expectEqualStrings("", rd(p, look_node, 0, 64).bytes); + try testing.expectStringStartsWith(p.panes[0].?.msg[0..p.panes[0].?.msg_len], "Look: "); } test "exec runs a builtin at the pane and records the pane it acted on" { |
