diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/pardes.zig | 43 |
1 files changed, 35 insertions, 8 deletions
diff --git a/src/pardes.zig b/src/pardes.zig index c14154e5..0219d474 100644 --- a/src/pardes.zig +++ b/src/pardes.zig @@ -1203,9 +1203,10 @@ pub const Pardes = struct { const free = p.freeSlot() orelse return; const nt = p.newShell(free, "") catch return; nt.greet = true; - const f = p.layoutFindTerm(p.active).?; + const src = p.splitParent(p.active); + const f = p.layoutFindTerm(src).?; p.layoutInsert(f.col, f.idx + 1, free); - p.splitBelow(p.active, nt); + p.splitBelow(src, nt); p.active = free; return; } @@ -3973,6 +3974,26 @@ pub const Pardes = struct { if (p.panes[sib]) |s| s.vweight += @as(f32, @floatFromInt(@max(1, p.rects[id].h))); } + /// The parent a new pane splits from must be tall enough that splitBelow + /// leaves the NEW pane at least 2 body rows (the parent keeps tag+1 row, + /// the new pane needs tag+2). A too-short choice is swapped for a + /// qualifying pane (same column first, keeping the split local), else the + /// tallest pane anywhere. + fn splitParent(p: *Pardes, want: usize) usize { + const need = 2 * BOX_H + 3; + if (p.rects[want].h >= need) return want; + if (p.layoutFindTerm(want)) |f| for (0..p.col_n[f.col]) |k| { + if (p.rects[p.col_terms[f.col][k]].h >= need) return p.col_terms[f.col][k]; + }; + var tallest = want; + for (0..p.ncol) |c| for (0..p.col_n[c]) |k| { + const pid = p.col_terms[c][k]; + if (p.rects[pid].h >= need) return pid; + if (p.rects[pid].h > p.rects[tallest].h) tallest = pid; + }; + return tallest; + } + /// Open a window BELOW `src` (acme-style) without rebalancing the column: /// shrink ONLY src to its content height (cursor row kept visible) and hand /// the freed rows to `nw` — together they fill src's old slot and the other @@ -4039,8 +4060,12 @@ pub const Pardes = struct { const nt = p.newShell(free, dir) catch return null; nt.greet = false; const rc = if (p.ncol > 0) p.ncol - 1 else 0; - if (p.col_n[rc] > 0) p.splitBelow(p.col_terms[rc][p.col_n[rc] - 1], nt); - p.layoutInsert(rc, p.col_n[rc], free); + if (p.col_n[rc] > 0) { + const src = p.splitParent(p.col_terms[rc][p.col_n[rc] - 1]); + const f = p.layoutFindTerm(src).?; + p.splitBelow(src, nt); + p.layoutInsert(f.col, f.idx + 1, free); + } else p.layoutInsert(rc, p.col_n[rc], free); return free; } @@ -4225,9 +4250,10 @@ pub const Pardes = struct { const free = p.freeSlot() orelse return; const nt = p.newShell(free, dir) catch return; nt.greet = true; - const f = p.layoutFindTerm(id).?; + const src = p.splitParent(id); + const f = p.layoutFindTerm(src).?; p.layoutInsert(f.col, f.idx + 1, free); - p.splitBelow(id, nt); + p.splitBelow(src, nt); p.active = free; }, .file => |target| { @@ -4359,9 +4385,10 @@ pub const Pardes = struct { }; }; if (src_id) |sid| { - const sf = p.layoutFindTerm(sid).?; + const src = p.splitParent(sid); + const sf = p.layoutFindTerm(src).?; p.layoutInsert(sf.col, sf.idx + 1, free); - p.splitBelow(sid, nt); + p.splitBelow(src, nt); p.active = free; } else { p.stackDocLeft(free, nt); |
