void ProcessOneKey(PSKeyInfo key, Dictionary <PSKeyInfo, KeyHandler> dispatchTable, bool ignoreIfNoAction, object arg) { var consoleKey = key.AsConsoleKeyInfo(); // Our dispatch tables are built as much as possible in a portable way, so for example, // we avoid depending on scan codes like ConsoleKey.Oem6 and instead look at the // PSKeyInfo.Key. We also want to ignore the shift state as that may differ on // different keyboard layouts. // // That said, we first look up exactly what we get from Console.ReadKey - that will fail // most of the time, and when it does, we normalize the key. if (!dispatchTable.TryGetValue(key, out var handler)) { // If we see a control character where Ctrl wasn't used but shift was, treat that like // shift hadn't be pressed. This cleanly allows Shift+Backspace without adding a key binding. if (key.Shift && !key.Control && !key.Alt) { var c = consoleKey.KeyChar; if (c != '\0' && char.IsControl(c)) { key = PSKeyInfo.From(consoleKey.Key); dispatchTable.TryGetValue(key, out handler); } } } if (handler != null) { if (handler.ScriptBlock != null) { CallPossibleExternalApplication(() => handler.Action(consoleKey, arg)); } else { handler.Action(consoleKey, arg); } } else if (!ignoreIfNoAction) { SelfInsert(consoleKey, arg); } }
static PSKeyInfo Key(ConsoleKey key) => PSKeyInfo.From(key);
static PSKeyInfo Key(char c) => PSKeyInfo.From(c);