diff options
| author | Gabriel Schneider <[email protected]> | 2026-09-28 01:09:05 -0300 |
|---|---|---|
| committer | Gabriel Schneider <[email protected]> | 2026-10-01 00:12:14 -0300 |
| commit | f48ab559a4d257137a3aae987a4962f9d74ede23 (patch) | |
| tree | 99b233f7386673ee7a84031f4e5ff1b3011adae0 /src/Text.zig | |
| parent | fb72c2402fa1b1ae99be64fe7b2947ea5dd42623 (diff) | |
| download | pardes-f48ab559a4d257137a3aae987a4962f9d74ede23.tar.gz pardes-f48ab559a4d257137a3aae987a4962f9d74ede23.zip | |
Have Text.pane return nothing for a header instead of trapping
A column's or the workspace's tag has no pane, and asking one for it hit
unreachable; every caller guarded against that by checking `what` first.
An optional makes each caller say what it does without a pane, so a
forgotten guard no longer compiles into a crash.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Diffstat (limited to 'src/Text.zig')
| -rw-r--r-- | src/Text.zig | 30 |
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, |
