mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-15 00:06:09 +03:00
terminal: eraseLine protected, tests
This commit is contained in:
@ -1219,36 +1219,58 @@ test "Terminal: eraseDisplay complete" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Erase the line.
|
/// Erase the line.
|
||||||
/// TODO: test
|
|
||||||
pub fn eraseLine(
|
pub fn eraseLine(
|
||||||
self: *Terminal,
|
self: *Terminal,
|
||||||
mode: csi.EraseLine,
|
mode: csi.EraseLine,
|
||||||
|
protected: bool,
|
||||||
) void {
|
) void {
|
||||||
const tracy = trace(@src());
|
const tracy = trace(@src());
|
||||||
defer tracy.end();
|
defer tracy.end();
|
||||||
|
|
||||||
switch (mode) {
|
// We always need a row no matter what
|
||||||
.right => {
|
const row = self.screen.getRow(.{ .active = self.screen.cursor.y });
|
||||||
const row = self.screen.getRow(.{ .active = self.screen.cursor.y });
|
|
||||||
row.fillSlice(self.screen.cursor.pen, self.screen.cursor.x, self.cols);
|
|
||||||
},
|
|
||||||
|
|
||||||
.left => {
|
// Non-protected erase is much faster because we can just memset
|
||||||
const row = self.screen.getRow(.{ .active = self.screen.cursor.y });
|
// a contiguous block of memory.
|
||||||
row.fillSlice(self.screen.cursor.pen, 0, self.screen.cursor.x + 1);
|
if (!protected) {
|
||||||
|
switch (mode) {
|
||||||
|
.right => row.fillSlice(
|
||||||
|
self.screen.cursor.pen,
|
||||||
|
self.screen.cursor.x,
|
||||||
|
self.cols,
|
||||||
|
),
|
||||||
|
|
||||||
// Unsets pending wrap state
|
.left => {
|
||||||
self.screen.cursor.pending_wrap = false;
|
row.fillSlice(self.screen.cursor.pen, 0, self.screen.cursor.x + 1);
|
||||||
},
|
|
||||||
|
|
||||||
.complete => {
|
// Unsets pending wrap state
|
||||||
const row = self.screen.getRow(.{ .active = self.screen.cursor.y });
|
self.screen.cursor.pending_wrap = false;
|
||||||
row.fill(self.screen.cursor.pen);
|
},
|
||||||
},
|
|
||||||
|
|
||||||
|
.complete => row.fill(self.screen.cursor.pen),
|
||||||
|
|
||||||
|
else => log.err("unimplemented erase line mode: {}", .{mode}),
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Protected mode we have to iterate over the cells to check their
|
||||||
|
// protection status and erase them individually.
|
||||||
|
const start, const end = switch (mode) {
|
||||||
|
.right => .{ self.screen.cursor.x, row.lenCells() },
|
||||||
|
.left => .{ 0, self.screen.cursor.x + 1 },
|
||||||
|
.complete => .{ 0, row.lenCells() },
|
||||||
else => {
|
else => {
|
||||||
log.err("unimplemented erase line mode: {}", .{mode});
|
log.err("unimplemented erase line mode: {}", .{mode});
|
||||||
|
return;
|
||||||
},
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
for (start..end) |x| {
|
||||||
|
const cell = row.getCellPtr(x);
|
||||||
|
if (cell.attrs.protected) continue;
|
||||||
|
cell.* = self.screen.cursor.pen;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1443,7 +1465,7 @@ pub fn insertBlanks(self: *Terminal, count: usize) void {
|
|||||||
|
|
||||||
// If our count is larger than the remaining amount, we just erase right.
|
// If our count is larger than the remaining amount, we just erase right.
|
||||||
if (count > self.cols - self.screen.cursor.x) {
|
if (count > self.cols - self.screen.cursor.x) {
|
||||||
self.eraseLine(.right);
|
self.eraseLine(.right, false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2987,3 +3009,60 @@ test "Terminal: setProtectedMode" {
|
|||||||
t.setProtectedMode(.off);
|
t.setProtectedMode(.off);
|
||||||
try testing.expect(!t.screen.cursor.pen.attrs.protected);
|
try testing.expect(!t.screen.cursor.pen.attrs.protected);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test "Terminal: eraseLine protected right" {
|
||||||
|
const alloc = testing.allocator;
|
||||||
|
var t = try init(alloc, 10, 5);
|
||||||
|
defer t.deinit(alloc);
|
||||||
|
|
||||||
|
for ("12345678") |c| try t.print(c);
|
||||||
|
t.setCursorColAbsolute(6);
|
||||||
|
t.setProtectedMode(.dec);
|
||||||
|
try t.print('X');
|
||||||
|
t.setCursorColAbsolute(4);
|
||||||
|
t.eraseLine(.right, true);
|
||||||
|
|
||||||
|
{
|
||||||
|
var str = try t.plainString(testing.allocator);
|
||||||
|
defer testing.allocator.free(str);
|
||||||
|
try testing.expectEqualStrings("123 X", str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
test "Terminal: eraseLine protected left" {
|
||||||
|
const alloc = testing.allocator;
|
||||||
|
var t = try init(alloc, 10, 5);
|
||||||
|
defer t.deinit(alloc);
|
||||||
|
|
||||||
|
for ("123456789") |c| try t.print(c);
|
||||||
|
t.setCursorColAbsolute(6);
|
||||||
|
t.setProtectedMode(.dec);
|
||||||
|
try t.print('X');
|
||||||
|
t.setCursorColAbsolute(8);
|
||||||
|
t.eraseLine(.left, true);
|
||||||
|
|
||||||
|
{
|
||||||
|
var str = try t.plainString(testing.allocator);
|
||||||
|
defer testing.allocator.free(str);
|
||||||
|
try testing.expectEqualStrings(" X 9", str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
test "Terminal: eraseLine protected complete" {
|
||||||
|
const alloc = testing.allocator;
|
||||||
|
var t = try init(alloc, 10, 5);
|
||||||
|
defer t.deinit(alloc);
|
||||||
|
|
||||||
|
for ("123456789") |c| try t.print(c);
|
||||||
|
t.setCursorColAbsolute(6);
|
||||||
|
t.setProtectedMode(.dec);
|
||||||
|
try t.print('X');
|
||||||
|
t.setCursorColAbsolute(8);
|
||||||
|
t.eraseLine(.complete, true);
|
||||||
|
|
||||||
|
{
|
||||||
|
var str = try t.plainString(testing.allocator);
|
||||||
|
defer testing.allocator.free(str);
|
||||||
|
try testing.expectEqualStrings(" X", str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1317,8 +1317,7 @@ const StreamHandler = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn eraseLine(self: *StreamHandler, mode: terminal.EraseLine, protected: bool) !void {
|
pub fn eraseLine(self: *StreamHandler, mode: terminal.EraseLine, protected: bool) !void {
|
||||||
_ = protected;
|
self.terminal.eraseLine(mode, protected);
|
||||||
self.terminal.eraseLine(mode);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deleteChars(self: *StreamHandler, count: usize) !void {
|
pub fn deleteChars(self: *StreamHandler, count: usize) !void {
|
||||||
|
Reference in New Issue
Block a user