diff options
Diffstat (limited to 'src/ninep/tree.zig')
| -rw-r--r-- | src/ninep/tree.zig | 18 |
1 files changed, 12 insertions, 6 deletions
diff --git a/src/ninep/tree.zig b/src/ninep/tree.zig index 4b52be51..66f73e9c 100644 --- a/src/ninep/tree.zig +++ b/src/ninep/tree.zig @@ -131,6 +131,9 @@ pub const Open = struct { /// An open of a file that takes lines of commands (look, exec, a /// ctl, tagexec): its `pending` and `results`. lines, + /// An open writing a file pane's body, data or xdata: its writes are + /// one undo step (pane.zig `joined_by`), another open's its own. + writes, } = .{ .snapshot = null }, /// What a write to a file of command lines left unfinished: a last line /// with no newline yet, or an Edit block still open. A write through a @@ -180,7 +183,7 @@ pub const Open = struct { gpa.free(run.output); gpa.free(run.line); }, - .event, .pty_data, .ctl, .lines => {}, + .event, .pty_data, .ctl, .lines, .writes => {}, } o.pending.deinit(gpa); if (o.replay) |r| gpa.free(r.bytes); @@ -752,7 +755,8 @@ fn open(p: *Pardes, req: Req, target: Target) Reply { pane_of = pn; const reader = req.omode & 3 != 1; // OWRITE is the one mode that never reads break :what switch (t.file) { - .body => if (pn.isTerminal()) .{ .snapshot = null } else return .{ .tag = req.tag }, + .body => if (pn.isTerminal()) .{ .snapshot = null } else if (req.omode & 3 == 0) return .{ .tag = req.tag } else .writes, + .data, .xdata => if (req.omode & 3 != 0) .writes else return .{ .tag = req.tag }, // Reads of these consume, so two readers would each see half // the stream; the second is refused rather than robbed. .event => if (reader and pn.fs.event_reader) return failText(req.tag, E.BUSY, e_in_use) else .{ .event = reader }, @@ -794,7 +798,7 @@ fn open(p: *Pardes, req: Req, target: Target) Reply { pn.fs.event_reader = pn.fs.event_reader or reader; }, .pty_data => pane_of.?.fs.pty_reader = true, - .run, .ctl, .lines => {}, + .run, .ctl, .lines, .writes => {}, } return .{ .tag = req.tag, .handle = @intCast(i + 1) }; } @@ -831,9 +835,11 @@ fn releaseHandle(p: *Pardes, req: Req) void { p.panes[id].?.fs.tag_rewrite = false; p.panes[id].?.fs.tag_held_newline = false; }; - // The writes of one open are one undo step (pane.zig `joined`). + // The writes of one open are one undo step (pane.zig `joined`): its + // close ends that step. if (t == .pane and (t.pane.file == .body or t.pane.file == .data or t.pane.file == .xdata)) if (p.paneBySerial(t.pane.serial)) |id| { - p.panes[id].?.fs.joined = null; + const pf = &p.panes[id].?.fs; + if (pf.joined_by == 0 or pf.joined_by == req.handle) pf.joined = null; }; // `: > limit` clears it for good once its open goes. if (t == .pane and t.pane.file == .limit) if (p.paneBySerial(t.pane.serial)) |id| { @@ -871,7 +877,7 @@ fn releaseHandle(p: *Pardes, req: Req) void { .ctl => if (pn.fs.lock == req.handle) { pn.fs.lock = null; }, - .snapshot, .log, .lines => {}, + .snapshot, .log, .lines, .writes => {}, }; o.deinit(p.gpa); } |
