summaryrefslogtreecommitdiff
path: root/src/Text.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/Text.zig')
-rw-r--r--src/Text.zig30
1 files changed, 17 insertions, 13 deletions
diff --git a/src/Text.zig b/src/Text.zig
index d4b6d048..61f238ae 100644
--- a/src/Text.zig
+++ b/src/Text.zig
@@ -76,13 +76,14 @@ ed_redo: [Terminal.history_max]Terminal.Snapshot = undefined,
ed_redo_len: usize = 0,
/// 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 {
+/// workspace's tag belongs to none, and the optional makes every caller
+/// say what it does then.
+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,
+ .column, .workspace => null,
};
}
@@ -98,7 +99,7 @@ pub fn deinit(t: *Text, gpa: std.mem.Allocator) void {
/// the tagline follows its caret where it is drawn, and a prompt's answer is
/// drawn whole.
pub fn show(t: *Text) void {
- if (t.what == .body) t.pane().ensureCursorVisible();
+ if (t.what == .body) if (t.pane()) |w| w.ensureCursorVisible();
}
pub fn toModalCursor(t: *Text) modal.Cursor {
@@ -526,8 +527,9 @@ pub fn visualMove(
pub fn halfPageMove(t: *Text, text: []const u8, range: modal.Selection, down: bool) void {
// a view to move through is a body's; a tag or an answer is all shown
if (t.what != .body) return;
- const half: i32 = @max(1, @divTrunc(@as(i32, t.pane().rows), 2));
- t.pane().scrollBy(if (down) half else -half);
+ const w = t.pane() orelse return;
+ const half: i32 = @max(1, @divTrunc(@as(i32, w.rows), 2));
+ w.scrollBy(if (down) half else -half);
verticalMove(t, text, range, down, @intCast(half));
}
@@ -536,9 +538,10 @@ pub fn halfPageMove(t: *Text, text: []const u8, range: modal.Selection, down: bo
pub fn scrollViewMove(t: *Text, text: []const u8, range: modal.Selection, delta: i32) void {
// a view to move through is a body's; a tag or an answer is all shown
if (t.what != .body) return;
- const margin: i32 = @min(config.scroll_off, @divTrunc(@as(i32, t.pane().rows) - 1, 2));
- t.pane().scrollBy(delta);
- const top = t.pane().scroll();
+ const w = t.pane() orelse return;
+ const margin: i32 = @min(config.scroll_off, @divTrunc(@as(i32, w.rows) - 1, 2));
+ w.scrollBy(delta);
+ const top = w.scroll();
const last_row: i32 = @intCast(File.textLineCount(t, text) - 1);
const cur = modal.selectionCursor(text, range);
if (delta > 0) {
@@ -548,7 +551,7 @@ pub fn scrollViewMove(t: *Text, text: []const u8, range: modal.Selection, delta:
const anchor = if (t.select) range.anchor else head;
setRange(t, text, 0, .{ .anchor = anchor, .head = head }, false);
} else {
- const snap: i32 = @max(0, @min(top + @as(i32, t.pane().rows) - margin - 1, last_row));
+ const snap: i32 = @max(0, @min(top + @as(i32, w.rows) - margin - 1, last_row));
const head = File.textLineStart(t, text, @intCast(snap));
if (head >= cur) return;
const anchor = if (t.select) range.anchor else head;
@@ -560,10 +563,11 @@ pub fn scrollViewMove(t: *Text, text: []const u8, range: modal.Selection, delta:
pub fn gotoWindow(t: *Text, text: []const u8, range: modal.Selection, which: enum { top, center, bottom }, cnt: usize) void {
// a view to move through is a body's; a tag or an answer is all shown
if (t.what != .body) return;
- const margin: i32 = @min(config.scroll_off, @divTrunc(@as(i32, t.pane().rows) - 1, 2));
- const top = t.pane().scroll();
+ const w = t.pane() orelse return;
+ const margin: i32 = @min(config.scroll_off, @divTrunc(@as(i32, w.rows) - 1, 2));
+ const top = w.scroll();
const last_row: i32 = @intCast(File.textLineCount(t, text) - 1);
- const last_vis: i32 = @min(@as(i32, t.pane().rows) - 1, last_row - top);
+ const last_vis: i32 = @min(@as(i32, w.rows) - 1, last_row - top);
const n: i32 = @intCast(cnt - 1);
var vline: i32 = switch (which) {
.top => top + margin + n,