summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/exec.zig29
-rw-r--r--src/ninep/ctl.zig13
-rw-r--r--src/ninep/pane.zig6
3 files changed, 45 insertions, 3 deletions
diff --git a/src/exec.zig b/src/exec.zig
index 0a7e71f9..bb4309a4 100644
--- a/src/exec.zig
+++ b/src/exec.zig
@@ -851,9 +851,32 @@ pub fn placeNew(p: *Pardes, from: usize, origin: ?usize, id: usize, kind: NewPan
layout.snapColWeights(p, f.col);
if (!layout.splitTallest(p, f.col, id) or !layout.placedRoomy(p, id, &before)) {
if (layout.findPane(p, id) == null) layout.insert(p, f.col, p.col_n[f.col], id);
- p.unplaced.set(id);
- p.reportError(from, "placement", error.NoPaneRoom);
- return;
+ // +Errors goes wherever there is room, last column first; with
+ // none, its maker says the text some other way (appendErrors).
+ if (kind == .errors) {
+ layout.removePane(p, id);
+ var c = p.ncol;
+ while (c > 0) {
+ c -= 1;
+ if (c == f.col) continue;
+ for (p.col_panes[c][0..p.col_n[c]]) |k| p.rects[k] = before[k];
+ layout.snapColWeights(p, c);
+ if (p.col_n[c] == 0) {
+ layout.insert(p, c, 0, id);
+ break;
+ }
+ if (layout.splitTallest(p, c, id) and layout.placedRoomy(p, id, &before)) break;
+ if (layout.findPane(p, id) != null) layout.removePane(p, id);
+ } else {
+ layout.insert(p, f.col, p.col_n[f.col], id);
+ p.unplaced.set(id);
+ return;
+ }
+ } else {
+ p.unplaced.set(id);
+ p.reportError(from, "placement", error.NoPaneRoom);
+ return;
+ }
}
};
if (kind == .command) return;
diff --git a/src/ninep/ctl.zig b/src/ninep/ctl.zig
index 25abd9b5..378dd844 100644
--- a/src/ninep/ctl.zig
+++ b/src/ninep/ctl.zig
@@ -1447,3 +1447,16 @@ test "an exec line over the command limit fails the write and says the limit; a
try testing.expect(th.logHas(p, "a command line is at most 1024 bytes"));
try testing.expectEqual(Status.ok, wr(p, root_exec, "Msg " ++ "z" ** 1100 ++ "\n").reply.status);
}
+
+test "Edit's p and = never fail for want of room for +Errors: the text is logged instead" {
+ const p = try withFile(testing.allocator, "one\ntwo\n");
+ defer p.deinit();
+ p.update(.{ .resize = .{ .cols = 80, .rows = 6 } });
+ const ctl_node = Node.of(serialOf(p), .ctl);
+ try testing.expectEqual(Status.ok, wr(p, ctl_node, "Edit ,p\n").reply.status);
+ try testing.expect(th.logHas(p, " one\n") and th.logHas(p, " two\n"));
+ p.sync();
+ var count: usize = 0;
+ for (p.panes) |slot| count += @intFromBool(slot != null);
+ try testing.expectEqual(@as(usize, 1), count); // the +Errors that had no room is gone
+}
diff --git a/src/ninep/pane.zig b/src/ninep/pane.zig
index 3307eb47..791cb797 100644
--- a/src/ninep/pane.zig
+++ b/src/ninep/pane.zig
@@ -649,6 +649,12 @@ pub fn appendErrors(p: *Pardes, id: usize, text: []const u8) ?usize {
return null;
};
exec.placeNew(p, id, id, free, .errors);
+ // No column had room for it (it closes at the step's end): the text is
+ // logged instead, a msg a line, so it is not lost and nothing fails.
+ if (p.unplaced.isSet(free)) {
+ var lines = std.mem.splitScalar(u8, std.mem.trimEnd(u8, text, "\n"), '\n');
+ while (lines.next()) |line| events.noteMessage(p, pane.serial, line[0..@min(line.len, pardes.Messages.LoggedMessage.cap)]);
+ }
return text.len;
}