From 9d2e07e997de155c7dbb894a79e5c11839eab39e Mon Sep 17 00:00:00 2001 From: Gabriel Schneider Date: Mon, 28 Sep 2026 01:01:35 -0300 Subject: 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 --- src/tagline.zig | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'src/tagline.zig') 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 -- cgit v1.3