terminal: setAttribute

pull/9342/head
Mitchell Hashimoto 2025-10-24 11:51:30 -07:00
parent 56376a8a38
commit e49694439c
No known key found for this signature in database
GPG Key ID: 523D5DC389D273BC
2 changed files with 18 additions and 21 deletions

View File

@ -124,6 +124,7 @@ pub const Action = union(Key) {
end_of_command: EndOfCommand,
mouse_shape: MouseShape,
configure_charset: ConfigureCharset,
set_attribute: sgr.Attribute,
pub const Key = lib.Enum(
lib_target,
@ -222,6 +223,7 @@ pub const Action = union(Key) {
"end_of_command",
"mouse_shape",
"configure_charset",
"set_attribute",
},
);
@ -231,7 +233,7 @@ pub const Action = union(Key) {
@This(),
// TODO: Before shipping an ABI-compatible libghostty, verify this.
// This was just arbitrarily chosen for now.
[8]u64,
[16]u64,
);
pub const Tag = c_union.Tag;
pub const Value = c_union.Value;
@ -1320,7 +1322,7 @@ pub fn Stream(comptime Handler: type) type {
// SGR - Select Graphic Rendition
'm' => switch (input.intermediates.len) {
0 => if (@hasDecl(T, "setAttribute")) {
0 => {
// log.info("parse SGR params={any}", .{input.params});
var p: sgr.Parser = .{
.params = input.params,
@ -1328,9 +1330,9 @@ pub fn Stream(comptime Handler: type) type {
};
while (p.next()) |attr| {
// log.info("SGR attribute: {}", .{attr});
try self.handler.setAttribute(attr);
try self.handler.vt(.set_attribute, attr);
}
} else log.warn("unimplemented CSI callback: {f}", .{input}),
},
1 => switch (input.intermediates[0]) {
'>' => blk: {
@ -3217,19 +3219,18 @@ test "stream: SGR with 17+ parameters for underline color" {
attrs: ?sgr.Attribute = null,
called: bool = false,
pub fn setAttribute(self: *@This(), attr: sgr.Attribute) !void {
self.attrs = attr;
self.called = true;
}
pub fn vt(
self: *@This(),
comptime action: anytype,
value: anytype,
) !void {
_ = self;
_ = action;
_ = value;
switch (action) {
.set_attribute => {
self.attrs = value;
self.called = true;
},
else => {},
}
}
};

View File

@ -317,6 +317,11 @@ pub const StreamHandler = struct {
.end_of_command => self.endOfCommand(value.exit_code),
.mouse_shape => try self.setMouseShape(value),
.configure_charset => self.configureCharset(value.slot, value.charset),
.set_attribute => switch (value) {
.unknown => |unk| log.warn("unimplemented or unknown SGR attribute: {any}", .{unk}),
else => self.terminal.setAttribute(value) catch |err|
log.warn("error setting attribute {}: {}", .{ value, err }),
},
.dcs_hook => try self.dcsHook(value),
.dcs_put => try self.dcsPut(value),
.dcs_unhook => try self.dcsUnhook(),
@ -716,15 +721,6 @@ pub const StreamHandler = struct {
}
}
pub inline fn setAttribute(self: *StreamHandler, attr: terminal.Attribute) !void {
switch (attr) {
.unknown => |unk| log.warn("unimplemented or unknown SGR attribute: {any}", .{unk}),
else => self.terminal.setAttribute(attr) catch |err|
log.warn("error setting attribute {}: {}", .{ attr, err }),
}
}
inline fn startHyperlink(self: *StreamHandler, uri: []const u8, id: ?[]const u8) !void {
try self.terminal.screen.startHyperlink(uri, id);
}