summaryrefslogtreecommitdiff
path: root/src/tagline.zig
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-09-28 01:01:35 -0300
committerGabriel Schneider <[email protected]>2026-10-01 00:12:14 -0300
commit9d2e07e997de155c7dbb894a79e5c11839eab39e (patch)
tree45d09fbe224693b2b9426213e59e56d5b1f35224 /src/tagline.zig
parent425d9beb9c977df364ed83743cb2efdef9429478 (diff)
downloadpardes-9d2e07e997de155c7dbb894a79e5c11839eab39e.tar.gz
pardes-9d2e07e997de155c7dbb894a79e5c11839eab39e.zip
Scroll a tag taller than its rows to keep its caret in view
A tag shows at most eight rows, so a longer one (a 9P write of many lines, or `o` in the tag) put its caret on a line that was never drawn. Pane, column and workspace tags now keep a first line on screen that follows the caret while they have the keyboard, and the pointer and the pane text count their rows from it. Co-Authored-By: Claude Opus 5.5 <[email protected]>
Diffstat (limited to 'src/tagline.zig')
-rw-r--r--src/tagline.zig15
1 files changed, 11 insertions, 4 deletions
diff --git a/src/tagline.zig b/src/tagline.zig
index 1021e9db..a918689b 100644
--- a/src/tagline.zig
+++ b/src/tagline.zig
@@ -81,10 +81,15 @@ pub fn focusedHeader(p: *Pardes) ?*Text {
pub fn revealHeader(p: *Pardes) void {
const t = focusedHeader(p) orelse {
p.header_scroll = 0;
+ p.header_top = 0;
return;
};
const text = edit.flatSurface(p, t) catch return;
- const line = modal.lineSlice(text, @intCast(@max(0, t.cur_row)));
+ const cur: usize = @intCast(@max(0, t.cur_row));
+ const rows: usize = if (p.header_column != null) p.columnBarHeight() else p.topBarHeight();
+ if (cur < p.header_top) p.header_top = cur;
+ if (rows > 0 and cur >= p.header_top + rows) p.header_top = cur + 1 - rows;
+ const line = modal.lineSlice(text, cur);
const width = p.tagCapacity(if (p.header_column) |c| p.col_w[c] -| TAG_TEXT_INSET else p.screen_w);
const col = panes.File.rawDisplayCol(line, @min(@as(usize, @intCast(@max(0, t.cur_col))), line.len));
if (col < p.header_scroll) p.header_scroll = col;
@@ -187,10 +192,11 @@ pub fn enterTag(p: *Pardes, pane: *Pane) void {
/// lands in the tag's own text, or null when it is on the prefix, which
/// only the first line has.
pub fn tagOffsetAt(p: *Pardes, pane: *Pane, row: usize, col: usize) ?modal.Cursor {
- const width = if (row == 0) panes.File.displayWidth(tagPrefix(p, pane) catch return null) else 0;
+ const at = row + pane.tag_top;
+ const width = if (at == 0) panes.File.displayWidth(tagPrefix(p, pane) catch return null) else 0;
if (col < width) return null;
- const line = modal.lineSlice(curTail(pane), row);
- return .{ .row = row, .col = modal.graphemeStart(line, panes.File.rawAtDisplay(line, col - width)) };
+ const line = modal.lineSlice(curTail(pane), at);
+ return .{ .row = at, .col = modal.graphemeStart(line, panes.File.rawAtDisplay(line, col - width)) };
}
/// Start a name draft for a file that can take one, its caret at display
@@ -235,6 +241,7 @@ pub fn exitHeader(p: *Pardes) void {
p.header_column = null;
p.header_drag = false;
p.header_scroll = 0;
+ p.header_top = 0;
}
/// Give the keyboard to a column's tag, or the workspace's for null, in