summaryrefslogtreecommitdiff
path: root/src/Text.zig
diff options
context:
space:
mode:
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();
}