diff --git a/src/renderer/Metal.zig b/src/renderer/Metal.zig index 5e282675e..753d155c3 100644 --- a/src/renderer/Metal.zig +++ b/src/renderer/Metal.zig @@ -935,22 +935,26 @@ pub fn updateCell( // cell is selected. // TODO(perf): we can check in advance if selection is in // our viewport at all and not run this on every point. - if (selection) |sel| { - const screen_point = (terminal.point.Viewport{ - .x = x, - .y = y, - }).toScreen(screen); + var selection_res: ?BgFg = sel_colors: { + if (selection) |sel| { + const screen_point = (terminal.point.Viewport{ + .x = x, + .y = y, + }).toScreen(screen); - // If we are selected, we our colors are just inverted fg/bg - if (sel.contains(screen_point)) { - break :colors BgFg{ - .bg = self.config.selection_background orelse self.config.foreground, - .fg = self.config.selection_foreground orelse self.config.background, - }; + // If we are selected, we our colors are just inverted fg/bg + if (sel.contains(screen_point)) { + break :sel_colors BgFg{ + .bg = self.config.selection_background orelse self.config.foreground, + .fg = self.config.selection_foreground orelse self.config.background, + }; + } } - } - const res: BgFg = if (!cell.attrs.inverse) .{ + break :sel_colors null; + }; + + const res: BgFg = selection_res orelse if (!cell.attrs.inverse) .{ // In normal mode, background and fg match the cell. We // un-optionalize the fg by defaulting to our fg color. .bg = if (cell.attrs.has_bg) cell.bg else null, @@ -962,6 +966,16 @@ pub fn updateCell( .bg = if (cell.attrs.has_fg) cell.fg else self.config.foreground, .fg = if (cell.attrs.has_bg) cell.bg else self.config.background, }; + + // If the cell is "invisible" then we just make fg = bg so that + // the cell is transparent but still copy-able. + if (cell.attrs.invisible) { + break :colors BgFg{ + .bg = res.bg, + .fg = res.bg orelse self.config.background, + }; + } + break :colors res; }; diff --git a/src/renderer/OpenGL.zig b/src/renderer/OpenGL.zig index 91c1c8346..e0c393c52 100644 --- a/src/renderer/OpenGL.zig +++ b/src/renderer/OpenGL.zig @@ -1056,22 +1056,26 @@ pub fn updateCell( // cell is selected. // TODO(perf): we can check in advance if selection is in // our viewport at all and not run this on every point. - if (selection) |sel| { - const screen_point = (terminal.point.Viewport{ - .x = x, - .y = y, - }).toScreen(screen); + var selection_res: ?BgFg = sel_colors: { + if (selection) |sel| { + const screen_point = (terminal.point.Viewport{ + .x = x, + .y = y, + }).toScreen(screen); - // If we are selected, we use the selection colors - if (sel.contains(screen_point)) { - break :colors BgFg{ - .bg = self.config.selection_background orelse self.config.foreground, - .fg = self.config.selection_foreground orelse self.config.background, - }; + // If we are selected, we our colors are just inverted fg/bg + if (sel.contains(screen_point)) { + break :sel_colors BgFg{ + .bg = self.config.selection_background orelse self.config.foreground, + .fg = self.config.selection_foreground orelse self.config.background, + }; + } } - } - const res: BgFg = if (!cell.attrs.inverse) .{ + break :sel_colors null; + }; + + const res: BgFg = selection_res orelse if (!cell.attrs.inverse) .{ // In normal mode, background and fg match the cell. We // un-optionalize the fg by defaulting to our fg color. .bg = if (cell.attrs.has_bg) cell.bg else null, @@ -1083,6 +1087,16 @@ pub fn updateCell( .bg = if (cell.attrs.has_fg) cell.fg else self.config.foreground, .fg = if (cell.attrs.has_bg) cell.bg else self.config.background, }; + + // If the cell is "invisible" then we just make fg = bg so that + // the cell is transparent but still copy-able. + if (cell.attrs.invisible) { + break :colors BgFg{ + .bg = res.bg, + .fg = res.bg orelse self.config.background, + }; + } + break :colors res; }; diff --git a/src/terminal/Screen.zig b/src/terminal/Screen.zig index 3d3ea2510..887f55acd 100644 --- a/src/terminal/Screen.zig +++ b/src/terminal/Screen.zig @@ -198,6 +198,7 @@ pub const Cell = struct { faint: bool = false, blink: bool = false, inverse: bool = false, + invisible: bool = false, strikethrough: bool = false, underline: sgr.Attribute.Underline = .none, underline_color: bool = false, @@ -272,7 +273,7 @@ pub const Cell = struct { test { //log.warn("CELL={} bits={} {}", .{ @sizeOf(Cell), @bitSizeOf(Cell), @alignOf(Cell) }); - try std.testing.expectEqual(16, @sizeOf(Cell)); + try std.testing.expectEqual(20, @sizeOf(Cell)); } }; diff --git a/src/terminal/Terminal.zig b/src/terminal/Terminal.zig index 0f0fef511..66b8aa13d 100644 --- a/src/terminal/Terminal.zig +++ b/src/terminal/Terminal.zig @@ -491,6 +491,14 @@ pub fn setAttribute(self: *Terminal, attr: sgr.Attribute) !void { self.screen.cursor.pen.attrs.inverse = false; }, + .invisible => { + self.screen.cursor.pen.attrs.invisible = true; + }, + + .reset_invisible => { + self.screen.cursor.pen.attrs.invisible = false; + }, + .strikethrough => { self.screen.cursor.pen.attrs.strikethrough = true; },