diff --git a/src/terminal/Screen.zig b/src/terminal/Screen.zig index a949d858d..73f39d1ee 100644 --- a/src/terminal/Screen.zig +++ b/src/terminal/Screen.zig @@ -232,6 +232,7 @@ pub const Cell = struct { strikethrough: bool = false, underline: sgr.Attribute.Underline = .none, underline_color: bool = false, + protected: bool = false, /// True if this is a wide character. This char takes up /// two cells. The following cell ALWAYS is a space. diff --git a/src/terminal/Terminal.zig b/src/terminal/Terminal.zig index eae35385a..62cf2c071 100644 --- a/src/terminal/Terminal.zig +++ b/src/terminal/Terminal.zig @@ -1728,6 +1728,24 @@ pub fn kittyGraphics( return kitty.graphics.execute(alloc, self, cmd); } +/// Set the character protection mode for the terminal. +pub fn setProtectedMode(self: *Terminal, mode: ansi.ProtectedMode) void { + switch (mode) { + .off => { + self.screen.cursor.pen.attrs.protected = false; + }, + + // TODO: ISO/DEC have very subtle differences, so we should track that. + .iso => { + self.screen.cursor.pen.attrs.protected = true; + }, + + .dec => { + self.screen.cursor.pen.attrs.protected = true; + }, + } +} + /// Full reset pub fn fullReset(self: *Terminal, alloc: Allocator) void { self.primaryScreen(alloc, .{ .clear_on_exit = true, .cursor_save = true }); @@ -2953,3 +2971,19 @@ test "Terminal: saveCursor with screen change" { try testing.expect(t.screen.charset.gr == .G3); try testing.expect(t.modes.get(.origin)); } + +test "Terminal: setProtectedMode" { + const alloc = testing.allocator; + var t = try init(alloc, 3, 3); + defer t.deinit(alloc); + + try testing.expect(!t.screen.cursor.pen.attrs.protected); + t.setProtectedMode(.off); + try testing.expect(!t.screen.cursor.pen.attrs.protected); + t.setProtectedMode(.iso); + try testing.expect(t.screen.cursor.pen.attrs.protected); + t.setProtectedMode(.dec); + try testing.expect(t.screen.cursor.pen.attrs.protected); + t.setProtectedMode(.off); + try testing.expect(!t.screen.cursor.pen.attrs.protected); +} diff --git a/src/terminal/ansi.zig b/src/terminal/ansi.zig index 36d3c7361..96f4b9c0a 100644 --- a/src/terminal/ansi.zig +++ b/src/terminal/ansi.zig @@ -111,3 +111,11 @@ pub const ModifyKeyFormat = union(enum) { function_keys: void, other_keys: enum { none, numeric_except, numeric }, }; + +/// The protection modes that can be set for the terminal. See DECSCA and +/// ESC V, W. +pub const ProtectedMode = enum { + off, + iso, // ESC V, W + dec, // CSI Ps " q +}; diff --git a/src/terminal/main.zig b/src/terminal/main.zig index 23b032daf..4e8d3819a 100644 --- a/src/terminal/main.zig +++ b/src/terminal/main.zig @@ -28,6 +28,7 @@ pub const DeviceAttributeReq = ansi.DeviceAttributeReq; pub const DeviceStatusReq = ansi.DeviceStatusReq; pub const Mode = modes.Mode; pub const ModifyKeyFormat = ansi.ModifyKeyFormat; +pub const ProtectedMode = ansi.ProtectedMode; pub const StatusLineType = ansi.StatusLineType; pub const StatusDisplay = ansi.StatusDisplay; pub const EraseDisplay = csi.EraseDisplay;