This commit is contained in:
Jeeves 2024-04-07 14:03:38 -06:00
parent 80f1d8f8a0
commit 8cf18400e2
3 changed files with 297 additions and 60 deletions

View file

@ -200,7 +200,13 @@ pub fn writeString(self: *Self, string: String, writer: anytype, arguments: []co
defer stack.deinit();
var args = try self.allocator.dupe(u32, arguments);
defer self.allocator.free(args);
var state: enum { none, expression, thenpart, elsepart } = .none;
var cond: ?bool = null;
// \E[ %?
// %p1 %{8} %< %t3 %p1 %d
// %e %p1 %{16} %< %t9 %p1 %{8} %- %d %e38;5; %p1 %d
// %; m
var i: usize = 0;
while (i < out.len) {
if (out[i] == '%') {
@ -222,8 +228,102 @@ pub fn writeString(self: *Self, string: String, writer: anytype, arguments: []co
i += 1;
try fmt.format(stack.writer(), "{d}", .{arg});
},
'P' => {},
'g' => {},
'?' => {
std.debug.assert(state == .none);
std.debug.assert(cond == null);
state = .expression;
},
't' => {
std.debug.assert(state == .expression);
std.debug.assert(cond == null);
state = .thenpart;
const res = stack.pop();
cond = res != 0;
if (!cond.?) {
const end_idx = mem.indexOfPos(u8, out, i + 2, "%;");
const else_idx = mem.indexOfPos(u8, out, i + 2, "%e");
if (end_idx) |end| {
if (else_idx) |el| {
if (el < end)
i = el
else
i = end;
} else i = end;
} else return error.InvalidFormatChar;
}
},
'e' => {
std.debug.assert(state == .thenpart);
state = .elsepart;
if (cond.?) {
const end_idx = mem.indexOfPos(u8, out, i + 2, "%;");
if (end_idx) |end| {
i = end;
} else return error.InvalidFormatChar;
}
},
';' => {
std.debug.assert(state == .thenpart or state == .elsepart);
state = .none;
cond = null;
},
'{' => {
const end = mem.indexOfScalarPos(u8, out, i + 2, '}');
if (end) |e| {
const num = try fmt.parseInt(u8, out[i + 2 .. e], 10);
try stack.append(num);
}
},
'+' => {
const a = stack.pop();
const b = stack.pop();
try stack.append(a + b);
},
'-' => {
const a = stack.pop();
const b = stack.pop();
try stack.append(a - b);
},
'*' => {
const a = stack.pop();
const b = stack.pop();
try stack.append(a * b);
},
'/' => {
const a = stack.pop();
const b = stack.pop();
try stack.append(a / b);
},
'm' => {
const a = stack.pop();
const b = stack.pop();
try stack.append(a % b);
},
'=' => {
const a = stack.pop();
const b = stack.pop();
try stack.append(if (a == b) 1 else 0);
},
'>' => {
const a = stack.pop();
const b = stack.pop();
try stack.append(if (a > b) 1 else 0);
},
'<' => {
const a = stack.pop();
const b = stack.pop();
try stack.append(if (a < b) 1 else 0);
},
// '!' => {
// const a = stack.pop();
// try stack.append(!a);
// },
'~' => {
const a = stack.pop();
try stack.append(~a);
},
'i' => {
args[0] += 1;
args[1] += 1;
@ -541,6 +641,41 @@ pub const String = enum {
xon_character,
zero_motion,
alt_scancode_esc,
bit_image_carriage_return,
bit_image_newline,
bit_image_repeat,
char_set_names,
code_set_init,
color_names,
define_bit_image_region,
device_type,
display_pc_char,
end_bit_image_region,
enter_pc_charset_mode,
enter_scancode_mode,
exit_pc_charset_mode,
exit_scancode_mode,
get_mouse,
key_mouse,
mouse_info,
pc_term_options,
pkey_plab,
req_mouse_pos,
scancode_escape,
set0_des_seq,
set1_des_seq,
set2_des_seq,
set3_des_seq,
set_a_background,
set_a_foreground,
set_rgb_background,
set_rgb_foreground,
set_color_band,
set_lr_margin,
set_page_length,
set_tb_margin,
pub fn toCapName(self: String) ?[]const u8 {
return switch (self) {
.acs_chars => "acsc",
@ -632,7 +767,6 @@ pub const String = enum {
.fixed_pause => "pause",
.flash_hook => "hook",
.flash_screen => "flash",
.form_feed => "ff",
.from_status_line => "fsl",
.goto_window => "wingo",
@ -737,6 +871,41 @@ pub const String = enum {
.xoff_character => "xoffc",
.xon_character => "xonc",
.zero_motion => "zerom",
.alt_scancode_esc => "scesa",
.bit_image_carriage_return => "bicr",
.bit_image_newline => "binel",
.bit_image_repeat => "birep",
.char_set_names => "csnm",
.code_set_init => "csin",
.color_names => "colornm",
.define_bit_image_region => "defbi",
.device_type => "devt",
.display_pc_char => "dispt",
.end_bit_image_region => "endbi",
.enter_pc_charset_mode => "smpch",
.enter_scancode_mode => "smsc",
.exit_pc_charset_mode => "rmpch",
.exit_scancode_mode => "rmsc",
.get_mouse => "getm",
.key_mouse => "kmous",
.mouse_info => "minfo",
.pc_term_options => "pctrm",
.pkey_plab => "pfxl",
.req_mouse_pos => "reqmp",
.scancode_escape => "scesc",
.set0_des_seq => "s0ds",
.set1_des_seq => "s1ds",
.set2_des_seq => "s2ds",
.set3_des_seq => "s3ds",
.set_a_background => "setab",
.set_a_foreground => "setaf",
.set_rgb_background => null,
.set_rgb_foreground => null,
.set_color_band => "setcolor",
.set_lr_margin => "smglr",
.set_page_length => "slines",
.set_tb_margin => "smgtb",
// else => "",
};
}
@ -758,12 +927,14 @@ pub const String = enum {
.exit_blink_mode => "\x1b[25m",
.exit_reverse_mode => "\x1b[27m",
.exit_secure_mode => "\x1b[28m",
.set_rgb_background => "\x1b[48;2;%p1%d;%p2%d;%p3%dm",
.set_rgb_foreground => "\x1b[38;2;%p1%d;%p2%d;%p3%dm",
else => null,
};
}
};
test "parse terminfo" {
test "terminfo" {
var terminfo = try parse(std.testing.allocator,
\\# Reconstructed via infocmp from file: /nix/store/c1d0bgq6whz4khqxncmqikpdsxmr1szw-kitty-0.32.2/lib/kitty/terminfo/x/xterm-kitty
\\xterm-kitty|KovIdTTY,
@ -819,4 +990,9 @@ test "parse terminfo" {
\\ u8=\E[?%[;0123456789]c, u9=\E[c, vpa=\E[%i%p1%dd,
);
defer terminfo.deinit();
var output = std.ArrayList(u8).init(std.testing.allocator);
defer output.deinit();
try terminfo.writeString(.set_rgb_foreground, output.writer(), &[_]u32{ 32, 32, 32 });
// std.debug.print("{s}\n", .{output.items[1..]});
}