mirror of
https://github.com/ghostty-org/ghostty.git
synced 2026-07-31 12:49:03 +00:00
lib-vt: readers for configured scrollback limits
C API callers could configure runtime scrollback limits but could not read them back. Add terminal data keys for the primary screen byte and line configurations. Return GHOSTTY_NO_VALUE for unlimited limits and keep reads stable while an alternate screen is active. Document the configured-value semantics and add focused coverage for defaults, updates, and unlimited values.
This commit is contained in:
@@ -884,8 +884,7 @@ typedef enum GHOSTTY_ENUM_TYPED {
|
||||
* Set the maximum number of physical lines retained in scrollback.
|
||||
*
|
||||
* Lowering the limit immediately removes eligible complete historical
|
||||
* pages. The effective limit retains the active-area and page-granularity
|
||||
* minimums. A NULL value pointer removes the line limit.
|
||||
* pages. A NULL value pointer removes the line limit.
|
||||
*
|
||||
* Input type: size_t*
|
||||
*/
|
||||
@@ -1217,6 +1216,28 @@ typedef enum GHOSTTY_ENUM_TYPED {
|
||||
* Output type: bool *
|
||||
*/
|
||||
GHOSTTY_TERMINAL_DATA_VT_PROCESSING_ERROR = 33,
|
||||
|
||||
/**
|
||||
* The configured maximum scrollback allocation in bytes.
|
||||
*
|
||||
* This always reports the primary screen's configured value, including
|
||||
* while an alternate screen is active. Returns GHOSTTY_NO_VALUE when the
|
||||
* configured byte limit is unlimited.
|
||||
*
|
||||
* Output type: size_t *
|
||||
*/
|
||||
GHOSTTY_TERMINAL_DATA_SCROLLBACK_MAX_BYTES = 34,
|
||||
|
||||
/**
|
||||
* The configured maximum number of physical scrollback lines.
|
||||
*
|
||||
* This always reports the primary screen's configured value, including
|
||||
* while an alternate screen is active. Returns GHOSTTY_NO_VALUE when the
|
||||
* configured line limit is unlimited.
|
||||
*
|
||||
* Output type: size_t *
|
||||
*/
|
||||
GHOSTTY_TERMINAL_DATA_SCROLLBACK_MAX_LINES = 35,
|
||||
GHOSTTY_TERMINAL_DATA_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE,
|
||||
} GhosttyTerminalData;
|
||||
|
||||
|
||||
@@ -782,6 +782,8 @@ pub const TerminalData = enum(c_int) {
|
||||
selection = 31,
|
||||
viewport_active = 32,
|
||||
vt_processing_error = 33,
|
||||
scrollback_max_bytes = 34,
|
||||
scrollback_max_lines = 35,
|
||||
|
||||
/// Output type expected for querying the data of the given kind.
|
||||
pub fn OutType(comptime self: TerminalData) type {
|
||||
@@ -799,7 +801,11 @@ pub const TerminalData = enum(c_int) {
|
||||
.scrollbar => TerminalScrollbar,
|
||||
.cursor_style => style_c.Style,
|
||||
.title, .pwd => lib.String,
|
||||
.total_rows, .scrollback_rows => usize,
|
||||
.total_rows,
|
||||
.scrollback_rows,
|
||||
.scrollback_max_bytes,
|
||||
.scrollback_max_lines,
|
||||
=> usize,
|
||||
.width_px, .height_px => u32,
|
||||
.color_foreground,
|
||||
.color_background,
|
||||
@@ -935,6 +941,16 @@ fn getTyped(
|
||||
),
|
||||
.viewport_active => out.* = t.screens.active.pages.viewport == .active,
|
||||
.vt_processing_error => out.* = wrapper.stream.handler.semantic_failure,
|
||||
.scrollback_max_bytes => {
|
||||
const max = t.screens.get(.primary).?.pages.limits.bytes.explicit;
|
||||
if (max == std.math.maxInt(usize)) return .no_value;
|
||||
out.* = max;
|
||||
},
|
||||
.scrollback_max_lines => {
|
||||
const max = t.screens.get(.primary).?.pages.limits.lines.explicit;
|
||||
if (max == std.math.maxInt(usize)) return .no_value;
|
||||
out.* = max;
|
||||
},
|
||||
}
|
||||
|
||||
return .success;
|
||||
@@ -1807,6 +1823,80 @@ test "get scrollback_rows" {
|
||||
try testing.expectEqual(@as(usize, 2), scrollback);
|
||||
}
|
||||
|
||||
test "get configured scrollback limits" {
|
||||
var t: Terminal = null;
|
||||
try testing.expectEqual(Result.success, new(
|
||||
&lib.alloc.test_allocator,
|
||||
&t,
|
||||
80,
|
||||
3,
|
||||
));
|
||||
defer free(t);
|
||||
|
||||
var value: usize = undefined;
|
||||
try testing.expectEqual(
|
||||
Result.success,
|
||||
get(t, .scrollback_max_bytes, @ptrCast(&value)),
|
||||
);
|
||||
try testing.expectEqual(@as(usize, 10_000), value);
|
||||
try testing.expectEqual(
|
||||
Result.no_value,
|
||||
get(t, .scrollback_max_lines, @ptrCast(&value)),
|
||||
);
|
||||
|
||||
const max_bytes: usize = 0;
|
||||
const max_lines: usize = 12;
|
||||
try testing.expectEqual(
|
||||
Result.success,
|
||||
set(t, .scrollback_max_bytes, &max_bytes),
|
||||
);
|
||||
try testing.expectEqual(
|
||||
Result.success,
|
||||
set(t, .scrollback_max_lines, &max_lines),
|
||||
);
|
||||
try testing.expectEqual(
|
||||
Result.success,
|
||||
get(t, .scrollback_max_bytes, @ptrCast(&value)),
|
||||
);
|
||||
try testing.expectEqual(max_bytes, value);
|
||||
try testing.expectEqual(
|
||||
Result.success,
|
||||
get(t, .scrollback_max_lines, @ptrCast(&value)),
|
||||
);
|
||||
try testing.expectEqual(max_lines, value);
|
||||
|
||||
// The configured limits belong to the primary screen and remain
|
||||
// readable while an alternate screen is active.
|
||||
vt_write(t, "\x1b[?1049h", 8);
|
||||
try testing.expectEqual(
|
||||
Result.success,
|
||||
get(t, .scrollback_max_bytes, @ptrCast(&value)),
|
||||
);
|
||||
try testing.expectEqual(max_bytes, value);
|
||||
try testing.expectEqual(
|
||||
Result.success,
|
||||
get(t, .scrollback_max_lines, @ptrCast(&value)),
|
||||
);
|
||||
try testing.expectEqual(max_lines, value);
|
||||
|
||||
try testing.expectEqual(
|
||||
Result.success,
|
||||
set(t, .scrollback_max_bytes, null),
|
||||
);
|
||||
try testing.expectEqual(
|
||||
Result.success,
|
||||
set(t, .scrollback_max_lines, null),
|
||||
);
|
||||
try testing.expectEqual(
|
||||
Result.no_value,
|
||||
get(t, .scrollback_max_bytes, @ptrCast(&value)),
|
||||
);
|
||||
try testing.expectEqual(
|
||||
Result.no_value,
|
||||
get(t, .scrollback_max_lines, @ptrCast(&value)),
|
||||
);
|
||||
}
|
||||
|
||||
test "get invalid" {
|
||||
var t: Terminal = null;
|
||||
try testing.expectEqual(Result.success, new(
|
||||
|
||||
Reference in New Issue
Block a user