diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/Terminal.zig | 11 | ||||
| -rw-r--r-- | src/pardes.zig | 8 | ||||
| -rw-r--r-- | src/tty/tty.zig | 28 |
3 files changed, 43 insertions, 4 deletions
diff --git a/src/Terminal.zig b/src/Terminal.zig index a32819c3..c99a92a6 100644 --- a/src/Terminal.zig +++ b/src/Terminal.zig @@ -1113,6 +1113,11 @@ pub fn forwardKey(p: *Pardes, id: usize, key: Key) void { const pane = p.panes[id] orelse return; const state = pane.terminal orelse return; const input = ghostty_vt.input; + const function_keys = comptime keys: { + var keys: [Key.f25 - Key.f1 + 1]input.Key = undefined; + for (&keys, 1..) |*k, n| k.* = @field(input.Key, std.fmt.comptimePrint("f{d}", .{n})); + break :keys keys; + }; const physical: input.Key = switch (key.cp) { Key.enter => .enter, Key.backspace => .backspace, @@ -1127,6 +1132,12 @@ pub fn forwardKey(p: *Pardes, id: usize, key: Key) void { Key.page_up => .page_up, Key.page_down => .page_down, Key.delete => .delete, + Key.insert => .insert, + Key.print_screen => .print_screen, + Key.scroll_lock => .scroll_lock, + Key.pause => .pause, + Key.menu => .context_menu, + Key.f1...Key.f25 => function_keys[key.cp - Key.f1], else => if (key.cp < 128) input.Key.fromASCII(@intCast(key.cp)) orelse .unidentified else .unidentified, }; var utf8: [4]u8 = undefined; diff --git a/src/pardes.zig b/src/pardes.zig index ae04b4e7..4fb11362 100644 --- a/src/pardes.zig +++ b/src/pardes.zig @@ -3590,6 +3590,14 @@ pub const Key = struct { pub const page_up: u21 = 0xF0007; pub const page_down: u21 = 0xF0008; pub const delete: u21 = 0xF0009; + pub const insert: u21 = 0xF000A; + pub const print_screen: u21 = 0xF000B; + pub const scroll_lock: u21 = 0xF000C; + pub const pause: u21 = 0xF000D; + pub const menu: u21 = 0xF000E; + /// F1 to F25, in order: Fn is `f1 + n - 1`. + pub const f1: u21 = 0xF0011; + pub const f25: u21 = f1 + 24; }; pub fn hit(key: Key, binding: []const config.Chord) bool { diff --git a/src/tty/tty.zig b/src/tty/tty.zig index 206d5c58..01d2f08e 100644 --- a/src/tty/tty.zig +++ b/src/tty/tty.zig @@ -1941,6 +1941,24 @@ fn mapKey(cp: u21) u21 { vaxis.Key.page_up => pardes.Key.page_up, vaxis.Key.page_down => pardes.Key.page_down, vaxis.Key.delete => pardes.Key.delete, + vaxis.Key.insert => pardes.Key.insert, + vaxis.Key.print_screen => pardes.Key.print_screen, + vaxis.Key.scroll_lock => pardes.Key.scroll_lock, + vaxis.Key.pause => pardes.Key.pause, + vaxis.Key.menu => pardes.Key.menu, + vaxis.Key.f1...vaxis.Key.f25 => pardes.Key.f1 + (cp - vaxis.Key.f1), + // The keypad's own keys, which the kitty keyboard protocol tells + // apart, do what the keys they are named for do. + vaxis.Key.kp_left => pardes.Key.left, + vaxis.Key.kp_right => pardes.Key.right, + vaxis.Key.kp_up => pardes.Key.up, + vaxis.Key.kp_down => pardes.Key.down, + vaxis.Key.kp_page_up => pardes.Key.page_up, + vaxis.Key.kp_page_down => pardes.Key.page_down, + vaxis.Key.kp_home => pardes.Key.home, + vaxis.Key.kp_end => pardes.Key.end, + vaxis.Key.kp_insert => pardes.Key.insert, + vaxis.Key.kp_delete => pardes.Key.delete, else => cp, }; } @@ -1966,7 +1984,7 @@ fn keyEvent(key: vaxis.Key) pardes.Event { } }; } -test "keys with no text of their own type nothing into a terminal pane" { +test "a terminal pane gets function keys as their sequences and lone modifiers not at all" { if (comptime builtin.os.tag == .windows) return error.SkipZigTest; const gpa = std.testing.allocator; const io = std.testing.io; @@ -2005,8 +2023,10 @@ test "keys with no text of their own type nothing into a terminal pane" { // Kitty reports Ctrl and Shift pressed on their own: the Ctrl of a // Ctrl-V typed `\x1b[57442;5u` into the shell. "\x1b[57442;5u\x1b[57441;2u\x1b[57358u", - // F3, F5 and Insert, kitty's way and the legacy way. - "\x1b[13~\x1b[15~\x1b[2~\x1bOR", + // F3, F5 and Insert the kitty way, F3 the legacy way and the + // keypad's Up: once typed as private-use junk, now what htop, + // mc and vim read them as. + "\x1b[13~\x1b[15~\x1b[2~\x1bOR\x1b[57419u", "\x1b[104;;104u", }, }; @@ -2024,7 +2044,7 @@ test "keys with no text of their own type nothing into a terminal pane" { while (core.nextEffect()) |effect| { if (effect == .write) try written.writer.writeAll(effect.write.bytes.slice()); } - try std.testing.expectEqualStrings("h", written.written()); + try std.testing.expectEqualStrings("\x1bOR\x1b[15~\x1b[2~\x1bOR\x1b[Ah", written.written()); } test "keypad Enter matches Return for editor input terminal writes and paste" { |
