diff options
| author | Gabriel Schneider <[email protected]> | 2026-09-27 23:42:53 -0300 |
|---|---|---|
| committer | Gabriel Schneider <[email protected]> | 2026-10-01 00:12:14 -0300 |
| commit | 9584b0682b45f17aaa42157540947904d867777a (patch) | |
| tree | faac80b84c02e9611e9df9ff0e210c1d1c895a84 /src/panes.zig | |
| parent | 95a3a1bb822e583988bfe0f312d0ef219b27a454 (diff) | |
| download | pardes-9584b0682b45f17aaa42157540947904d867777a.tar.gz pardes-9584b0682b45f17aaa42157540947904d867777a.zip | |
Give prompts their own line to type into instead of the tag's tail
A search, pipe or Save prompt wrote its marker and answer onto the end of
the tag, so the tag's cursor, its selection, its 9P writes and a prompt
abandoned by a click all shared one buffer: the abandoned text stayed in
the tag and a 9P write landed inside the prompt. The answer is now its own
Text on the pane, typed in insert mode and shown on the notice band where
it was already drawn, and the tag never holds any of it.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Diffstat (limited to 'src/panes.zig')
| -rw-r--r-- | src/panes.zig | 36 |
1 files changed, 21 insertions, 15 deletions
diff --git a/src/panes.zig b/src/panes.zig index e6634583..c26065ca 100644 --- a/src/panes.zig +++ b/src/panes.zig @@ -59,12 +59,13 @@ pub const Pane = struct { const PdfSlot = if (Pdf.enabled) ?Pdf.State else void; + /// What an open prompt is asking. The answer is typed into `input`. pub const Prompt = union(enum) { none, - search: u16, - pipe: struct { at: u16, how: modal.Normal.PipeBehavior }, - /// Save on a scratch buffer or a terminal: the tail is a path to write to. - save: u16, + search, + pipe: modal.Normal.PipeBehavior, + /// Save on a scratch buffer or a terminal: the answer is a path to write to. + save, /// Del from the keyboard with open panes both above and below: which /// one takes the rows. Nothing is typed; one key answers. del_side, @@ -94,9 +95,11 @@ pub const Pane = struct { file: ?File.State = null, image: ?Image.State = null, pdf: PdfSlot = if (Pdf.enabled) null else {}, - /// Tag-tail input state. The tag text is presentation; this tag carries - /// which operation owns it and the tail offset restored on submit/cancel. prompt: Prompt = .none, + /// The answer to an open prompt: its marker and what is typed after it, + /// edited in insert mode and shown on the notice band. It is its own text + /// so a prompt never touches the tag. + input: Text = .{ .what = .input }, search_pane: ?usize = null, search_row: ?usize = null, look_at: ?LookSpot = null, @@ -297,20 +300,23 @@ pub const Pane = struct { pub fn tagSlice(p: *const Pane) []const u8 { return p.tag_tail[0..p.tag_tail_len]; } - pub fn promptAt(p: *const Pane) ?u16 { - return switch (p.prompt) { - .none, .del_side => null, - .search, .save => |at| at, - .pipe => |pipe| pipe.at, - }; + /// Close an open prompt, answered or not. Its answer goes with it, and an + /// s/S preview keeps whatever it last previewed. + pub fn closePrompt(pane: *Pane) void { + if (pane.input.own) |text| pane.gpa.free(text); + pane.input = .{ .what = .input }; + pane.prompt = .none; + pane.nsel_snap = 0; } /// What an open prompt shows on its notice band: the one answer every /// painter of the band reads. pub fn promptText(p: *const Pane) ?[]const u8 { - if (p.prompt == .del_side) return config.del_question; - const at = p.promptAt() orelse return null; - return p.tagSlice()[@min(at, p.tag_tail_len)..]; + return switch (p.prompt) { + .none => null, + .del_side => config.del_question, + else => p.input.own orelse "", + }; } pub fn appendTag(p: *Pane, text: []const u8) bool { |
