diff options
| author | Gabriel Schneider <[email protected]> | 2026-09-24 10:06:08 -0300 |
|---|---|---|
| committer | Gabriel Schneider <[email protected]> | 2026-10-01 00:12:14 -0300 |
| commit | 3f6ad1bc30570348297ae4aa6d1fd676de229a09 (patch) | |
| tree | b52037635072e90e0ff20c80a15c5d18c578d445 /src/layout.zig | |
| parent | 82c4f9e7212f569d6343dd03ddbab3520a784993 (diff) | |
| download | pardes-3f6ad1bc30570348297ae4aa6d1fd676de229a09.tar.gz pardes-3f6ad1bc30570348297ae4aa6d1fd676de229a09.zip | |
Ask from the keyboard which neighbour a closed pane's rows go to
Del takes a side: `Del k` gives the closed pane's rows to the nearest
expanded pane above it, `Del j` to the one below, each falling back to the
other side when it has none. DelAbove and DelBelow are those two lines, with
no path of their own under SPC.
A bare Del started from a key -- SPC d, Enter on the tag word, a row run from
an output buffer -- on a pane with expanded panes both above and below asks
instead of guessing. The question is a prompt like Save's or a search's
(Pane.Prompt.del_side), so it is painted on the pane's notice band by the
same path, and the next key answers it before any mode sees it: k or Up,
j or Down, anything else keeps the pane, as does a click. Only a key press
sets Pardes.can_ask, so a click, a 9P ctl or event write, a startup line, a
restore and a shell exiting all close the pane at once, the rows going
where layout.absorbVWeight has always sent them. A collapsed pane is not
asked about (it has only a tag row to give), and collapsed neighbours are
passed over (layout.expandedNeighbor, which Collapse now uses too).
removePane and absorbVWeight take the recipient; every other caller passes
null. Three scripts that closed a middle pane with SPC d answer k, which
is where the rows went before, and their goldens are unchanged. delask.snap
covers the question, Esc, j, a clicked DelBelow and a clicked Del.
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
Diffstat (limited to 'src/layout.zig')
| -rw-r--r-- | src/layout.zig | 29 |
1 files changed, 17 insertions, 12 deletions
diff --git a/src/layout.zig b/src/layout.zig index 3637f30e..116a64b8 100644 --- a/src/layout.zig +++ b/src/layout.zig @@ -995,7 +995,7 @@ pub fn splitColumn(p: *Pardes, source_id: usize, id: usize, before: bool) bool { if (needs_rebase) old_weight *= 2; if (id == source_id) { if (p.col_n[source_col] <= 1) return false; - absorbVWeight(p, id); + absorbVWeight(p, id, null); removePane(p, id); } else if (findPane(p, id) != null) return false; @@ -1033,13 +1033,16 @@ pub fn snapColWeights(p: *Pardes, c: usize) void { } } -pub fn absorbVWeight(p: *Pardes, id: usize) void { +/// Hand a closing pane's rows to `to`. With none named they go up: past any +/// results listing to the nearest pane above that is not one, or to the +/// pane below when the closing one is first in its column. +pub fn absorbVWeight(p: *Pardes, id: usize, to: ?usize) void { const f = findPane(p, id) orelse return; if (p.col_n[f.col] <= 1) return; snapColWeights(p, f.col); - var sib = if (f.idx > 0) p.col_panes[f.col][f.idx - 1] else p.col_panes[f.col][f.idx + 1]; + var sib = to orelse if (f.idx > 0) p.col_panes[f.col][f.idx - 1] else p.col_panes[f.col][f.idx + 1]; var k = f.idx; - while (k > 0) : (k -= 1) { + while (to == null and k > 0) : (k -= 1) { sib = p.col_panes[f.col][k - 1]; if (p.panes[sib]) |pp| if (if (pp.file) |ff| panes.Output.fileTraits(ff.output).doc else true) break; } @@ -1119,7 +1122,7 @@ pub fn toggleCollapse(p: *Pardes, id: usize) void { // Convert only visible panes to row weights. The toggle then changes one // pair, rather than letting the column redistribute the released space. snapColWeights(p, at.col); - const neighbor = collapseNeighbor(p, at.col, at.idx); + const neighbor = expandedNeighbor(p, at.col, at.idx, .above) orelse expandedNeighbor(p, at.col, at.idx, .below); if (was_collapsed) { if (neighbor) |other| { const wanted: u16 = @intFromFloat(@min(@as(f32, @floatFromInt(std.math.maxInt(u16))), @max(1, @round(remembered_height)))); @@ -1139,15 +1142,17 @@ pub fn toggleCollapse(p: *Pardes, id: usize) void { compute(p); } -fn collapseNeighbor(p: *Pardes, col: usize, index: usize) ?usize { - var above = index; - while (above > 0) { - above -= 1; - const id = p.col_panes[col][above]; +/// The nearest pane on one side of `index` in its column that is not folded +/// to its tag: the one Collapse lends rows to and Del k / Del j gives them +/// to. A folded pane only keeps its weight for later, so rows handed to it +/// would spread over the whole column instead. +pub fn expandedNeighbor(p: *const Pardes, col: usize, index: usize, side: enum { above, below }) ?usize { + var k = index; + while (if (side == .above) k > 0 else k + 1 < p.col_n[col]) { + k = if (side == .above) k - 1 else k + 1; + const id = p.col_panes[col][k]; if (p.panes[id]) |pane| if (!pane.collapsed) return id; } - for (p.col_panes[col][index + 1 .. p.col_n[col]]) |id| - if (p.panes[id]) |pane| if (!pane.collapsed) return id; return null; } |
