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.zig22
1 files changed, 16 insertions, 6 deletions
diff --git a/src/ninep/tree.zig b/src/ninep/tree.zig
index 5f3ffc9c..17941e10 100644
--- a/src/ninep/tree.zig
+++ b/src/ninep/tree.zig
@@ -605,7 +605,7 @@ fn attrOf(p: *Pardes, target: Target) ?Reply.Attr {
.tag, .exec => 0o666,
},
.size = switch (c.file) {
- .tag => cols.headerText(p, c.serial).?.len + 1,
+ .tag => cols.headerText(p, c.serial).?.len,
.exec => ctl.resultsLen(p),
else => 0,
},
@@ -647,7 +647,7 @@ fn topSize(p: *Pardes, f: TopFile) u64 {
// and /pane/new none until an open has a pane to name.
.root, .pane, .col, .screen, .new => 0,
.layout => cols.layoutLen(p),
- .tag => cols.headerText(p, null).?.len + 1,
+ .tag => cols.headerText(p, null).?.len,
.index => pane.indexLen(p),
.README => fs.help.len,
.status => ctl.statusLen(p),
@@ -935,6 +935,7 @@ fn releaseHandle(p: *Pardes, req: Req) void {
// A truncating write to `tag` is over when its open goes (pane.zig
// writeTag): a newline it held back is dropped.
if (t == .pane and t.pane.file == .tag) if (p.paneBySerial(t.pane.serial)) |id| {
+ pane.applyTagTruncation(p, p.panes[id].?);
p.panes[id].?.fs.tag_rewrite = false;
p.panes[id].?.fs.tag_held_newline = false;
};
@@ -1052,7 +1053,7 @@ fn readFile(p: *Pardes, req: Req, target: Target) Reply {
// A name as /log shows it: one line of UTF-8, a
// newline in it `\n` (events.shown).
var name_buf: [4 * 4096]u8 = undefined;
- const name = events.shown(pane.nameOf(pn), &name_buf);
+ const name = events.shown(pane.nameOf(p, pn), &name_buf);
out.print(p.gpa, "{d} {s} {d} {s} {d}\n", .{ serial, pane.kindOf(pn), @intFromBool(pane.dirtyOf(pn)), name, pane.columnOf(p, id) }) catch {};
}
break :index stagedReply(p, req);
@@ -1146,12 +1147,21 @@ fn holdsLines(p: *Pardes, req: Req) bool {
/// A line held back longer than this is refused rather than kept growing.
const pending_cap = 1 << 20;
+/// The ctl files, whose lines are commands as look's and exec's are.
+fn ctlFile(target: Target) bool {
+ return switch (target) {
+ .top => |f| f == .ctl,
+ .col => |c| c.file == .ctl,
+ .pane => |t| t.file == .ctl,
+ };
+}
+
fn write(p: *Pardes, req: Req, target: Target) Reply {
+ // A command line holds no control character but a tab: the whole write
+ // is refused at once, not held to fail unseen at the close.
+ if (resultsFile(target) or ctlFile(target)) for (req.data) |c| if ((c < ' ' and c != '\t' and c != '\n' and c != '\r') or c == 0x7f) return failText(req.tag, E.INVAL, ctl.e_control);
const o = (if (linesFile(target)) openOf(p, req) else null) orelse return writeNow(p, req, target);
if (o.what != .lines and o.what != .ctl) return writeNow(p, req, target);
- // A clicked line holds no control character: refused at once, not held
- // to fail unseen at the close.
- if (resultsFile(target)) for (req.data) |c| if ((c < ' ' and c != '\t' and c != '\n' and c != '\r') or c == 0x7f) return failText(req.tag, E.INVAL, ctl.e_control);
o.pending.appendSlice(p.gpa, req.data) catch return Reply.fail(req.tag, E.NOMEM);
var end = ctl.completeEnd(p, o.pending.items);
// A tail with no newline is a whole line when the write is the whole of