feat: implement scroll-to-bottom on output option

Implements the `output` option for the `scroll-to-bottom` configuration,
which scrolls the viewport to the bottom when new lines are printed.

Co-Authored-By: Sachin <sachinbeniwal0101@gmail.com>
pull/9938/head
benodiwal 2025-12-17 16:45:18 +05:30
parent 50cb1bafd7
commit c00949275c
No known key found for this signature in database
GPG Key ID: 5A94FC71DED69DBC
3 changed files with 13 additions and 1 deletions

View File

@ -835,7 +835,7 @@ palette: Palette = .{},
/// anything but modifiers or keybinds that are processed by Ghostty).
///
/// - `output` If set, scroll the surface to the bottom if there is new data
/// to display. (Currently unimplemented.)
/// to display (e.g., when new lines are printed to the terminal).
///
/// The default is `keystroke, no-output`.
@"scroll-to-bottom": ScrollToBottom = .default,

View File

@ -165,6 +165,7 @@ pub const DerivedConfig = struct {
osc_color_report_format: configpkg.Config.OSCColorReportFormat,
clipboard_write: configpkg.ClipboardAccess,
enquiry_response: []const u8,
scroll_to_bottom: configpkg.Config.ScrollToBottom,
pub fn init(
alloc_gpa: Allocator,
@ -185,6 +186,7 @@ pub const DerivedConfig = struct {
.osc_color_report_format = config.@"osc-color-report-format",
.clipboard_write = config.@"clipboard-write",
.enquiry_response = try alloc.dupe(u8, config.@"enquiry-response"),
.scroll_to_bottom = config.@"scroll-to-bottom",
// This has to be last so that we copy AFTER the arena allocations
// above happen (Zig assigns in order).
@ -279,6 +281,7 @@ pub fn init(self: *Termio, alloc: Allocator, opts: termio.Options) !void {
.enquiry_response = opts.config.enquiry_response,
.default_cursor_style = opts.config.cursor_style,
.default_cursor_blink = opts.config.cursor_blink,
.scroll_to_bottom_on_output = opts.config.scroll_to_bottom.output,
};
const thread_enter_state = try ThreadEnterState.create(

View File

@ -56,6 +56,9 @@ pub const StreamHandler = struct {
/// The clipboard write access configuration.
clipboard_write: configpkg.ClipboardAccess,
/// The scroll-to-bottom behavior configuration.
scroll_to_bottom_on_output: bool,
//---------------------------------------------------------------
// Internal state
@ -112,6 +115,7 @@ pub const StreamHandler = struct {
self.enquiry_response = config.enquiry_response;
self.default_cursor_style = config.cursor_style;
self.default_cursor_blink = config.cursor_blink;
self.scroll_to_bottom_on_output = config.scroll_to_bottom.output;
// If our cursor is the default, then we update it immediately.
if (self.default_cursor) self.setCursorStyle(.default) catch |err| {
@ -575,6 +579,11 @@ pub const StreamHandler = struct {
// Small optimization: call index instead of linefeed because they're
// identical and this avoids one layer of function call overhead.
try self.terminal.index();
// If configured, scroll to bottom on output so the user sees new content
if (self.scroll_to_bottom_on_output) {
try self.terminal.scrollViewport(.bottom);
}
}
pub inline fn reverseIndex(self: *StreamHandler) !void {