summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
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);