From 2c16c9e40c8862342ea02a9f3ffae2a52c3735e3 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Tue, 24 Mar 2026 13:57:34 -0700 Subject: [PATCH] vt: add total_rows and scrollback_rows to terminal get API Add total_rows and scrollback_rows as new TerminalData variants queryable through the existing ghostty_terminal_get interface, using the cached O(1) total_rows field from PageList rather than introducing standalone functions. --- include/ghostty/vt/terminal.h | 14 +++++++++++ src/terminal/c/terminal.zig | 47 +++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+) diff --git a/include/ghostty/vt/terminal.h b/include/ghostty/vt/terminal.h index 30f6179c8..86a425dce 100644 --- a/include/ghostty/vt/terminal.h +++ b/include/ghostty/vt/terminal.h @@ -556,6 +556,20 @@ typedef enum { * Output type: GhosttyString * */ GHOSTTY_TERMINAL_DATA_PWD = 13, + + /** + * The total number of rows in the active screen including scrollback. + * + * Output type: size_t * + */ + GHOSTTY_TERMINAL_DATA_TOTAL_ROWS = 14, + + /** + * The number of scrollback rows (total rows minus viewport rows). + * + * Output type: size_t * + */ + GHOSTTY_TERMINAL_DATA_SCROLLBACK_ROWS = 15, } GhosttyTerminalData; /** diff --git a/src/terminal/c/terminal.zig b/src/terminal/c/terminal.zig index da8e91a0f..60b192c96 100644 --- a/src/terminal/c/terminal.zig +++ b/src/terminal/c/terminal.zig @@ -444,6 +444,8 @@ pub const TerminalData = enum(c_int) { mouse_tracking = 11, title = 12, pwd = 13, + total_rows = 14, + scrollback_rows = 15, /// Output type expected for querying the data of the given kind. pub fn OutType(comptime self: TerminalData) type { @@ -456,6 +458,7 @@ pub const TerminalData = enum(c_int) { .scrollbar => TerminalScrollbar, .cursor_style => style_c.Style, .title, .pwd => lib.String, + .total_rows, .scrollback_rows => usize, }; } }; @@ -512,6 +515,8 @@ fn getTyped( const pwd = t.getPwd() orelse ""; out.* = .{ .ptr = pwd.ptr, .len = pwd.len }; }, + .total_rows => out.* = t.screens.active.pages.total_rows, + .scrollback_rows => out.* = t.screens.active.pages.total_rows - t.rows, } return .success; @@ -1003,6 +1008,48 @@ test "get mouse_tracking" { try testing.expect(!tracking); } +test "get total_rows" { + var t: Terminal = null; + try testing.expectEqual(Result.success, new( + &lib_alloc.test_allocator, + &t, + .{ + .cols = 80, + .rows = 24, + .max_scrollback = 10_000, + }, + )); + defer free(t); + + var total: usize = undefined; + try testing.expectEqual(Result.success, get(t, .total_rows, @ptrCast(&total))); + try testing.expect(total >= 24); +} + +test "get scrollback_rows" { + var t: Terminal = null; + try testing.expectEqual(Result.success, new( + &lib_alloc.test_allocator, + &t, + .{ + .cols = 80, + .rows = 3, + .max_scrollback = 10_000, + }, + )); + defer free(t); + + var scrollback: usize = undefined; + try testing.expectEqual(Result.success, get(t, .scrollback_rows, @ptrCast(&scrollback))); + try testing.expectEqual(@as(usize, 0), scrollback); + + // Write enough lines to push content into scrollback + vt_write(t, "line1\r\nline2\r\nline3\r\nline4\r\nline5\r\n", 34); + + try testing.expectEqual(Result.success, get(t, .scrollback_rows, @ptrCast(&scrollback))); + try testing.expectEqual(@as(usize, 2), scrollback); +} + test "get invalid" { var t: Terminal = null; try testing.expectEqual(Result.success, new(