From 17ee5c7fd5d2a45a762636a285c341e36bfb57cf Mon Sep 17 00:00:00 2001 From: Tim Culverhouse Date: Sun, 24 Sep 2023 19:45:34 -0500 Subject: [PATCH 1/2] terminal: insert a blank cell in insertBlanks The name sounds obvious, but nothing ever is with ANSI escapes. ICH (Insert Blank Characters) should insert a cell with no attributes or colors set. Remove comment about inserting a space for tests: the tests pass with a blank cell inserted. Remove comment about inserted cells having current SGR. Update tests to check for attribute of inserted cell. --- src/terminal/Terminal.zig | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/terminal/Terminal.zig b/src/terminal/Terminal.zig index d4311415a..754693826 100644 --- a/src/terminal/Terminal.zig +++ b/src/terminal/Terminal.zig @@ -1442,8 +1442,6 @@ pub fn linefeed(self: *Terminal) !void { /// region are lost. The cursor position is not changed. /// /// This unsets the pending wrap state without wrapping. -/// -/// The inserted cells are colored according to the current SGR state. pub fn insertBlanks(self: *Terminal, count: usize) void { const tracy = trace(@src()); defer tracy.end(); @@ -1483,9 +1481,7 @@ pub fn insertBlanks(self: *Terminal, count: usize) void { } // Insert zero - var pen = self.screen.cursor.pen; - pen.char = ' '; // NOTE: this should be 0 but we need space for tests - row.fillSlice(pen, start, pivot); + row.fillSlice(.{}, start, pivot); } /// Insert amount lines at the current cursor row. The contents of the line @@ -2615,6 +2611,7 @@ test "Terminal: insertBlanks" { try t.print('A'); try t.print('B'); try t.print('C'); + t.screen.cursor.pen.attrs.bold = true; t.setCursorPos(1, 1); t.insertBlanks(2); @@ -2622,6 +2619,8 @@ test "Terminal: insertBlanks" { var str = try t.plainString(testing.allocator); defer testing.allocator.free(str); try testing.expectEqualStrings(" ABC", str); + const cell = t.screen.getCell(.active, 0, 0); + try testing.expect(!cell.attrs.bold); } } From 3d35ae18696e07c0c311a0391709201b6798cde7 Mon Sep 17 00:00:00 2001 From: Tim Culverhouse Date: Sun, 24 Sep 2023 20:23:25 -0500 Subject: [PATCH 2/2] terminal: save charset state and DECOM mode when saving cursor The charset state and DECOM mode should be saved along with the cursor state. Reference: https://vt100.net/docs/vt510-rm/DECSC.html Fixes: alacritty/saved_cursor --- src/terminal/Terminal.zig | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/terminal/Terminal.zig b/src/terminal/Terminal.zig index 754693826..7b3a12aca 100644 --- a/src/terminal/Terminal.zig +++ b/src/terminal/Terminal.zig @@ -77,6 +77,10 @@ pwd: std.ArrayList(u8), /// The charset state charset: CharsetState = .{}, +/// The saved charset state. This state is saved / restored along with the +/// cursor state +saved_charset: CharsetState = .{}, + /// The color palette to use color_palette: color.Palette = color.default, @@ -419,6 +423,8 @@ fn plainString(self: *Terminal, alloc: Allocator) ![]const u8 { /// was already saved it is overwritten. pub fn saveCursor(self: *Terminal) void { self.screen.saved_cursor = self.screen.cursor; + self.saved_charset = self.charset; + self.modes.save(.origin); } /// Restore cursor position and other state. @@ -427,6 +433,8 @@ pub fn saveCursor(self: *Terminal) void { /// If no save was done before values are reset to their initial values. pub fn restoreCursor(self: *Terminal) void { self.screen.cursor = self.screen.saved_cursor; + self.charset = self.saved_charset; + _ = self.modes.restore(.origin); } /// TODO: test @@ -1442,6 +1450,8 @@ pub fn linefeed(self: *Terminal) !void { /// region are lost. The cursor position is not changed. /// /// This unsets the pending wrap state without wrapping. +/// +/// The inserted cells are colored according to the current SGR state. pub fn insertBlanks(self: *Terminal, count: usize) void { const tracy = trace(@src()); defer tracy.end(); @@ -2913,3 +2923,21 @@ test "Terminal: resize less cols with wide char then print" { t.setCursorPos(1, 2); try t.print('😀'); // 0x1F600 } + +test "Terminal: saveCursor" { + const alloc = testing.allocator; + var t = try init(alloc, 3, 3); + defer t.deinit(alloc); + + t.screen.cursor.pen.attrs.bold = true; + t.charset.gr = .G3; + t.modes.set(.origin, true); + t.saveCursor(); + t.charset.gr = .G0; + t.screen.cursor.pen.attrs.bold = false; + t.modes.set(.origin, false); + t.restoreCursor(); + try testing.expect(t.screen.cursor.pen.attrs.bold); + try testing.expect(t.charset.gr == .G3); + try testing.expect(t.modes.get(.origin)); +}