Example #1
0
        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;
        }