Skip to content

Commit

Permalink
Remove GetCharFromConsoleKey
Browse files Browse the repository at this point in the history
The ConsoleKey enum does not necessarily cover all possible chars.
Moreover, the times we need to obtain this info, we already have it.
  • Loading branch information
andyleejordan committed Jul 29, 2016
1 parent 5fca605 commit 75b0864
Show file tree
Hide file tree
Showing 2 changed files with 5 additions and 50 deletions.
52 changes: 4 additions & 48 deletions src/Microsoft.PowerShell.PSReadLine/ConsoleKeyChordConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ private static ConsoleKeyInfo ConvertOneSequence(string sequence)
Stack<string> tokens = null;
ConsoleModifiers modifiers = 0;
ConsoleKey key = 0;
char keyChar = '\u0000';

bool valid = !String.IsNullOrEmpty(sequence);

Expand All @@ -81,6 +82,9 @@ private static ConsoleKeyInfo ConvertOneSequence(string sequence)
// key should be first token to be popped
if (key == 0)
{
// the keyChar is this token
keyChar = token[0];

// Enum.TryParse accepts arbitrary integers. We shouldn't,
// but single digits need to map to the correct key, e.g.
// ConsoleKey.D1
Expand Down Expand Up @@ -152,8 +156,6 @@ private static ConsoleKeyInfo ConvertOneSequence(string sequence)
throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, PSReadLineResources.InvalidSequence, sequence));
}

char keyChar = GetCharFromConsoleKey(key, modifiers);

return new ConsoleKeyInfo(keyChar, key,
shift: ((modifiers & ConsoleModifiers.Shift) != 0),
alt: ((modifiers & ConsoleModifiers.Alt) != 0),
Expand Down Expand Up @@ -209,51 +211,5 @@ private static bool TryParseCharLiteral(char literal, ref ConsoleModifiers modif

return valid;
}

internal static char GetCharFromConsoleKey(ConsoleKey key, ConsoleModifiers modifiers)
{
// default for unprintables and unhandled
char keyChar = '\u0000';
#if UNIX
Type keyType = typeof (Keys);
FieldInfo[] keyFields = keyType.GetFields();

foreach (FieldInfo field in keyFields)
{
if (field.FieldType == typeof(ConsoleKeyInfo))
{
ConsoleKeyInfo info = (ConsoleKeyInfo)field.GetValue(null);
if (info.Key == key && info.Modifiers == modifiers)
{
return info.KeyChar;
}
}
}
#else
// emulate GetKeyboardState bitmap - set high order bit for relevant modifier virtual keys
var state = new byte[256];
state[NativeMethods.VK_SHIFT] = (byte)(((modifiers & ConsoleModifiers.Shift) != 0) ? 0x80 : 0);
state[NativeMethods.VK_CONTROL] = (byte)(((modifiers & ConsoleModifiers.Control) != 0) ? 0x80 : 0);
state[NativeMethods.VK_ALT] = (byte)(((modifiers & ConsoleModifiers.Alt) != 0) ? 0x80 : 0);

// a ConsoleKey enum's value is a virtual key code
uint virtualKey = (uint)key;

// get corresponding scan code
uint scanCode = NativeMethods.MapVirtualKey(virtualKey, NativeMethods.MAPVK_VK_TO_VSC);

// get corresponding character - maybe be 0, 1 or 2 in length (diacriticals)
var chars = new char[2];
int charCount = NativeMethods.ToUnicode(
virtualKey, scanCode, state, chars, chars.Length, NativeMethods.MENU_IS_INACTIVE);

// TODO: support diacriticals (charCount == 2)
if (charCount == 1)
{
keyChar = chars[0];
}
#endif
return keyChar;
}
}
}
3 changes: 1 addition & 2 deletions src/Microsoft.PowerShell.PSReadLine/ConsoleLib.cs
Original file line number Diff line number Diff line change
Expand Up @@ -404,8 +404,7 @@ public static string ToGestureString(this ConsoleKeyInfo key)
sb.Append(key.Key);
}
#else
char c = ConsoleKeyChordConverter.GetCharFromConsoleKey(key.Key,
(mods & ConsoleModifiers.Shift) != 0 ? ConsoleModifiers.Shift : 0);
char c = key.KeyChar;
if (char.IsControl(c) || char.IsWhiteSpace(c))
{
if (key.Modifiers.HasFlag(ConsoleModifiers.Shift))
Expand Down

0 comments on commit 75b0864

Please sign in to comment.