summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-07-08 05:18:55 -0300
committerGabriel Schneider <[email protected]>2026-08-01 15:02:07 -0300
commit2826704c7f829b5b5375ed2bf7414b455d3b0735 (patch)
tree87d79168d297d1d599a81c82635580d073302111 /src
parent4314f442048c6654b9179633539495836f7fae82 (diff)
downloadpardes-2826704c7f829b5b5375ed2bf7414b455d3b0735.tar.gz
pardes-2826704c7f829b5b5375ed2bf7414b455d3b0735.zip
new panes reject a too-short split parent: if the chosen parent would leave the new pane under 2 body rows, splitParent swaps in a qualifying pane (same column first), else the tallest pane anywhere; applied to Alt-n, look-dir, placeDoc and ttyForDir. New splitparent.snap.
Diffstat (limited to 'src')
-rw-r--r--src/pardes.zig43
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);