summaryrefslogtreecommitdiff
path: root/src/Text.zig
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-09-28 00:13:11 -0300
committerGabriel Schneider <[email protected]>2026-10-01 00:12:14 -0300
commit42748f92b77367db415c8b4d0f2e537a9e1ddde7 (patch)
tree3ff6606d33149581d5954dcc900eb6ab3e4f0f17 /src/Text.zig
parent23f430573efe4f6ef55b0180aa0d742ff4eca1d9 (diff)
downloadpardes-42748f92b77367db415c8b4d0f2e537a9e1ddde7.tar.gz
pardes-42748f92b77367db415c8b4d0f2e537a9e1ddde7.zip
Make the column and workspace tags Texts with the pane tag's keys
The headers had their own one-line editor with its own keys: Enter always executed, h/l and J/K moved between headers and panes, Ctrl-c/x/v cut and pasted, and TagLine refused a newline that 9P accepted. They are now Texts like a pane's tag, with no prefix and a default until edited, so normal and insert mode, undo and the look and execute keys are the body's. Moving between them is the window keys' job: Up from a pane with nothing above it reaches its column's tag and then the workspace's, Down comes back, and Left and Right walk the column tags. Co-Authored-By: Claude Opus 5.5 <[email protected]>
Diffstat (limited to 'src/Text.zig')
-rw-r--r--src/Text.zig19
1 files changed, 15 insertions, 4 deletions
diff --git a/src/Text.zig b/src/Text.zig
index 3e48a42e..d4b6d048 100644
--- a/src/Text.zig
+++ b/src/Text.zig
@@ -1,7 +1,8 @@
//! 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, its tag is another, and so is the
-//! answer typed into a pane's prompt. Where a body's characters come from --
+//! an edit buffer. A pane's body is one, its tag is another, and so are the
+//! answer typed into a pane's prompt and the tags of the columns and the
+//! workspace. 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
@@ -19,7 +20,7 @@ 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, tag, input };
+pub const What = enum { body, tag, input, column, workspace };
/// A modal line selection (helix `x`): whole rows [r0, r1], absolute.
pub const LineSel = struct {
@@ -74,15 +75,25 @@ ed_undo_len: usize = 0,
ed_redo: [Terminal.history_max]Terminal.Snapshot = undefined,
ed_redo_len: usize = 0,
-/// The window this text belongs to (acme's t->w).
+/// The window this text belongs to (acme's t->w). A column's or the
+/// workspace's tag belongs to no pane; nothing asks it for one.
pub fn pane(t: *Text) *Pane {
return switch (t.what) {
.body => @alignCast(@fieldParentPtr("body", t)),
.tag => @alignCast(@fieldParentPtr("tag", t)),
.input => @alignCast(@fieldParentPtr("input", t)),
+ .column, .workspace => unreachable,
};
}
+/// Free what a text owns: its characters and the buffers its undo keeps.
+pub fn deinit(t: *Text, gpa: std.mem.Allocator) void {
+ if (t.own) |own| gpa.free(own);
+ for (t.ed_undo[0..t.ed_undo_len]) |item| if (item.ovl) |overlay| gpa.free(overlay.text);
+ for (t.ed_redo[0..t.ed_redo_len]) |item| if (item.ovl) |overlay| gpa.free(overlay.text);
+ t.* = .{ .what = t.what };
+}
+
/// Bring the cursor into view (acme's textshow). Only a body scrolls to it;
/// the tagline follows its caret where it is drawn, and a prompt's answer is
/// drawn whole.