input: lot more Kitty encoding logic

This commit is contained in:
Mitchell Hashimoto
2023-08-17 08:55:37 -07:00
parent 91ba53b081
commit fb9dc74b29

View File

@ -41,7 +41,7 @@ pub fn kitty(
const binding_mods = effective_mods.binding();
// Find the entry for this key in the kitty table.
const entry: ?KittyEntry = entry: {
const entry_: ?KittyEntry = entry: {
for (kitty_entries) |entry| {
if (entry.key == self.event.key) break :entry entry;
}
@ -49,11 +49,27 @@ pub fn kitty(
break :entry null;
};
preprocessing: {
// When composing, the only keys sent are plain modifiers.
if (self.event.composing) {
if (entry_) |entry| {
if (entry.modifier) break :preprocessing;
}
return "";
}
// If we're reporting all then we always send CSI sequences.
if (!self.kitty_flags.report_all) {
// Quote:
// The only exceptions are the Enter, Tab and Backspace keys which
// still generate the same bytes as in legacy mode this is to allow the
// user to type and execute commands in the shell such as reset after a
// program that sets this mode crashes without clearing it.
//
// Quote ("report all" mode):
// Note that all keys are reported as escape codes, including Enter,
// Tab, Backspace etc.
if (effective_mods.empty()) {
switch (self.event.key) {
.enter => return try copyToBuf(buf, "\r"),
@ -71,16 +87,37 @@ pub fn kitty(
{
return try copyToBuf(buf, self.event.utf8);
}
}
}
const kitty_mods = KittyMods.fromInput(all_mods);
const final_entry = entry orelse {
const final_entry = entry_ orelse {
// TODO: we need to look it up
return "";
};
_ = kitty_mods;
_ = final_entry;
return "X";
const seq: KittySequence = seq: {
var seq: KittySequence = .{
.key = final_entry.code,
.final = final_entry.final,
.mods = KittyMods.fromInput(all_mods),
};
if (self.kitty_flags.report_events) {
seq.event = switch (self.event.action) {
.press => .press,
.release => .release,
.repeat => .repeat,
};
}
if (self.kitty_flags.report_associated) {
seq.text = self.event.utf8;
}
break :seq seq;
};
return try seq.encode(buf);
}
/// Perform legacy encoding of the key event. "Legacy" in this case
@ -477,9 +514,9 @@ const KittyMods = packed struct(u8) {
const KittySequence = struct {
key: u16,
final: u8,
mods: KittyMods = .{},
event: Event = .none,
alternates: []const u16 = &.{},
mods: KittyMods = .{},
text: []const u8 = "",
/// Values for the event code (see "event-type" in above comment).
@ -701,6 +738,36 @@ test "kitty: enter, backspace, tab" {
}
}
test "kitty: composing with no modifier" {
var buf: [128]u8 = undefined;
var enc: KeyEncoder = .{
.event = .{
.key = .a,
.mods = .{ .shift = true },
.composing = true,
},
.kitty_flags = .{ .disambiguate = true },
};
const actual = try enc.kitty(&buf);
try testing.expectEqualStrings("", actual);
}
test "kitty: composing with modifier" {
var buf: [128]u8 = undefined;
var enc: KeyEncoder = .{
.event = .{
.key = .left_shift,
.mods = .{ .shift = true },
.composing = true,
},
.kitty_flags = .{ .disambiguate = true },
};
const actual = try enc.kitty(&buf);
try testing.expectEqualStrings("\x1b[57441;2u", actual);
}
test "legacy: ctrl+alt+c" {
var buf: [128]u8 = undefined;
var enc: KeyEncoder = .{