summaryrefslogtreecommitdiff
path: root/src/Text.zig
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-09-27 23:42:53 -0300
committerGabriel Schneider <[email protected]>2026-10-01 00:12:14 -0300
commit9584b0682b45f17aaa42157540947904d867777a (patch)
treefaac80b84c02e9611e9df9ff0e210c1d1c895a84 /src/Text.zig
parent95a3a1bb822e583988bfe0f312d0ef219b27a454 (diff)
downloadpardes-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/Text.zig')
-rw-r--r--src/Text.zig33
1 files changed, 26 insertions, 7 deletions
diff --git a/src/Text.zig b/src/Text.zig
index ad5aa186..aaa6dc88 100644
--- a/src/Text.zig
+++ b/src/Text.zig
@@ -1,9 +1,11 @@
//! One editable text, acme's Text (editors/acme/dat.h:171-190, text.c): the
//! cursor, the selections and the modal state that edit it, and the undo of
-//! an edit buffer. A pane's body is one. Where its characters come from -- a
-//! file's content, a terminal's edit overlay, a PDF's text -- is the window's
-//! business (edit.zig's editText and flatSurface), the way acme's Text reads
-//! its File; everything here works on the flat text it is handed.
+//! an edit buffer. A pane's body is one, and so is the answer typed into a
+//! pane's prompt. Where a body's characters come from -- a file's content, a
+//! terminal's edit overlay, a PDF's text -- is the window's business
+//! (edit.zig's editText and flatSurface), the way acme's Text reads its File;
+//! every other text owns its characters. Everything here works on the flat
+//! text it is handed.
const std = @import("std");
const panes = @import("panes.zig");
const modal = @import("modal.zig");
@@ -15,6 +17,10 @@ const Text = @This();
pub const Mode = enum { normal, insert, tty };
+/// Which text of its window this is, acme's `what`. It says where the
+/// characters live and whether moving the cursor scrolls a body.
+pub const What = enum { body, input };
+
/// A modal line selection (helix `x`): whole rows [r0, r1], absolute.
pub const LineSel = struct {
active: bool = false,
@@ -41,6 +47,10 @@ pub const SelRange = struct {
sticky: i32 = -1,
};
+what: What = .body,
+/// The characters of a text that holds its own (gpa-owned): everything but
+/// a body, which reads its pane's.
+own: ?[]u8 = null,
mode: Mode = .normal,
cur_pinned: bool = false,
cur_row: i32 = 0,
@@ -65,7 +75,16 @@ ed_redo_len: usize = 0,
/// The window this text belongs to (acme's t->w).
pub fn pane(t: *Text) *Pane {
- return @alignCast(@fieldParentPtr("body", t));
+ return switch (t.what) {
+ .body => @alignCast(@fieldParentPtr("body", t)),
+ .input => @alignCast(@fieldParentPtr("input", t)),
+ };
+}
+
+/// Bring the cursor into view (acme's textshow). Only a body scrolls to it;
+/// a prompt's answer is drawn whole.
+pub fn show(t: *Text) void {
+ if (t.what == .body) t.pane().ensureCursorVisible();
}
pub fn toModalCursor(t: *Text) modal.Cursor {
@@ -143,7 +162,7 @@ pub fn setRange(t: *Text, text: []const u8, row0: i32, r0: modal.Selection, expl
t.cur_pinned = true;
t.sticky_col = -1;
t.normal.clear();
- t.pane().ensureCursorVisible();
+ t.show();
}
pub fn ranges(t: *Text, text: []const u8, row0: i32, out: *[max_selections]modal.Selection) struct { n: usize, pri: usize } {
@@ -602,5 +621,5 @@ pub fn clampCursor(t: *Text, text: []const u8, row0: i32) void {
t.cur_pinned = true;
t.vsel.active = false;
t.msel.active = false;
- t.pane().ensureCursorVisible();
+ t.show();
}