diff options
| author | Gabriel Schneider <[email protected]> | 2026-09-29 06:10:43 -0300 |
|---|---|---|
| committer | Gabriel Schneider <[email protected]> | 2026-10-01 00:12:16 -0300 |
| commit | 4dc55f7e3ae8232e6994b92e6b1948bd8c190baf (patch) | |
| tree | 9f3b89287316eb25c8eff92013ccbd76a66ed919 | |
| parent | b88e6ddf653b6031b906493807b475395c4ae3c4 (diff) | |
| download | pardes-4dc55f7e3ae8232e6994b92e6b1948bd8c190baf.tar.gz pardes-4dc55f7e3ae8232e6994b92e6b1948bd8c190baf.zip | |
A new pane with no room under the last goes last all the same
A pane from pane/new or New takes the bottom half of its column's last
pane, as acme's coladd does (cols.c:62-65); when that pane is too short
to give it a tag and 2 rows, the fallback halved the tallest pane and
put the new one under it, mid-column (the 7 9 8 found). It now goes last
all the same, with half the tallest pane's rows (its tag measured at the
column's width). Tty from a pane's ctl already follows acme's
makenewwindow (the active column first, util.c:456-467); fs.md now says
so rather than beside that pane.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
| -rw-r--r-- | docs/fs.md | 9 | ||||
| -rw-r--r-- | src/layout.zig | 16 | ||||
| -rw-r--r-- | src/ninep/tree.zig | 10 |
3 files changed, 29 insertions, 6 deletions
@@ -124,7 +124,9 @@ Existing Plan9port/v9fs clients need a userspace bridge for QUIC. /col/<n>/ctl write Delcol, Joincol, New or Tty: each acts on that column, as from its tag /col/<n>/exec write a word: a middle click on it in that column's tag; read as /exec; rmdir col/<n> closes an empty column (a column with panes is refused, ENOTEMPTY) -/pane/new open it to make a pane; the read answers that pane's serial. A session holds +/pane/new open it to make a pane (the bottom half of the active column's last + pane, acme's coladd; with no room there, last all the same, taking half + the tallest pane's rows); the read answers that pane's serial. A session holds 64 panes (16 on the board); at that, every route that would open one -- this open, look, exec, New, Tty -- fails with `no space for a pane: 64 max` (ENOSPC through 9ns, which has no word for ENFILE) and an err @@ -327,7 +329,10 @@ same tree without leaving the process. `src/builtins.zig` (`Save`, `Del`, `New`, `Newcol`, `Mount NAME DIAL`, `Unmount NAME`, `Dump`, `Restore`, `Msg TEXT`, `Find`, `Grep`, `Tty`, ...; `Tty`'s argument is the shell it runs, `Tty fish`, and `Tty` on a pane's - ctl opens a new terminal pane beside that one, not in it), + ctl opens a new terminal pane, not in that one: in the active column, as + acme's makenewwindow puts a new window (util.c:456-467: the active column + first, then the pane's own), under the text with room or halving the + tallest, never shorter than its tag and 2 rows), or anything else, a command line. Written at a terminal at its prompt it is typed into that shell (and a terminal whose shell exits, `exit` typed or run, closes its pane). From anywhere else -- a file, a scratch, a tag, diff --git a/src/layout.zig b/src/layout.zig index bdef9675..644054ed 100644 --- a/src/layout.zig +++ b/src/layout.zig @@ -447,8 +447,9 @@ pub fn everyPaneRoomy(p: *Pardes) bool { return true; } -/// Places `id` in column `c` by halving its tallest unfolded pane, when -/// that leaves both their rows; false, and `id` in no column, when not. +/// Places `id` last in column `c`, where acme's coladd puts a new window, +/// with half the rows of the column's tallest unfolded pane, when that +/// leaves both their rows; false, and `id` in no column, when not. pub fn splitTallest(p: *Pardes, c: usize, id: usize) bool { compute(p); var tall: ?usize = null; @@ -457,8 +458,15 @@ pub fn splitTallest(p: *Pardes, c: usize, id: usize) bool { if (tall == null or p.rects[k].h > p.rects[tall.?].h) tall = k; } const v = tall orelse return false; - if (p.rects[v].h < minRows(p, v) + minRows(p, id)) return false; - splitAt(p, c, id, p.rects[v].y + p.rects[v].h / 2); + const h = p.rects[v].h; + // Its tag wraps at the column's width: measured there, not at none. + p.rects[id].w = p.col_w[c]; + if (h < minRows(p, v) + minRows(p, id)) return false; + snapColWeights(p, c); + insert(p, c, p.col_n[c], id); + const given = std.math.clamp(h / 2, minRows(p, id), h - minRows(p, v)); + p.panes[v].?.vweight = @floatFromInt(h - given); + p.panes[id].?.vweight = @floatFromInt(given); return true; } diff --git a/src/ninep/tree.zig b/src/ninep/tree.zig index 27091112..af1c589d 100644 --- a/src/ninep/tree.zig +++ b/src/ninep/tree.zig @@ -1560,3 +1560,13 @@ test "an a, c or i text cut short through exec is an err in the log, not a msg" try testing.expect(!th.logHas(p, "msg 1 Edit: a, c or i")); try testing.expectEqualStrings("abc\n", p.panes[0].?.file.?.content); } + +test "a pane made from pane/new goes last in its column, even when the last pane has no room to halve" { + const p = try th.withFile(testing.allocator, "x\n"); + defer p.deinit(); + for (0..3) |_| { + const made = call(p, .{ .tag = 1, .op = .open, .node = @intFromEnum(TopFile.new) }).reply.handle; + p.sync(); + try testing.expectEqual(made, p.panes[p.col_panes[0][p.col_n[0] - 1]].?.serial); + } +} |
