Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions src/XTerm.NET.Tests/Input/KittyKeyboardStateTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,15 @@ public void GenerateKittyKeyInput_honours_MacOptionIsMeta()
Assert.Equal("\u001b[102;3u", t.GenerateKittyKeyInput(ev));
}

[Fact]
public void GenerateKittyKeyInput_unwinds_shifted_punctuation()
{
var t = NewTerminal();
t.Write("\u001b[=9u"); // AllKeys | Disambiguate
var ev = new KeyEvent { Key = "+", Code = "Equal", ShiftKey = true };
Assert.Equal("\u001b[61;2u", t.GenerateKittyKeyInput(ev));
}

[Theory]
[InlineData("Escape", "", "\u001b")]
[InlineData("F13", "", "\u001b[25~")]
Expand Down
42 changes: 42 additions & 0 deletions src/XTerm.NET.Tests/Input/KittyKeyboardTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,48 @@ public void Shifted_key_appears_as_a_sub_parameter()
Assert.Equal("\u001b[53:37;2u", KittyKeyboard.Evaluate(Ev("%", "Digit5", shift: true), AllKeys | Alternates));
}

[Theory]
[InlineData("`", "~", "Backquote")]
[InlineData("-", "_", "Minus")]
[InlineData("=", "+", "Equal")]
[InlineData("[", "{", "BracketLeft")]
[InlineData("]", "}", "BracketRight")]
[InlineData("\\", "|", "Backslash")]
[InlineData(";", ":", "Semicolon")]
[InlineData("'", "\"", "Quote")]
[InlineData(",", "<", "Comma")]
[InlineData(".", ">", "Period")]
[InlineData("/", "?", "Slash")]
public void Shifted_punctuation_appears_as_a_sub_parameter(string unshiftedKey, string shiftedKey, string code)
{
var expected = $"\u001b[{(int)unshiftedKey[0]}:{(int)shiftedKey[0]};2u";
Assert.Equal(expected, KittyKeyboard.Evaluate(Ev(shiftedKey, code, shift: true), AllKeys | Alternates));
}

[Theory]
[InlineData("+", "Equal", "\u001b[61;2u")]
[InlineData(":", "Semicolon", "\u001b[59;2u")]
[InlineData("_", "Minus", "\u001b[45;2u")]
[InlineData("?", "Slash", "\u001b[47;2u")]
public void Shifted_punctuation_unwinds_under_ReportAllKeys(string shiftedKey, string code, string expected)
{
Assert.Equal(expected, KittyKeyboard.Evaluate(Ev(shiftedKey, code, shift: true), AllKeys | Disambiguate));
}

[Theory]
[InlineData("+", "Equal", "\u001b[61:43;6u", "\u001b[61;6u")]
[InlineData(":", "Semicolon", "\u001b[59:58;6u", "\u001b[59;6u")]
[InlineData("_", "Minus", "\u001b[45:95;6u", "\u001b[45;6u")]
[InlineData("?", "Slash", "\u001b[47:63;6u", "\u001b[47;6u")]
public void Ctrl_Shift_punctuation_unwinds_to_base_key_code(
string shiftedKey, string code, string expectedWithAlternates, string expectedDisambiguate)
{
Assert.Equal(expectedWithAlternates,
KittyKeyboard.Evaluate(Ev(shiftedKey, code, ctrl: true, shift: true), Disambiguate | Alternates));
Assert.Equal(expectedDisambiguate,
KittyKeyboard.Evaluate(Ev(shiftedKey, code, ctrl: true, shift: true), Disambiguate));
}

[Fact]
public void Unshifted_and_functional_keys_have_no_alternate()
{
Expand Down
18 changes: 18 additions & 0 deletions src/XTerm.NET/Input/KittyKeyboard.cs
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,24 @@ private static int EncodeModifiers(KeyEvent ev)
}
if (ev.Code.StartsWith("Key", StringComparison.Ordinal) && ev.Code.Length == 4)
return char.ToLowerInvariant(ev.Code[3]);

if (ev.ShiftKey)
{
switch (ev.Code)
{
case "Backquote": return '`';
case "Minus": return '-';
case "Equal": return '=';
case "BracketLeft": return '[';
case "BracketRight": return ']';
case "Backslash": return '\\';
case "Semicolon": return ';';
case "Quote": return '\'';
case "Comma": return ',';
case "Period": return '.';
case "Slash": return '/';
}
}
}

if (ev.Key.Length == 1)
Expand Down
Loading