summaryrefslogtreecommitdiff
path: root/src/layout.zig
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-09-30 13:30:40 -0300
committerGabriel Schneider <[email protected]>2026-10-01 00:12:17 -0300
commit23d7f949b8595ed42e938a28b0d433d90853b341 (patch)
tree73b8b8b0ef981b513de05024ad0756ac4fb2c375 /src/layout.zig
parent92ef244c8a24583896feb47c8c48ec40aa04ebb9 (diff)
downloadpardes-23d7f949b8595ed42e938a28b0d433d90853b341.tar.gz
pardes-23d7f949b8595ed42e938a28b0d433d90853b341.zip
A Newcol refused because the panes' tags would not fit logs its err alone and spends no column serial
Newcol tries its column before keeping it: the new column is inserted, the panes' rows are shared out again, and where a pane would be left under its tag and two rows the column is taken back. The trial showed. insertColumn logged `newcol N` and the take-back `delcol N`, so a follower saw a column come and go around the err. Laying the column out also gave it a serial, so the next column made skipped one. The trial is now unannounced, since insert and drop have unlogged forms. A refusal puts the serial counter back where it was, after first giving every existing column its serial so the trial's is the only one spent. Only a column that stays is logged, and it gets the next serial. Co-Authored-By: Claude Opus 5.5 <[email protected]>
Diffstat (limited to 'src/layout.zig')
-rw-r--r--src/layout.zig20
1 files changed, 16 insertions, 4 deletions
diff --git a/src/layout.zig b/src/layout.zig
index 28f3d270..4aebcf28 100644
--- a/src/layout.zig
+++ b/src/layout.zig
@@ -325,8 +325,14 @@ pub fn removePane(p: *Pardes, id: usize) void {
/// Close column `c` once its panes are gone, its width to the one left of
/// it (the first column's to its right), as acme's rowclose gives it.
pub fn dropColumn(p: *Pardes, c: usize) void {
- std.debug.assert(p.col_n[c] == 0);
const serial = columnSerial(p, c);
+ dropColumnUnannounced(p, c);
+ noteColumn(p, "delcol", serial);
+}
+
+/// dropColumn with no `delcol`, for a column never announced.
+pub fn dropColumnUnannounced(p: *Pardes, c: usize) void {
+ std.debug.assert(p.col_n[c] == 0);
tagline.exitHeader(p);
if (p.ncol > 1) p.col_weight[if (c > 0) c - 1 else c + 1] +|= p.col_weight[c];
p.col_tags[c].deinit(p.gpa);
@@ -341,12 +347,11 @@ pub fn dropColumn(p: *Pardes, c: usize) void {
p.ncol -= 1;
p.col_tags[p.ncol] = .{ .what = .column, .gpa = p.gpa };
p.col_serial[p.ncol] = 0;
- noteColumn(p, "delcol", serial);
}
/// `newcol <serial>` or `delcol <serial>` in the log: the column's serial,
/// as /layout and /col name it.
-fn noteColumn(p: *Pardes, what: []const u8, serial: u32) void {
+pub fn noteColumn(p: *Pardes, what: []const u8, serial: u32) void {
var buf: [16]u8 = undefined;
pardes.ctlfs.events.notePath(p, what, std.fmt.bufPrint(&buf, "{d}", .{serial}) catch return);
}
@@ -649,6 +654,14 @@ pub fn firstColumn(p: *Pardes) ?usize {
}
pub fn insertColumn(p: *Pardes, col: usize, before: bool) ?usize {
+ const c = insertColumnUnannounced(p, col, before) orelse return null;
+ noteColumn(p, "newcol", columnSerial(p, c));
+ return c;
+}
+
+/// insertColumn with no serial given and no `newcol`: a column that may
+/// yet be taken back (Newcol's trial), which then leaves no trace.
+pub fn insertColumnUnannounced(p: *Pardes, col: usize, before: bool) ?usize {
if (!canSplitCol(p, col)) return null;
var old_weight = p.col_weight[col];
if (old_weight < 2 or old_weight % 2 != 0) {
@@ -672,7 +685,6 @@ pub fn insertColumn(p: *Pardes, col: usize, before: bool) ?usize {
p.col_serial[c] = 0;
p.col_n[c] = 0;
p.ncol += 1;
- noteColumn(p, "newcol", columnSerial(p, c));
return c;
}