From 4cc749faccda67c961d4c6e13d700899a602cd56 Mon Sep 17 00:00:00 2001 From: Yves Biener Date: Wed, 28 May 2025 14:39:27 +0200 Subject: [PATCH] feat(app): read input options correctly --- src/app.zig | 115 +++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 87 insertions(+), 28 deletions(-) diff --git a/src/app.zig b/src/app.zig index e521a60..e482bee 100644 --- a/src/app.zig +++ b/src/app.zig @@ -163,6 +163,9 @@ pub fn App(comptime E: type) type { // Legacy keys // CSI {ABCDEFHPQS} // CSI 1 ; modifier:event_type {ABCDEFHPQS} + var field_iter = std.mem.splitScalar(u8, sequence[2 .. sequence.len - 1], ';'); + _ = field_iter.next(); // skip first field + const key: Key = .{ .cp = switch (final) { 'A' => input.Up, @@ -178,42 +181,77 @@ pub fn App(comptime E: type) type { 'S' => input.F4, else => unreachable, }, + .mod = blk: { + // modifier_mask:event_type + var mod: Key.Modifier = .{}; + const field_buf = field_iter.next() orelse break :blk mod; + var param_iter = std.mem.splitScalar(u8, field_buf, ':'); + const modifier_buf = param_iter.next() orelse unreachable; + const modifier_mask = fmt.parseUnsigned(u8, modifier_buf, 10) catch break :blk mod; + if ((modifier_mask -| 1) & 1 != 0) mod.shift = true; + if ((modifier_mask -| 1) & 2 != 0) mod.alt = true; + if ((modifier_mask -| 1) & 4 != 0) mod.ctrl = true; + break :blk mod; + }, }; this.postEvent(.{ .key = key }); }, + 'Z' => this.postEvent(.{ .key = .{ .cp = input.Tab, .mod = .{ .shift = true } } }), '~' => { // Legacy keys // CSI number ~ // CSI number ; modifier ~ // CSI number ; modifier:event_type ; text_as_codepoint ~ var field_iter = mem.splitScalar(u8, sequence[2 .. sequence.len - 1], ';'); - const number_buf = field_iter.next() orelse unreachable; // always will have one field - const number = fmt.parseUnsigned(u16, number_buf, 10) catch break; const key: Key = .{ - .cp = switch (number) { - 2 => input.Insert, - 3 => input.Delete, - 5 => input.PageUp, - 6 => input.PageDown, - 7 => input.Home, - 8 => input.End, - 11 => input.F1, - 12 => input.F2, - 13 => input.F3, - 14 => input.F4, - 15 => input.F5, - 17 => input.F6, - 18 => input.F7, - 19 => input.F8, - 20 => input.F9, - 21 => input.F10, - 23 => input.F11, - 24 => input.F12, - // 200 => return .{ .event = .paste_start, .n = sequence.len }, - // 201 => return .{ .event = .paste_end, .n = sequence.len }, - 57427 => input.KpBegin, - else => unreachable, + .cp = blk: { + const number_buf = field_iter.next() orelse unreachable; // always will have one field + const number = fmt.parseUnsigned(u16, number_buf, 10) catch break; + break :blk switch (number) { + 2 => input.Insert, + 3 => input.Delete, + 5 => input.PageUp, + 6 => input.PageDown, + 7 => input.Home, + 8 => input.End, + 11 => input.F1, + 12 => input.F2, + 13 => input.F3, + 14 => input.F4, + 15 => input.F5, + 17 => input.F6, + 18 => input.F7, + 19 => input.F8, + 20 => input.F9, + 21 => input.F10, + 23 => input.F11, + 24 => input.F12, + 25 => input.F13, + 26 => input.F14, + 28 => input.F15, + 29 => input.F16, + 31 => input.F17, + 32 => input.F18, + 33 => input.F19, + 34 => input.F20, + // 200 => return .{ .event = .paste_start, .n = sequence.len }, + // 201 => return .{ .event = .paste_end, .n = sequence.len }, + 57427 => input.KpBegin, + else => unreachable, + }; + }, + .mod = blk: { + // modifier_mask:event_type + var mod: Key.Modifier = .{}; + const field_buf = field_iter.next() orelse break :blk mod; + var param_iter = std.mem.splitScalar(u8, field_buf, ':'); + const modifier_buf = param_iter.next() orelse unreachable; + const modifier_mask = fmt.parseUnsigned(u8, modifier_buf, 10) catch break :blk mod; + if ((modifier_mask -| 1) & 1 != 0) mod.shift = true; + if ((modifier_mask -| 1) & 2 != 0) mod.alt = true; + if ((modifier_mask -| 1) & 4 != 0) mod.ctrl = true; + break :blk mod; }, }; this.postEvent(.{ .key = key }); @@ -303,9 +341,29 @@ pub fn App(comptime E: type) type { else => {}, } }, + 0x50 => { + // DCS + }, + 0x58 => { + // SOS + }, + 0x5D => { + // OSC + }, // TODO parse corresponding codes - // 0x5B => parseCsi(input, &self.buf), // CSI see https://github.com/rockorager/libvaxis/blob/main/src/Parser.zig - else => {}, + 0x5F => { + // APC + // parse for kitty graphics capabilities + }, + else => { + // alt + keypress + this.postEvent(.{ + .key = .{ + .cp = buf[1], + .mod = .{ .alt = true }, + }, + }); + }, } } else { const b = buf[0]; @@ -313,7 +371,8 @@ pub fn App(comptime E: type) type { 0x00 => .{ .cp = '@', .mod = .{ .ctrl = true } }, 0x08 => .{ .cp = input.Backspace }, 0x09 => .{ .cp = input.Tab }, - 0x0a, 0x0d => .{ .cp = input.Enter }, + 0x0a => .{ .cp = 'j', .mod = .{ .ctrl = true } }, + 0x0d => .{ .cp = input.Enter }, 0x01...0x07, 0x0b...0x0c, 0x0e...0x1a => .{ .cp = b + 0x60, .mod = .{ .ctrl = true } }, 0x1b => escape: { assert(read_bytes == 1);