private void ReadOneOrMoreKeys() { _readkeyStopwatch.Restart(); while (_console.KeyAvailable) { // _charMap is only guaranteed to accumulate input while KeyAvailable // returns false. Make sure to check KeyAvailable after every ProcessKey call, // and clear it in a loop in case the input was something like ^[[1 which can // be 3, 2, or part of 1 key depending on timing. _charMap.ProcessKey(_console.ReadKey()); while (_charMap.KeyAvailable) { var key = PSKeyInfo.FromConsoleKeyInfo(_charMap.ReadKey()); _lastNKeys.Enqueue(key); _queuedKeys.Enqueue(key); } if (_readkeyStopwatch.ElapsedMilliseconds > 2) { // Don't spend too long in this loop if there are lots of queued keys break; } } if (_queuedKeys.Count == 0) { while (!_charMap.KeyAvailable) { // Don't want to block when there is an escape sequence being read. if (_charMap.InEscapeSequence) { if (_console.KeyAvailable) { _charMap.ProcessKey(_console.ReadKey()); } else { // We don't want to sleep for the whole escape timeout // or the user will have a laggy console, but there's // nothing to block on at this point either, so do a // small sleep to yield the CPU while we're waiting // to decide what the input was. This will only run // if there are no keys waiting to be read. Thread.Sleep(5); } } else { _charMap.ProcessKey(_console.ReadKey()); } } while (_charMap.KeyAvailable) { var key = PSKeyInfo.FromConsoleKeyInfo(_charMap.ReadKey()); _lastNKeys.Enqueue(key); _queuedKeys.Enqueue(key); } } }
private void CheckEscapeInput(ICharMap map, ConsoleKeyInfo intended, ConsoleKeyInfo[] keys, bool inputOnly = false) { for (int i = 0; i < keys.Length; i++) { map.ProcessKey(keys[i]); if (i < keys.Length - 1) { Assert.AreEqual(false, map.KeyAvailable); } } if (inputOnly) { // Hack to make the map process escapes now. var escapeTimeout = map.EscapeTimeout; map.EscapeTimeout = 0; bool unused = map.KeyAvailable; map.EscapeTimeout = escapeTimeout; return; } Assert.AreEqual(true, map.KeyAvailable); var processedKey = map.ReadKey(); Assert.AreEqual(false, map.KeyAvailable); Assert.AreEqual(intended, processedKey); }
private void CheckPartialEscapeInput(ICharMap map, int expectedCount, ConsoleKeyInfo[] keys) { foreach (var key in keys) { map.ProcessKey(key); Assert.AreEqual(false, map.KeyAvailable); } int keyCount = 0; // Hack to make the map think the timeout is up. var escapeTimeout = map.EscapeTimeout; map.EscapeTimeout = 0; while (map.KeyAvailable) { map.ReadKey(); keyCount++; } Assert.AreEqual(expectedCount, keyCount); map.EscapeTimeout = escapeTimeout; }