diff options
| author | Gabriel Schneider <[email protected]> | 2026-09-29 06:07:10 -0300 |
|---|---|---|
| committer | Gabriel Schneider <[email protected]> | 2026-10-01 00:12:16 -0300 |
| commit | b88e6ddf653b6031b906493807b475395c4ae3c4 (patch) | |
| tree | 3692c1ca35c205ddae9f908a769f999b251f3024 | |
| parent | 98ed98178b667e551ff2bcaeb981e70d1f6ccb1f (diff) | |
| download | pardes-b88e6ddf653b6031b906493807b475395c4ae3c4.tar.gz pardes-b88e6ddf653b6031b906493807b475395c4ae3c4.zip | |
@p<serial>:<address> takes any sam address, as file:<address> does
@p<serial> took a line spot but an address after it (/re/, #n, $, 0/re/,
a range) was dropped, the name failing the file check, and an unknown
serial fell through to a search. The pane is now addressed like a file;
a miss and a serial no pane has each log an err, and look reads back
empty.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
| -rw-r--r-- | docs/fs.md | 5 | ||||
| -rw-r--r-- | src/look.zig | 7 | ||||
| -rw-r--r-- | src/ninep/ctl.zig | 27 |
3 files changed, 36 insertions, 3 deletions
@@ -442,7 +442,10 @@ whose `{` or `a`/`c`/`i` text never ended fails and changes nothing unfinished was cut short. A fragment never runs on its own. A line or Edit block held past 1 MiB is refused (EINVAL). -A look takes acme's addresses after a colon (editors/acme/look.c:450): a +`@p<serial>:<address>` addresses the pane with that serial as `file:<address>` +does a file, with any sam address (`/re/`, `#n`, `$`, `0/re/`, a range); a +miss, and a serial no pane has, each log an `err`, and look reads back +empty. A look takes acme's addresses after a colon (editors/acme/look.c:450): a line written to `look` as `file:/re/`, `file:#n`, `file:$` or any address opens (or finds) the file and selects what the address names. **The address is evaluated from the file's dot**, as acme's is: `file:/re/` diff --git a/src/look.zig b/src/look.zig index 8318973b..6a4fe1d1 100644 --- a/src/look.zig +++ b/src/look.zig @@ -1289,6 +1289,9 @@ fn lookAddress(p: *Pardes, id: usize, path: []const u8, expr: []const u8) void { .pane => |t| if (t.id < MAX_PANES and p.panes[t.id] != null) t.id else null, else => null, }; + // `@p<serial>:<address>`: that pane, or, not open, a miss said as one. + const by_serial = std.mem.startsWith(u8, path, config.pane_addr); + if (by_serial and open == null) return missed(p, id, "no pane {s}", .{path[0..@min(path.len, 32)]}); if (open) |o| target = o else if (path.len > 0) { const before = p.active; lookAt(p, id, path); @@ -1297,8 +1300,8 @@ fn lookAddress(p: *Pardes, id: usize, path: []const u8, expr: []const u8) void { if (target == before and target != id) return; } const pane = p.panes[target] orelse return; - const f = pane.file orelse return; - if (path.len > 0 and (f.output != null or !std.mem.endsWith(u8, f.path, std.fs.path.basename(path)))) return; + const f = pane.file orelse return missed(p, id, "{s} is no text to address", .{path[0..@min(path.len, 64)]}); + 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 }; const r = a.address(ninep_pane.dotOf(pane)) orelse { return missed(p, id, "{s}", .{a.err}); diff --git a/src/ninep/ctl.zig b/src/ninep/ctl.zig index d623296b..bed53473 100644 --- a/src/ninep/ctl.zig +++ b/src/ninep/ctl.zig @@ -1890,3 +1890,30 @@ test "a word written to a raw terminal's look is listed as in normal mode" { const made = p.panes[p.paneBySerial(try std.fmt.parseInt(u32, said, 10)).?].?; try testing.expect(made.file.?.output.?.from == .search); } + +test "@p<serial>:<address> takes any sam address; a miss and an unknown serial are errs" { + const p = try withFile(testing.allocator, "foo x foo y\nbar\n"); + defer p.deinit(); + const serial = serialOf(p); + const root = @intFromEnum(tree.TopFile.look); + const dot = Node.of(serial, .dot); + const Case = struct { addr: []const u8, want: []const u8 }; + for ([_]Case{ + .{ .addr = "0/foo/", .want = " 0 3 " }, + .{ .addr = "/foo/", .want = " 6 9 " }, + .{ .addr = "#12,#15", .want = " 12 15 " }, + .{ .addr = "$", .want = " 16 16 " }, + .{ .addr = "1,2", .want = " 0 16 " }, + }) |c| { + var line: [64]u8 = undefined; + try testing.expectEqual(Status.ok, wr(p, root, try std.fmt.bufPrint(&line, "@p{d}:{s}\n", .{ serial, c.addr })).reply.status); + try testing.expectEqualStrings(c.want, rd(p, dot, 0, 64).bytes); + } + var line: [64]u8 = undefined; + _ = wr(p, root, try std.fmt.bufPrint(&line, "@p{d}:/zzqq/\n", .{serial})); + try testing.expect(th.logHas(p, "look: no match for regexp")); + try testing.expectEqualStrings("", rd(p, root, 0, 64).bytes); + _ = wr(p, root, "@p999:/foo/\n"); + try testing.expect(th.logHas(p, "look: no pane @p999")); + try testing.expectEqualStrings("", rd(p, root, 0, 64).bytes); +} |
