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/builtins.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/builtins.zig')
| -rw-r--r-- | src/builtins.zig | 43 |
1 files changed, 42 insertions, 1 deletions
diff --git a/src/builtins.zig b/src/builtins.zig index 30a5a50f..146789b0 100644 --- a/src/builtins.zig +++ b/src/builtins.zig @@ -460,9 +460,38 @@ pub const Newcol = struct { } }; +/// Close the pane. `Del k` gives its rows to the open pane above it and +/// `Del j` to the one below, each falling back to the other side. pub const Del = struct { + pub const takes_arg = true; pub fn run(c: Ctx) void { - c.p.removePane(c.id) catch |err| c.p.reportError(c.id, "close", err); + const side = std.mem.trim(u8, c.arg orelse "", " \t\r\n"); + const at = layout.findPane(c.p, c.id); + const above = if (at) |f| layout.expandedNeighbor(c.p, f.col, f.idx, .above) else null; + const below = if (at) |f| layout.expandedNeighbor(c.p, f.col, f.idx, .below) else null; + const to: ?usize = if (std.mem.eql(u8, side, "k")) + above orelse below + else if (std.mem.eql(u8, side, "j")) + below orelse above + else if (side.len > 0) + return c.p.reportError(c.id, "Del k|j", error.InvalidArgument) + else + null; + // Someone at the keyboard with a real choice to make is asked, on the + // pane's notice band; a click, a 9P write or a script closes it the + // way it always has. A folded pane gives back only its tag row, and a + // pane with a prompt open closes as it did rather than trade the + // prompt for a question. + if (side.len == 0 and c.p.can_ask and above != null and below != null and + !c.pane.collapsed and c.pane.prompt == .none) + { + c.pane.prompt = .del_side; + c.p.active = c.id; + // The question says Del already. + if (c.pane.msg_announcement) c.pane.msg_len = 0; + return; + } + c.p.removePane(c.id, to) catch |err| c.p.reportError(c.id, "close", err); } }; @@ -500,6 +529,18 @@ pub const Delcol = struct { } }; +pub const DelAbove = struct { + pub fn run(c: Ctx) void { + Del.run(.{ .p = c.p, .pane = c.pane, .id = c.id, .txt = c.txt, .arg = "k" }); + } +}; + +pub const DelBelow = struct { + pub fn run(c: Ctx) void { + Del.run(.{ .p = c.p, .pane = c.pane, .id = c.id, .txt = c.txt, .arg = "j" }); + } +}; + /// A shell in the calling pane's directory, raw from the first frame. On every /// pane's tagline: the fast path from wherever you are to a prompt there. pub const Tty = struct { |
