diff options
Diffstat (limited to 'src/Text.zig')
| -rw-r--r-- | src/Text.zig | 33 |
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(); } |
