diff --git a/src/terminal/Screen.zig b/src/terminal/Screen.zig index 95a842df4..e07db5faf 100644 --- a/src/terminal/Screen.zig +++ b/src/terminal/Screen.zig @@ -165,6 +165,7 @@ pub const Cell = struct { italic: bool = false, faint: bool = false, underline: bool = false, + blink: bool = false, inverse: bool = false, strikethrough: bool = false, diff --git a/src/terminal/Terminal.zig b/src/terminal/Terminal.zig index f83d59287..50bc40f69 100644 --- a/src/terminal/Terminal.zig +++ b/src/terminal/Terminal.zig @@ -354,10 +354,20 @@ pub fn setAttribute(self: *Terminal, attr: sgr.Attribute) !void { self.screen.cursor.pen.attrs.bold = true; }, + .reset_bold => { + // Bold and faint share the same SGR code for this + self.screen.cursor.pen.attrs.bold = false; + self.screen.cursor.pen.attrs.faint = false; + }, + .italic => { self.screen.cursor.pen.attrs.italic = true; }, + .reset_italic => { + self.screen.cursor.pen.attrs.italic = false; + }, + .faint => { self.screen.cursor.pen.attrs.faint = true; }, @@ -366,6 +376,19 @@ pub fn setAttribute(self: *Terminal, attr: sgr.Attribute) !void { self.screen.cursor.pen.attrs.underline = true; }, + .reset_underline => { + self.screen.cursor.pen.attrs.underline = false; + }, + + .blink => { + log.warn("blink requested, but not implemented", .{}); + self.screen.cursor.pen.attrs.blink = true; + }, + + .reset_blink => { + self.screen.cursor.pen.attrs.blink = false; + }, + .inverse => { self.screen.cursor.pen.attrs.inverse = true; }, @@ -434,7 +457,7 @@ pub fn setAttribute(self: *Terminal, attr: sgr.Attribute) !void { self.screen.cursor.pen.bg = color.default[idx]; }, - else => return error.InvalidAttribute, + .unknown => return error.InvalidAttribute, } } diff --git a/src/terminal/sgr.zig b/src/terminal/sgr.zig index 38f0d1391..835694092 100644 --- a/src/terminal/sgr.zig +++ b/src/terminal/sgr.zig @@ -20,18 +20,23 @@ pub const Attribute = union(enum) { /// Bold the text. bold: void, + reset_bold: void, /// Italic text. italic: void, + reset_italic: void, /// Faint/dim text. + /// Note: reset faint is the same SGR code as reset bold faint: void, /// Underline the text underline: void, + reset_underline: void, /// Blink the text blink: void, + reset_blink: void, /// Invert fg/bg colors. inverse: void, @@ -106,10 +111,20 @@ pub const Parser = struct { 5 => return Attribute{ .blink = {} }, + 6 => return Attribute{ .blink = {} }, + 7 => return Attribute{ .inverse = {} }, 9 => return Attribute{ .strikethrough = {} }, + 22 => return Attribute{ .reset_bold = {} }, + + 23 => return Attribute{ .reset_italic = {} }, + + 24 => return Attribute{ .reset_underline = {} }, + + 25 => return Attribute{ .reset_blink = {} }, + 27 => return Attribute{ .reset_inverse = {} }, 29 => return Attribute{ .reset_strikethrough = {} }, @@ -225,13 +240,56 @@ test "sgr: Parser multiple" { } test "sgr: bold" { - const v = testParse(&[_]u16{1}); - try testing.expect(v == .bold); + { + const v = testParse(&[_]u16{1}); + try testing.expect(v == .bold); + } + + { + const v = testParse(&[_]u16{22}); + try testing.expect(v == .reset_bold); + } } test "sgr: italic" { - const v = testParse(&[_]u16{3}); - try testing.expect(v == .italic); + { + const v = testParse(&[_]u16{3}); + try testing.expect(v == .italic); + } + + { + const v = testParse(&[_]u16{23}); + try testing.expect(v == .reset_italic); + } +} + +test "sgr: underline" { + { + const v = testParse(&[_]u16{4}); + try testing.expect(v == .underline); + } + + { + const v = testParse(&[_]u16{24}); + try testing.expect(v == .reset_underline); + } +} + +test "sgr: blink" { + { + const v = testParse(&[_]u16{5}); + try testing.expect(v == .blink); + } + + { + const v = testParse(&[_]u16{6}); + try testing.expect(v == .blink); + } + + { + const v = testParse(&[_]u16{25}); + try testing.expect(v == .reset_blink); + } } test "sgr: inverse" {