diff --git a/PSReadLine/ConsoleKeyChordConverter.cs b/PSReadLine/ConsoleKeyChordConverter.cs index 6cce52ca..bc33cf70 100644 --- a/PSReadLine/ConsoleKeyChordConverter.cs +++ b/PSReadLine/ConsoleKeyChordConverter.cs @@ -246,17 +246,22 @@ static bool MapKeyChar(string input, ref ConsoleModifiers mods, out ConsoleKey k } if (isCtrl) { - if (keyChar >= 'a' && keyChar <= 'z') + switch (keyChar) { - keyChar = (char)(keyChar - 'a' + 1); - } - else if (keyChar >= 'A' && keyChar <= 'Z') - { - keyChar = (char)(keyChar - 'A' + 1); - } - else - { - keyChar = '\0'; + case var _ when (keyChar >= 'a' && keyChar <= 'z'): + keyChar = (char)(keyChar - 'a' + 1); + break; + case var _ when (keyChar >= 'A' && keyChar <= ']'): + keyChar = (char)(keyChar - 'A' + 1); + break; + case '_': + keyChar = Keys.CtrlUnderbar.KeyChar; + mods |= Keys.CtrlUnderbar.Modifiers; + break; + case '^': + keyChar = Keys.CtrlCaret.KeyChar; + mods |= Keys.CtrlCaret.Modifiers; + break; } } diff --git a/PSReadLine/Keys.cs b/PSReadLine/Keys.cs index 4e51fe09..35dbe8ce 100644 --- a/PSReadLine/Keys.cs +++ b/PSReadLine/Keys.cs @@ -326,6 +326,7 @@ static ConsoleKeyInfo CtrlAlt(char c) public static ConsoleKeyInfo CtrlLBracket = Ctrl('\x1b'); public static ConsoleKeyInfo CtrlBackslash = Ctrl('\x1c'); public static ConsoleKeyInfo CtrlRBracket = Ctrl('\x1d'); + public static ConsoleKeyInfo CtrlCaret = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? CtrlShift('\x1e') : Ctrl('\x1e'); public static ConsoleKeyInfo CtrlUnderbar = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? CtrlShift('\x1f') : Ctrl('\x1f'); public static ConsoleKeyInfo CtrlBackspace = Ctrl(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? '\x7f' : '\x08'); public static ConsoleKeyInfo CtrlDelete = Ctrl(ConsoleKey.Delete); // !Linux @@ -478,13 +479,13 @@ internal static bool IgnoreKeyChar(this ConsoleKeyInfo key) private static ConsoleModifiers NormalizeModifiers(this ConsoleKeyInfo key) { + var keyChar = key.IgnoreKeyChar() ? key.KeyChar : key.NormalizeKeyChar(); var result = key.Modifiers; - if (!char.IsControl(key.KeyChar)) + if (!char.IsControl(keyChar)) { // Ignore Shift state unless it's a control character. result = result & ~ConsoleModifiers.Shift; } - return result; } @@ -537,7 +538,7 @@ internal static int GetNormalizedHashCode(this ConsoleKeyInfo obj) // Because a comparison of two ConsoleKeyInfo objects is a comparison of the // combination of the ConsoleKey and Modifiers, we must combine their hashes. // Note that if the ConsoleKey is default, we must fall back to the KeyChar, - // otherwise every non-special key will compare as the same. + // otherwise every non-special key will compare as the same. int h1 = obj.IgnoreKeyChar() ? obj.Key.GetHashCode() : obj.NormalizeKeyChar().GetHashCode();