renderer: support invisible attribute

This commit is contained in:
Mitchell Hashimoto
2023-06-25 09:31:33 -07:00
parent aafff194f9
commit c6356930cc
4 changed files with 64 additions and 27 deletions

View File

@ -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;
};

View File

@ -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;
};

View File

@ -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));
}
};

View File

@ -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;
},