diff options
| author | Gabriel Schneider <[email protected]> | 2026-09-30 19:30:33 -0300 |
|---|---|---|
| committer | Gabriel Schneider <[email protected]> | 2026-10-01 00:12:17 -0300 |
| commit | b2886edda1a1630f38732975c04bdf4d6f6ded29 (patch) | |
| tree | bf9d63ebb5a1f08fe6b11f5b96a8388945e71b66 /src/ninep/pane.zig | |
| parent | 42b68e5ea63c32ff9359f2268ef0d8c08eaafff2 (diff) | |
| download | pardes-b2886edda1a1630f38732975c04bdf4d6f6ded29.tar.gz pardes-b2886edda1a1630f38732975c04bdf4d6f6ded29.zip | |
A refused write to dot after a shell's truncation changes nothing: the truncation waits for the write, as limit's does
echo /nomatch/ > dot truncated dot to an empty range at the top before
the write was refused, so a failed address still moved the selection
and scrolled. The truncation is now held until the write that follows
it: that write sets dot, or, refused, leaves it as it was. A truncation
with no write after it (: > dot) empties it when its open goes.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Diffstat (limited to 'src/ninep/pane.zig')
| -rw-r--r-- | src/ninep/pane.zig | 14 |
1 files changed, 12 insertions, 2 deletions
diff --git a/src/ninep/pane.zig b/src/ninep/pane.zig index 78bec09f..71484538 100644 --- a/src/ninep/pane.zig +++ b/src/ninep/pane.zig @@ -44,6 +44,10 @@ pub const State = struct { /// The limit a truncation cleared, kept until the write that follows it /// on that open (a shell's `>`): a write that fails puts it back. limit_truncated: ?Range = null, + /// `dot` was truncated and nothing written since: the write that + /// follows sets it or, refused, leaves it as it was; with none, the + /// open's release empties it (tree.zig releaseHandle). + dot_truncated: bool = false, /// Opens of `event`, which hold the pane scripted. readers: u16 = 0, /// One of `readers` reads `event`; a second reading open is refused. @@ -800,9 +804,11 @@ fn writeRange(req: Req, pane: *Pane, file: PaneFile) Reply { pf.limit = kept; pf.limit_truncated = null; }; + if (file == .dot) pf.dot_truncated = false; return tree.failText(req.tag, E.INVAL, a.err); }; if (file == .limit) pf.limit_truncated = null; + if (file == .dot) pf.dot_truncated = false; switch (file) { .addr => { pf.addr = range; @@ -1000,7 +1006,7 @@ pub fn truncate(p: *Pardes, pane: *Pane, file: PaneFile) tree.Status { pf.limit_truncated = pf.limit; pf.limit = null; }, - .dot => if (fileOf(pane) != null) setDot(pane, .{}), + .dot => pf.dot_truncated = fileOf(pane) != null, else => {}, } return .ok; @@ -1211,8 +1217,12 @@ test "sel reads the selection and writing sel replaces it" { try testing.expectEqual(@as(u32, 0), p.panes[0].?.fs.addr.q0); try testing.expectEqual(@as(u32, 3), p.panes[0].?.fs.addr.q1); - // A truncation empties dot; an address expression addresses it. + // A truncation empties dot once its open goes, nothing written after + // it; an address expression addresses it. + const h = call(p, .{ .tag = 8, .op = .open, .node = dot, .omode = 1 }).reply.handle; _ = call(p, .{ .tag = 9, .op = .setattr, .node = dot, .truncate = true }); + try testing.expectEqualStrings("one", rd(p, sel, 0, 100).bytes); + _ = call(p, .{ .tag = 10, .op = .release, .node = dot, .handle = h, .opened = true }); try testing.expectEqualStrings("", rd(p, sel, 0, 100).bytes); try testing.expectEqual(Status.ok, wr(p, dot, "#0,#3").reply.status); |
