mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-16 00:36:07 +03:00
terminal/new: decaln
This commit is contained in:
@ -4521,6 +4521,7 @@ test "Terminal: index inside left/right margin" {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// X
|
||||||
test "Terminal: DECALN" {
|
test "Terminal: DECALN" {
|
||||||
const alloc = testing.allocator;
|
const alloc = testing.allocator;
|
||||||
var t = try init(alloc, 2, 2);
|
var t = try init(alloc, 2, 2);
|
||||||
@ -4543,6 +4544,7 @@ test "Terminal: DECALN" {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// X
|
||||||
test "Terminal: decaln reset margins" {
|
test "Terminal: decaln reset margins" {
|
||||||
const alloc = testing.allocator;
|
const alloc = testing.allocator;
|
||||||
var t = try init(alloc, 3, 3);
|
var t = try init(alloc, 3, 3);
|
||||||
@ -4561,6 +4563,7 @@ test "Terminal: decaln reset margins" {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// X
|
||||||
test "Terminal: decaln preserves color" {
|
test "Terminal: decaln preserves color" {
|
||||||
const alloc = testing.allocator;
|
const alloc = testing.allocator;
|
||||||
var t = try init(alloc, 3, 3);
|
var t = try init(alloc, 3, 3);
|
||||||
|
@ -394,6 +394,11 @@ pub fn setAttribute(self: *Screen, attr: sgr.Attribute) !void {
|
|||||||
.unknown => return,
|
.unknown => return,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try self.manualStyleUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Call this whenever you manually change the cursor style.
|
||||||
|
pub fn manualStyleUpdate(self: *Screen) !void {
|
||||||
var page = &self.cursor.page_offset.page.data;
|
var page = &self.cursor.page_offset.page.data;
|
||||||
|
|
||||||
// Remove our previous style if is unused.
|
// Remove our previous style if is unused.
|
||||||
|
@ -1333,6 +1333,59 @@ fn blankCells(
|
|||||||
@memset(cells, self.blankCell());
|
@memset(cells, self.blankCell());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Resets all margins and fills the whole screen with the character 'E'
|
||||||
|
///
|
||||||
|
/// Sets the cursor to the top left corner.
|
||||||
|
pub fn decaln(self: *Terminal) !void {
|
||||||
|
// TODO: erase display to gc graphemes, styles
|
||||||
|
|
||||||
|
// Clear our stylistic attributes. This is the only thing that can
|
||||||
|
// fail so we do it first so we can undo it.
|
||||||
|
const old_style = self.screen.cursor.style;
|
||||||
|
self.screen.cursor.style = .{
|
||||||
|
.bg_color = self.screen.cursor.style.bg_color,
|
||||||
|
.fg_color = self.screen.cursor.style.fg_color,
|
||||||
|
// TODO: protected attribute
|
||||||
|
// .protected = self.screen.cursor.pen.attrs.protected,
|
||||||
|
};
|
||||||
|
errdefer self.screen.cursor.style = old_style;
|
||||||
|
try self.screen.manualStyleUpdate();
|
||||||
|
|
||||||
|
// Reset margins, also sets cursor to top-left
|
||||||
|
self.scrolling_region = .{
|
||||||
|
.top = 0,
|
||||||
|
.bottom = self.rows - 1,
|
||||||
|
.left = 0,
|
||||||
|
.right = self.cols - 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Origin mode is disabled
|
||||||
|
self.modes.set(.origin, false);
|
||||||
|
|
||||||
|
// Move our cursor to the top-left
|
||||||
|
self.setCursorPos(1, 1);
|
||||||
|
|
||||||
|
// Fill with Es, does not move cursor.
|
||||||
|
// TODO: cursor across pages
|
||||||
|
var page = &self.screen.cursor.page_offset.page.data;
|
||||||
|
const rows: [*]Row = @ptrCast(self.screen.cursor.page_row);
|
||||||
|
for (0..self.rows) |y| {
|
||||||
|
const row: *Row = @ptrCast(rows + y);
|
||||||
|
const cells = page.getCells(row);
|
||||||
|
@memset(cells, .{
|
||||||
|
.content_tag = .codepoint,
|
||||||
|
.content = .{ .codepoint = 'E' },
|
||||||
|
.style_id = self.screen.cursor.style_id,
|
||||||
|
});
|
||||||
|
|
||||||
|
// If we have a ref-counted style, increase
|
||||||
|
if (self.screen.cursor.style_ref) |ref| {
|
||||||
|
ref.* += @intCast(cells.len);
|
||||||
|
row.styled = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Set a style attribute.
|
/// Set a style attribute.
|
||||||
pub fn setAttribute(self: *Terminal, attr: sgr.Attribute) !void {
|
pub fn setAttribute(self: *Terminal, attr: sgr.Attribute) !void {
|
||||||
try self.screen.setAttribute(attr);
|
try self.screen.setAttribute(attr);
|
||||||
@ -4586,3 +4639,72 @@ test "Terminal: print with style marks the row as styled" {
|
|||||||
try testing.expect(list_cell.row.styled);
|
try testing.expect(list_cell.row.styled);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test "Terminal: DECALN" {
|
||||||
|
const alloc = testing.allocator;
|
||||||
|
var t = try init(alloc, 2, 2);
|
||||||
|
defer t.deinit(alloc);
|
||||||
|
|
||||||
|
// Initial value
|
||||||
|
try t.print('A');
|
||||||
|
t.carriageReturn();
|
||||||
|
try t.linefeed();
|
||||||
|
try t.print('B');
|
||||||
|
try t.decaln();
|
||||||
|
|
||||||
|
try testing.expectEqual(@as(usize, 0), t.screen.cursor.y);
|
||||||
|
try testing.expectEqual(@as(usize, 0), t.screen.cursor.x);
|
||||||
|
|
||||||
|
{
|
||||||
|
const str = try t.plainString(testing.allocator);
|
||||||
|
defer testing.allocator.free(str);
|
||||||
|
try testing.expectEqualStrings("EE\nEE", str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
test "Terminal: decaln reset margins" {
|
||||||
|
const alloc = testing.allocator;
|
||||||
|
var t = try init(alloc, 3, 3);
|
||||||
|
defer t.deinit(alloc);
|
||||||
|
|
||||||
|
// Initial value
|
||||||
|
t.modes.set(.origin, true);
|
||||||
|
t.setTopAndBottomMargin(2, 3);
|
||||||
|
try t.decaln();
|
||||||
|
t.scrollDown(1);
|
||||||
|
|
||||||
|
{
|
||||||
|
const str = try t.plainString(testing.allocator);
|
||||||
|
defer testing.allocator.free(str);
|
||||||
|
try testing.expectEqualStrings("\nEEE\nEEE", str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
test "Terminal: decaln preserves color" {
|
||||||
|
const alloc = testing.allocator;
|
||||||
|
var t = try init(alloc, 3, 3);
|
||||||
|
defer t.deinit(alloc);
|
||||||
|
|
||||||
|
// Initial value
|
||||||
|
try t.setAttribute(.{ .direct_color_bg = .{ .r = 0xFF, .g = 0, .b = 0 } });
|
||||||
|
t.modes.set(.origin, true);
|
||||||
|
t.setTopAndBottomMargin(2, 3);
|
||||||
|
try t.decaln();
|
||||||
|
t.scrollDown(1);
|
||||||
|
|
||||||
|
{
|
||||||
|
const str = try t.plainString(testing.allocator);
|
||||||
|
defer testing.allocator.free(str);
|
||||||
|
try testing.expectEqualStrings("\nEEE\nEEE", str);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const list_cell = t.screen.pages.getCell(.{ .active = .{ .x = 0, .y = 0 } }).?;
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user