From b6ac4c764f41db8dfcca4ac8a40053148c30b790 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Thu, 23 Oct 2025 20:15:05 -0700 Subject: [PATCH] terminal: modify_other_keys --- src/terminal/ansi.zig | 21 +++++++++++++++------ src/terminal/stream.zig | 32 ++++++++++++++++++-------------- src/termio/stream_handler.zig | 6 ++---- 3 files changed, 35 insertions(+), 24 deletions(-) diff --git a/src/terminal/ansi.zig b/src/terminal/ansi.zig index 590e9885a..7c18d933e 100644 --- a/src/terminal/ansi.zig +++ b/src/terminal/ansi.zig @@ -1,3 +1,7 @@ +const build_options = @import("terminal_options"); +const lib = @import("../lib/main.zig"); +const lib_target: lib.Target = if (build_options.c_abi) .c else .zig; + /// C0 (7-bit) control characters from ANSI. /// /// This is not complete, control characters are only added to this @@ -95,12 +99,17 @@ pub const StatusDisplay = enum(u16) { /// The possible modify key formats to ESC[>{a};{b}m /// Note: this is not complete, we should add more as we support more -pub const ModifyKeyFormat = union(enum) { - legacy: void, - cursor_keys: void, - function_keys: void, - other_keys: enum { none, numeric_except, numeric }, -}; +pub const ModifyKeyFormat = lib.Enum( + lib_target, + &.{ + "legacy", + "cursor_keys", + "function_keys", + "other_keys_none", + "other_keys_numeric_except", + "other_keys_numeric", + }, +); /// The protection modes that can be set for the terminal. See DECSCA and /// ESC V, W. diff --git a/src/terminal/stream.zig b/src/terminal/stream.zig index 7ecd67750..2c237fbb0 100644 --- a/src/terminal/stream.zig +++ b/src/terminal/stream.zig @@ -73,6 +73,7 @@ pub const Action = union(Key) { reset_mode: Mode, save_mode: Mode, restore_mode: Mode, + modify_key_format: ansi.ModifyKeyFormat, pub const Key = lib.Enum( lib_target, @@ -120,6 +121,7 @@ pub const Action = union(Key) { "reset_mode", "save_mode", "restore_mode", + "modify_key_format", }, ); @@ -1094,18 +1096,18 @@ pub fn Stream(comptime Handler: type) type { } else log.warn("unimplemented CSI callback: {f}", .{input}), 1 => switch (input.intermediates[0]) { - '>' => if (@hasDecl(T, "setModifyKeyFormat")) blk: { + '>' => blk: { if (input.params.len == 0) { // Reset - try self.handler.setModifyKeyFormat(.{ .legacy = {} }); + try self.handler.vt(.modify_key_format, .legacy); break :blk; } var format: ansi.ModifyKeyFormat = switch (input.params[0]) { - 0 => .{ .legacy = {} }, - 1 => .{ .cursor_keys = {} }, - 2 => .{ .function_keys = {} }, - 4 => .{ .other_keys = .none }, + 0 => .legacy, + 1 => .cursor_keys, + 2 => .function_keys, + 4 => .other_keys_none, else => { log.warn("invalid setModifyKeyFormat: {f}", .{input}); break :blk; @@ -1125,15 +1127,17 @@ pub fn Stream(comptime Handler: type) type { .function_keys => {}, // We only support the numeric form. - .other_keys => |*v| switch (input.params[1]) { - 2 => v.* = .numeric, - else => v.* = .none, + .other_keys_none => switch (input.params[1]) { + 2 => format = .other_keys_numeric, + else => {}, }, + .other_keys_numeric_except => {}, + .other_keys_numeric => {}, } } - try self.handler.setModifyKeyFormat(format); - } else log.warn("unimplemented setModifyKeyFormat: {f}", .{input}), + try self.handler.vt(.modify_key_format, format); + }, else => log.warn( "unknown CSI m with intermediate: {}", @@ -1194,13 +1198,13 @@ pub fn Stream(comptime Handler: type) type { 0 => unreachable, // handled above 1 => switch (input.intermediates[0]) { - '>' => if (@hasDecl(T, "setModifyKeyFormat")) { + '>' => { // This isn't strictly correct. CSI > n has parameters that // control what exactly is being disabled. However, we // only support reverting back to modify other keys in // numeric except format. - try self.handler.setModifyKeyFormat(.{ .other_keys = .numeric_except }); - } else log.warn("unimplemented setModifyKeyFormat: {f}", .{input}), + try self.handler.vt(.modify_key_format, .other_keys_numeric_except); + }, else => log.warn( "unknown CSI n with intermediate: {}", diff --git a/src/termio/stream_handler.zig b/src/termio/stream_handler.zig index 226a6fde9..cb78ff264 100644 --- a/src/termio/stream_handler.zig +++ b/src/termio/stream_handler.zig @@ -253,6 +253,7 @@ pub const StreamHandler = struct { const v = self.terminal.modes.restore(value.mode); try self.setMode(value.mode, v); }, + .modify_key_format => try self.setModifyKeyFormat(value), } } @@ -450,10 +451,7 @@ pub const StreamHandler = struct { pub fn setModifyKeyFormat(self: *StreamHandler, format: terminal.ModifyKeyFormat) !void { self.terminal.flags.modify_other_keys_2 = false; switch (format) { - .other_keys => |v| switch (v) { - .numeric => self.terminal.flags.modify_other_keys_2 = true, - else => {}, - }, + .other_keys_numeric => self.terminal.flags.modify_other_keys_2 = true, else => {}, } }