Fast and reasonably complete (framebuffer) terminal emulator (Zig fork)

Skip unhandled CSI sequences entirely, stopping at the terminator

fish sends modifyOtherKeys even in TERM=linux, dirtying the prompt

Changed files
+16
src
+15
src/flanterm.c
···
ctx->reverse_video = false;
ctx->dec_private = false;
ctx->insert_mode = false;
ctx->unicode_remaining = 0;
ctx->g_select = 0;
ctx->charsets[0] = CHARSET_DEFAULT;
···
ctx->scroll_enabled = false;
size_t x, y;
ctx->get_cursor_pos(ctx, &x, &y);
switch (c) {
case 'F':
···
case ']':
linux_private_parse(ctx);
break;
}
ctx->scroll_enabled = r;
···
ctx->esc_values[i] = 0;
ctx->esc_values_i = 0;
ctx->rrr = false;
ctx->control_sequence = true;
return;
case '7':
···
ctx->reverse_video = false;
ctx->dec_private = false;
ctx->insert_mode = false;
+
ctx->csi_unhandled = false;
ctx->unicode_remaining = 0;
ctx->g_select = 0;
ctx->charsets[0] = CHARSET_DEFAULT;
···
ctx->scroll_enabled = false;
size_t x, y;
ctx->get_cursor_pos(ctx, &x, &y);
+
+
// CSI sequences are terminated by a byte in [0x40,0x7E]
+
// so skip all bytes until the terminator byte
+
if (ctx->csi_unhandled) {
+
if (c >= 0x40 && c <= 0x7E) {
+
ctx->csi_unhandled = false;
+
goto cleanup;
+
}
+
return;
+
}
switch (c) {
case 'F':
···
case ']':
linux_private_parse(ctx);
break;
+
default:
+
ctx->csi_unhandled = true;
+
return;
}
ctx->scroll_enabled = r;
···
ctx->esc_values[i] = 0;
ctx->esc_values_i = 0;
ctx->rrr = false;
+
ctx->csi_unhandled = false;
ctx->control_sequence = true;
return;
case '7':
+1
src/flanterm_private.h
···
bool reverse_video;
bool dec_private;
bool insert_mode;
uint64_t code_point;
size_t unicode_remaining;
uint8_t g_select;
···
bool reverse_video;
bool dec_private;
bool insert_mode;
+
bool csi_unhandled;
uint64_t code_point;
size_t unicode_remaining;
uint8_t g_select;