key-encode: only set associated text when there is printable text

Associated text should only be sent to the terminal when printable text
is generated from the keypress. Prevent sending associated text when any
modifier is pressed, except for Shift, NumLock, and Capslock

This brings Ghostty inline with the output of Kitty.
This commit is contained in:
Tim Culverhouse
2023-11-24 13:56:47 -06:00
parent 115e8130ba
commit 07e6cf900f

View File

@ -175,7 +175,7 @@ fn kitty(
}
}
if (self.kitty_flags.report_associated) {
if (self.kitty_flags.report_associated and !seq.mods.preventsText()) {
seq.text = self.event.utf8;
}
@ -585,6 +585,19 @@ const KittyMods = packed struct(u8) {
};
}
/// Returns true if the modifiers prevent printable text
pub fn preventsText(self: KittyMods) bool {
if (self.alt or
self.ctrl or
self.super or
self.hyper or
self.meta)
{
return true;
}
return false;
}
/// Returns the raw int value of this packed struct.
pub fn int(self: KittyMods) u8 {
return @bitCast(self);
@ -1167,6 +1180,48 @@ test "kitty: left shift with report all" {
try testing.expectEqualStrings("\x1b[57441u", actual);
}
test "kitty: report associated with modifiers" {
var buf: [128]u8 = undefined;
var enc: KeyEncoder = .{
.event = .{
.key = .j,
.mods = .{ .ctrl = true },
.utf8 = "j",
.unshifted_codepoint = 106,
},
.kitty_flags = .{
.disambiguate = true,
.report_all = true,
.report_alternates = true,
.report_associated = true,
},
};
const actual = try enc.kitty(&buf);
try testing.expectEqualStrings("\x1b[106;5u", actual);
}
test "kitty: report associated" {
var buf: [128]u8 = undefined;
var enc: KeyEncoder = .{
.event = .{
.key = .j,
.mods = .{ .shift = true },
.utf8 = "J",
.unshifted_codepoint = 106,
},
.kitty_flags = .{
.disambiguate = true,
.report_all = true,
.report_alternates = true,
.report_associated = true,
},
};
const actual = try enc.kitty(&buf);
try testing.expectEqualStrings("\x1b[106:74;2;74u", actual);
}
test "kitty: alternates omit control characters" {
var buf: [128]u8 = undefined;
var enc: KeyEncoder = .{