summaryrefslogtreecommitdiff
path: root/src/ninep/tree.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/ninep/tree.zig')
-rw-r--r--src/ninep/tree.zig18
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);
}