core: implement legacy SGR sequences and fallbacks

This commit is contained in:
Tim Culverhouse 2024-05-08 13:59:57 -05:00
parent 48a8aa509c
commit bb5d79ef75
3 changed files with 51 additions and 7 deletions

View file

@ -33,7 +33,8 @@ pub fn main() !void {
defer loop.stop(); defer loop.stop();
// Optionally enter the alternate screen // Optionally enter the alternate screen
// try vx.enterAltScreen(); try vx.enterAltScreen();
try vx.queryTerminal();
var nvim = try vaxis.widgets.nvim.Nvim(Event).init(alloc, &loop); var nvim = try vaxis.widgets.nvim.Nvim(Event).init(alloc, &loop);
try nvim.spawn(); try nvim.spawn();

View file

@ -61,6 +61,11 @@ renders: usize = 0,
render_dur: i128 = 0, render_dur: i128 = 0,
render_timer: std.time.Timer, render_timer: std.time.Timer,
sgr: enum {
standard,
legacy,
} = .standard,
/// Initialize Vaxis with runtime options /// Initialize Vaxis with runtime options
pub fn init(alloc: std.mem.Allocator, _: Options) !Vaxis { pub fn init(alloc: std.mem.Allocator, _: Options) !Vaxis {
return .{ return .{
@ -190,6 +195,16 @@ pub fn queryTerminal(self: *Vaxis) !void {
// 1 second timeout // 1 second timeout
std.Thread.Futex.timedWait(&self.query_futex, 0, 1 * std.time.ns_per_s) catch {}; std.Thread.Futex.timedWait(&self.query_futex, 0, 1 * std.time.ns_per_s) catch {};
// Apply any environment variables
if (std.posix.getenv("ASCIINEMA_REC")) |_|
self.sgr = .legacy;
if (std.posix.getenv("VAXIS_FORCE_LEGACY_SGR")) |_|
self.sgr = .legacy;
if (std.posix.getenv("VAXIS_FORCE_WCWIDTH")) |_|
self.caps.unicode = .wcwidth;
if (std.posix.getenv("VAXIS_FORCE_UNICODE")) |_|
self.caps.unicode = .unicode;
// enable detected features // enable detected features
if (self.caps.kitty_keyboard) { if (self.caps.kitty_keyboard) {
try self.enableKittyKeyboard(.{}); try self.enableKittyKeyboard(.{});
@ -350,11 +365,19 @@ pub fn render(self: *Vaxis) !void {
switch (idx) { switch (idx) {
0...7 => try std.fmt.format(writer, ctlseqs.fg_base, .{idx}), 0...7 => try std.fmt.format(writer, ctlseqs.fg_base, .{idx}),
8...15 => try std.fmt.format(writer, ctlseqs.fg_bright, .{idx - 8}), 8...15 => try std.fmt.format(writer, ctlseqs.fg_bright, .{idx - 8}),
else => try std.fmt.format(writer, ctlseqs.fg_indexed, .{idx}), else => {
switch (self.sgr) {
.standard => try std.fmt.format(writer, ctlseqs.fg_indexed, .{idx}),
.legacy => try std.fmt.format(writer, ctlseqs.fg_indexed_legacy, .{idx}),
}
},
} }
}, },
.rgb => |rgb| { .rgb => |rgb| {
try std.fmt.format(writer, ctlseqs.fg_rgb, .{ rgb[0], rgb[1], rgb[2] }); switch (self.sgr) {
.standard => try std.fmt.format(writer, ctlseqs.fg_rgb, .{ rgb[0], rgb[1], rgb[2] }),
.legacy => try std.fmt.format(writer, ctlseqs.fg_rgb_legacy, .{ rgb[0], rgb[1], rgb[2] }),
}
}, },
} }
} }
@ -367,11 +390,19 @@ pub fn render(self: *Vaxis) !void {
switch (idx) { switch (idx) {
0...7 => try std.fmt.format(writer, ctlseqs.bg_base, .{idx}), 0...7 => try std.fmt.format(writer, ctlseqs.bg_base, .{idx}),
8...15 => try std.fmt.format(writer, ctlseqs.bg_bright, .{idx - 8}), 8...15 => try std.fmt.format(writer, ctlseqs.bg_bright, .{idx - 8}),
else => try std.fmt.format(writer, ctlseqs.bg_indexed, .{idx}), else => {
switch (self.sgr) {
.standard => try std.fmt.format(writer, ctlseqs.bg_indexed, .{idx}),
.legacy => try std.fmt.format(writer, ctlseqs.bg_indexed_legacy, .{idx}),
}
},
} }
}, },
.rgb => |rgb| { .rgb => |rgb| {
try std.fmt.format(writer, ctlseqs.bg_rgb, .{ rgb[0], rgb[1], rgb[2] }); switch (self.sgr) {
.standard => try std.fmt.format(writer, ctlseqs.bg_rgb, .{ rgb[0], rgb[1], rgb[2] }),
.legacy => try std.fmt.format(writer, ctlseqs.bg_rgb_legacy, .{ rgb[0], rgb[1], rgb[2] }),
}
}, },
} }
} }
@ -381,10 +412,16 @@ pub fn render(self: *Vaxis) !void {
switch (cell.style.bg) { switch (cell.style.bg) {
.default => _ = try tty.write(ctlseqs.ul_reset), .default => _ = try tty.write(ctlseqs.ul_reset),
.index => |idx| { .index => |idx| {
try std.fmt.format(writer, ctlseqs.ul_indexed, .{idx}); switch (self.sgr) {
.standard => try std.fmt.format(writer, ctlseqs.ul_indexed, .{idx}),
.legacy => try std.fmt.format(writer, ctlseqs.ul_indexed_legacy, .{idx}),
}
}, },
.rgb => |rgb| { .rgb => |rgb| {
try std.fmt.format(writer, ctlseqs.ul_rgb, .{ rgb[0], rgb[1], rgb[2] }); switch (self.sgr) {
.standard => try std.fmt.format(writer, ctlseqs.ul_rgb, .{ rgb[0], rgb[1], rgb[2] }),
.legacy => try std.fmt.format(writer, ctlseqs.ul_rgb_legacy, .{ rgb[0], rgb[1], rgb[2] }),
}
}, },
} }
} }

View file

@ -67,6 +67,12 @@ pub const ul_indexed = "\x1b[58:5:{d}m";
pub const fg_rgb = "\x1b[38:2:{d}:{d}:{d}m"; pub const fg_rgb = "\x1b[38:2:{d}:{d}:{d}m";
pub const bg_rgb = "\x1b[48:2:{d}:{d}:{d}m"; pub const bg_rgb = "\x1b[48:2:{d}:{d}:{d}m";
pub const ul_rgb = "\x1b[58:2:{d}:{d}:{d}m"; pub const ul_rgb = "\x1b[58:2:{d}:{d}:{d}m";
pub const fg_indexed_legacy = "\x1b[38;5;{d}m";
pub const bg_indexed_legacy = "\x1b[48;5;{d}m";
pub const ul_indexed_legacy = "\x1b[58;5;{d}m";
pub const fg_rgb_legacy = "\x1b[38;2;{d};{d};{d}m";
pub const bg_rgb_legacy = "\x1b[48;2;{d};{d};{d}m";
pub const ul_rgb_legacy = "\x1b[58;2;{d};{d};{d}m";
// Underlines // Underlines
pub const ul_off = "\x1b[24m"; // NOTE: this could be \x1b[4:0m but is not as widely supported pub const ul_off = "\x1b[24m"; // NOTE: this could be \x1b[4:0m but is not as widely supported