mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-16 16:56:09 +03:00
terminal: index (LF) that scrolls scroll region preserves SGR
Fixes #1676 The comment in the diff explains. This is a regression that was not unit tested properly in the old implementation prior to the paged-terminal merge.
This commit is contained in:
@ -967,7 +967,7 @@ pub fn clearPrompt(self: *Screen) void {
|
|||||||
|
|
||||||
/// Returns the blank cell to use when doing terminal operations that
|
/// Returns the blank cell to use when doing terminal operations that
|
||||||
/// require preserving the bg color.
|
/// require preserving the bg color.
|
||||||
fn blankCell(self: *const Screen) Cell {
|
pub fn blankCell(self: *const Screen) Cell {
|
||||||
if (self.cursor.style_id == style.default_id) return .{};
|
if (self.cursor.style_id == style.default_id) return .{};
|
||||||
return self.cursor.style.bgCell() orelse .{};
|
return self.cursor.style.bgCell() orelse .{};
|
||||||
}
|
}
|
||||||
|
@ -1089,7 +1089,15 @@ pub fn index(self: *Terminal) !void {
|
|||||||
} else {
|
} else {
|
||||||
// Slow path for left and right scrolling region margins.
|
// Slow path for left and right scrolling region margins.
|
||||||
if (self.scrolling_region.left != 0 or
|
if (self.scrolling_region.left != 0 or
|
||||||
self.scrolling_region.right != self.cols - 1)
|
self.scrolling_region.right != self.cols - 1 or
|
||||||
|
|
||||||
|
// PERF(mitchellh): If we have an SGR background set then
|
||||||
|
// we need to preserve that background in our erased rows.
|
||||||
|
// scrollUp does that but eraseRowBounded below does not.
|
||||||
|
// However, scrollUp is WAY slower. We should optimize this
|
||||||
|
// case to work in the eraseRowBounded codepath and remove
|
||||||
|
// this check.
|
||||||
|
!self.screen.blankCell().isZero())
|
||||||
{
|
{
|
||||||
self.scrollUp(1);
|
self.scrollUp(1);
|
||||||
return;
|
return;
|
||||||
@ -5317,6 +5325,40 @@ test "Terminal: index inside scroll region" {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test "Terminal: index bottom of scroll region with background SGR" {
|
||||||
|
const alloc = testing.allocator;
|
||||||
|
var t = try init(alloc, .{ .rows = 5, .cols = 5 });
|
||||||
|
defer t.deinit(alloc);
|
||||||
|
|
||||||
|
t.setTopAndBottomMargin(1, 3);
|
||||||
|
t.setCursorPos(4, 1);
|
||||||
|
try t.print('B');
|
||||||
|
t.setCursorPos(3, 1);
|
||||||
|
try t.print('A');
|
||||||
|
try t.setAttribute(.{ .direct_color_bg = .{
|
||||||
|
.r = 0xFF,
|
||||||
|
.g = 0,
|
||||||
|
.b = 0,
|
||||||
|
} });
|
||||||
|
try t.index();
|
||||||
|
|
||||||
|
{
|
||||||
|
const str = try t.plainString(testing.allocator);
|
||||||
|
defer testing.allocator.free(str);
|
||||||
|
try testing.expectEqualStrings("\nA\n\nB", str);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (0..t.cols) |x| {
|
||||||
|
const list_cell = t.screen.pages.getCell(.{ .active = .{ .x = x, .y = 2 } }).?;
|
||||||
|
try testing.expect(list_cell.cell.content_tag == .bg_color_rgb);
|
||||||
|
try testing.expectEqual(Cell.RGB{
|
||||||
|
.r = 0xFF,
|
||||||
|
.g = 0,
|
||||||
|
.b = 0,
|
||||||
|
}, list_cell.cell.content.color_rgb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
test "Terminal: index bottom of primary screen with scroll region" {
|
test "Terminal: index bottom of primary screen with scroll region" {
|
||||||
const alloc = testing.allocator;
|
const alloc = testing.allocator;
|
||||||
var t = try init(alloc, .{ .rows = 5, .cols = 5 });
|
var t = try init(alloc, .{ .rows = 5, .cols = 5 });
|
||||||
|
@ -1138,6 +1138,10 @@ pub const Cell = packed struct(u64) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn isZero(self: Cell) bool {
|
||||||
|
return @as(u64, @bitCast(self)) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
pub fn hasText(self: Cell) bool {
|
pub fn hasText(self: Cell) bool {
|
||||||
return switch (self.content_tag) {
|
return switch (self.content_tag) {
|
||||||
.codepoint,
|
.codepoint,
|
||||||
@ -1231,6 +1235,12 @@ pub const Cell = packed struct(u64) {
|
|||||||
// //const pages = total_size / std.mem.page_size;
|
// //const pages = total_size / std.mem.page_size;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
test "Cell is zero by default" {
|
||||||
|
const cell: Cell = .{};
|
||||||
|
const cell_int: u64 = @bitCast(cell);
|
||||||
|
try std.testing.expectEqual(@as(u64, 0), cell_int);
|
||||||
|
}
|
||||||
|
|
||||||
test "Page capacity adjust cols down" {
|
test "Page capacity adjust cols down" {
|
||||||
const original = std_capacity;
|
const original = std_capacity;
|
||||||
const original_size = Page.layout(original).total_size;
|
const original_size = Page.layout(original).total_size;
|
||||||
|
@ -316,7 +316,9 @@ pub fn Stream(comptime Handler: type) type {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn execute(self: *Self, c: u8) !void {
|
pub fn execute(self: *Self, c: u8) !void {
|
||||||
switch (@as(ansi.C0, @enumFromInt(c))) {
|
const c0: ansi.C0 = @enumFromInt(c);
|
||||||
|
// log.info("execute: {}", .{c0});
|
||||||
|
switch (c0) {
|
||||||
// We ignore SOH/STX: https://github.com/microsoft/terminal/issues/10786
|
// We ignore SOH/STX: https://github.com/microsoft/terminal/issues/10786
|
||||||
.NUL, .SOH, .STX => {},
|
.NUL, .SOH, .STX => {},
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user