From 203895e3f76af0e3f9a8e16778a706d08f6718f1 Mon Sep 17 00:00:00 2001 From: "Jeffrey C. Ollie" Date: Sat, 11 Apr 2026 21:27:18 -0500 Subject: [PATCH] decbkm: address review comments * Don't alter Kitty keyboard protocol responses. Kitty does not support DECBKM so KKP doesn't take DECBKM into consideration. * Make better use of the function key lookup to control what sequence is returned when backspace is pressed using the legacy encoding. --- src/input/function_keys.zig | 7 +++-- src/input/key_encode.zig | 56 +++++++++++++++++++++++++++++++++---- 2 files changed, 55 insertions(+), 8 deletions(-) diff --git a/src/input/function_keys.zig b/src/input/function_keys.zig index efe86d9e3..66ab4bc4d 100644 --- a/src/input/function_keys.zig +++ b/src/input/function_keys.zig @@ -43,6 +43,9 @@ pub const Entry = struct { /// The sequence to send to the pty if this entry matches. sequence: []const u8, + + /// Sequence to send to the PTY if DECBKM is set. + sequence_decbkm: ?[]const u8 = null, }; /// The list of modifier combinations for modify other key sequences. @@ -161,8 +164,8 @@ pub const keys = keys: { .{ .mods = .{ .alt = true, .super = true, .ctrl = true }, .modify_other_keys = .set_other, .sequence = "\x1b[27;15;127~" }, .{ .mods = .{ .alt = true, .super = true, .ctrl = true, .shift = true }, .modify_other_keys = .set_other, .sequence = "\x1b[27;16;127~" }, - .{ .mods = .{ .ctrl = true }, .sequence = "\x08" }, - .{ .sequence = "\x7f" }, + .{ .mods = .{ .ctrl = true }, .sequence = "\x08", .sequence_decbkm = "\x7f" }, + .{ .sequence = "\x7f", .sequence_decbkm = "\x08" }, }); result.set(.tab, &.{ diff --git a/src/input/key_encode.zig b/src/input/key_encode.zig index b939c7fed..dc585d39d 100644 --- a/src/input/key_encode.zig +++ b/src/input/key_encode.zig @@ -189,9 +189,7 @@ fn kitty( switch (event.key) { .enter => return try writer.writeByte('\r'), .tab => return try writer.writeByte('\t'), - .backspace => return try writer.writeByte( - if (opts.backarrow_key_mode) 0x08 else 0x7F, - ), + .backspace => return try writer.writeByte(0x7F), else => {}, } } @@ -664,7 +662,10 @@ fn pcStyleFunctionKey( continue; } - if (keyval == .backspace and backarrow_key_mode) return "\x08"; + decbkm: { + if (!backarrow_key_mode) break :decbkm; + return entry.sequence_decbkm orelse break :decbkm; + } return entry.sequence; } @@ -1267,13 +1268,13 @@ test "kitty: enter, backspace, tab" { try testing.expectEqualStrings("\x7f", writer.buffered()); } { - // DECBKM set + // DECBKM set (Kitty does not support DECBKM so there should be no change) var writer: std.Io.Writer = .fixed(&buf); try kitty(&writer, .{ .key = .backspace, .mods = .{}, .utf8 = "" }, .{ .kitty_flags = .{ .disambiguate = true }, .backarrow_key_mode = true, }); - try testing.expectEqualStrings("\x08", writer.buffered()); + try testing.expectEqualStrings("\x7f", writer.buffered()); } { var writer: std.Io.Writer = .fixed(&buf); @@ -1912,7 +1913,26 @@ test "legacy: backspace with utf8 (dead key state)" { try testing.expectEqualStrings("", writer.buffered()); } +test "kitty: backspace (DECBKM reset) (report_all: true)" { + var buf: [128]u8 = undefined; + var writer: std.Io.Writer = .fixed(&buf); + try kitty(&writer, .{ + .key = .backspace, + }, .{ + .kitty_flags = .{ + .disambiguate = true, + .report_events = true, + .report_alternates = true, + .report_all = true, + .report_associated = true, + }, + .backarrow_key_mode = false, + }); + try testing.expectEqualStrings("\x1b[127u", writer.buffered()); +} + test "kitty: backspace (DECBKM set) (report_all: true)" { + // Kitty does not support DECBKM so there should be no difference. var buf: [128]u8 = undefined; var writer: std.Io.Writer = .fixed(&buf); try kitty(&writer, .{ @@ -2091,6 +2111,18 @@ test "legacy: backspace (DECBKM reset)" { try testing.expectEqualStrings("\x7f", writer.buffered()); } +test "legacy: backspace (DECBKM reset, with ctrl)" { + var buf: [128]u8 = undefined; + var writer: std.Io.Writer = .fixed(&buf); + try legacy(&writer, .{ + .key = .backspace, + .mods = .{ + .ctrl = true, + }, + }, .{ .backarrow_key_mode = false }); + try testing.expectEqualStrings("\x08", writer.buffered()); +} + test "legacy: backspace (DECBKM set)" { var buf: [128]u8 = undefined; var writer: std.Io.Writer = .fixed(&buf); @@ -2101,6 +2133,18 @@ test "legacy: backspace (DECBKM set)" { try testing.expectEqualStrings("\x08", writer.buffered()); } +test "legacy: backspace (DECBKM set, with ctrl)" { + var buf: [128]u8 = undefined; + var writer: std.Io.Writer = .fixed(&buf); + try legacy(&writer, .{ + .key = .backspace, + .mods = .{ + .ctrl = true, + }, + }, .{ .backarrow_key_mode = true }); + try testing.expectEqualStrings("\x7f", writer.buffered()); +} + test "legacy: ctrl+shift+char with modify other state 2" { var buf: [128]u8 = undefined; var writer: std.Io.Writer = .fixed(&buf);