Beispiel #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);
                }
            }
        }
Beispiel #2
0
        ConsoleKeyInfo IPSConsoleReadLineMockableMethods.ReadKey()
        {
            var key = Console.ReadKey(true);

            _lastNKeys.Enqueue(key);
            return(key);
        }
Beispiel #3
0
        private string MaybeAddToHistory(string result, List <EditItem> edits, int undoEditIndex, bool readingHistoryFile, bool fromDifferentSession)
        {
            bool addToHistory = !string.IsNullOrWhiteSpace(result) && ((Options.AddToHistoryHandler == null) || Options.AddToHistoryHandler(result));

            if (addToHistory)
            {
                _history.Enqueue(new HistoryItem
                {
                    _line                     = result,
                    _edits                    = edits,
                    _undoEditIndex            = undoEditIndex,
                    _saved                    = readingHistoryFile,
                    _fromDifferentLiveSession = fromDifferentSession,
                });
                _currentHistoryIndex = _history.Count;

                if (_options.HistorySaveStyle == HistorySaveStyle.SaveIncrementally && !readingHistoryFile)
                {
                    IncrementalHistoryWrite();
                }
            }

            // Clear the saved line unless we used AcceptAndGetNext in which
            // case we're really still in middle of history and might want
            // to recall the saved line.
            if (_getNextHistoryIndex == 0)
            {
                _savedCurrentLine._line          = null;
                _savedCurrentLine._edits         = null;
                _savedCurrentLine._undoEditIndex = 0;
            }
            return(result);
        }
Beispiel #4
0
        private string MaybeAddToHistory(
            string result,
            List <EditItem> edits,
            int undoEditIndex,
            bool fromDifferentSession = false,
            bool fromInitialRead      = false)
        {
            var addToHistoryOption = GetAddToHistoryOption(result);

            if (addToHistoryOption != AddToHistoryOption.SkipAdding)
            {
                var fromHistoryFile = fromDifferentSession || fromInitialRead;
                _previousHistoryItem = new HistoryItem
                {
                    CommandLine      = result,
                    _edits           = edits,
                    _undoEditIndex   = undoEditIndex,
                    _editGroupStart  = -1,
                    _saved           = fromHistoryFile,
                    FromOtherSession = fromDifferentSession,
                    FromHistoryFile  = fromInitialRead,
                };

                if (!fromHistoryFile)
                {
                    // Add to the recent history queue, which is used when querying for prediction.
                    _recentHistory.Enqueue(result);
                    // 'MemoryOnly' indicates sensitive content in the command line
                    _previousHistoryItem._sensitive = addToHistoryOption == AddToHistoryOption.MemoryOnly;
                    _previousHistoryItem.StartTime  = DateTime.UtcNow;
                }

                _history.Enqueue(_previousHistoryItem);

                _currentHistoryIndex = _history.Count;

                if (_options.HistorySaveStyle == HistorySaveStyle.SaveIncrementally && !fromHistoryFile)
                {
                    IncrementalHistoryWrite();
                }
            }
            else
            {
                _previousHistoryItem = null;
            }

            // Clear the saved line unless we used AcceptAndGetNext in which
            // case we're really still in middle of history and might want
            // to recall the saved line.
            if (_getNextHistoryIndex == 0)
            {
                ClearSavedCurrentLine();
            }
            return(result);
        }
Beispiel #5
0
        private void ReadOneOrMoreKeys()
        {
            _readkeyStopwatch.Restart();
            while (_console.KeyAvailable)
            {
                var key = _console.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)
            {
                var key = _console.ReadKey();
                _lastNKeys.Enqueue(key);
                _queuedKeys.Enqueue(key);
            }
        }
Beispiel #6
0
        private void SetOptionsInternal(SetPSReadlineOption options)
        {
            if (options.ContinuationPrompt != null)
            {
                Options.ContinuationPrompt = options.ContinuationPrompt;
            }
            if (options._continuationPromptForegroundColor.HasValue)
            {
                Options.ContinuationPromptForegroundColor = options.ContinuationPromptForegroundColor;
            }
            if (options._continuationPromptBackgroundColor.HasValue)
            {
                Options.ContinuationPromptBackgroundColor = options.ContinuationPromptBackgroundColor;
            }
            if (options._emphasisBackgroundColor.HasValue)
            {
                Options.EmphasisBackgroundColor = options.EmphasisBackgroundColor;
            }
            if (options._emphasisForegroundColor.HasValue)
            {
                Options.EmphasisForegroundColor = options.EmphasisForegroundColor;
            }
            if (options._errorBackgroundColor.HasValue)
            {
                Options.ErrorBackgroundColor = options.ErrorBackgroundColor;
            }
            if (options._errorForegroundColor.HasValue)
            {
                Options.ErrorForegroundColor = options.ErrorForegroundColor;
            }
            if (options._historyNoDuplicates.HasValue)
            {
                Options.HistoryNoDuplicates = options.HistoryNoDuplicates;
            }
            if (options._historySearchCursorMovesToEnd.HasValue)
            {
                Options.HistorySearchCursorMovesToEnd = options.HistorySearchCursorMovesToEnd;
            }
            if (options._addToHistoryHandlerSpecified)
            {
                Options.AddToHistoryHandler = options.AddToHistoryHandler;
            }
            if (options._commandValidationHandlerSpecified)
            {
                Options.CommandValidationHandler = options.CommandValidationHandler;
            }
            if (options._maximumHistoryCount.HasValue)
            {
                Options.MaximumHistoryCount = options.MaximumHistoryCount;
                if (_history != null)
                {
                    var newHistory = new HistoryQueue <HistoryItem>(Options.MaximumHistoryCount);
                    while (_history.Count > Options.MaximumHistoryCount)
                    {
                        _history.Dequeue();
                    }
                    while (_history.Count > 0)
                    {
                        newHistory.Enqueue(_history.Dequeue());
                    }
                    _history             = newHistory;
                    _currentHistoryIndex = _history.Count;
                }
            }
            if (options._maximumKillRingCount.HasValue)
            {
                Options.MaximumKillRingCount = options.MaximumKillRingCount;
                // TODO - make _killRing smaller
            }
            if (options._editMode.HasValue)
            {
                Options.EditMode = options.EditMode;

                // Switching/resetting modes - clear out chord dispatch table
                _chordDispatchTable.Clear();

                SetDefaultBindings(Options.EditMode);
            }
            if (options._showToolTips.HasValue)
            {
                Options.ShowToolTips = options.ShowToolTips;
            }
            if (options._extraPromptLineCount.HasValue)
            {
                Options.ExtraPromptLineCount = options.ExtraPromptLineCount;
            }
            if (options._dingTone.HasValue)
            {
                Options.DingTone = options.DingTone;
            }
            if (options._dingDuration.HasValue)
            {
                Options.DingDuration = options.DingDuration;
            }
            if (options._bellStyle.HasValue)
            {
                Options.BellStyle = options.BellStyle;
            }
            if (options._completionQueryItems.HasValue)
            {
                Options.CompletionQueryItems = options.CompletionQueryItems;
            }
            if (options.WordDelimiters != null)
            {
                Options.WordDelimiters = options.WordDelimiters;
            }
            if (options._historySearchCaseSensitive.HasValue)
            {
                Options.HistorySearchCaseSensitive = options.HistorySearchCaseSensitive;
            }
            if (options._historySaveStyle.HasValue)
            {
                Options.HistorySaveStyle = options.HistorySaveStyle;
            }
            #region vi
            if (options._viModeIndicator.HasValue)
            {
                Options.ViModeIndicator = options.ViModeIndicator;
            }
            #endregion
            if (options.HistorySavePath != null)
            {
                Options.HistorySavePath = options.HistorySavePath;
                if (_historyFileMutex != null)
                {
                    _historyFileMutex.Dispose();
                }
                _historyFileMutex         = new Mutex(false, GetHistorySaveFileMutexName());
                _historyFileLastSavedSize = 0;
            }
            if (options.ResetTokenColors)
            {
                Options.ResetColors();
            }
            if (options._tokenKind.HasValue)
            {
                if (options._foregroundColor.HasValue)
                {
                    Options.SetForegroundColor(options.TokenKind, options.ForegroundColor);
                }
                if (options._backgroundColor.HasValue)
                {
                    Options.SetBackgroundColor(options.TokenKind, options.BackgroundColor);
                }
            }
        }
Beispiel #7
0
        private void SetOptionsInternal(SetPSReadLineOption options)
        {
            if (options.ContinuationPrompt != null)
            {
                Options.ContinuationPrompt = options.ContinuationPrompt;
            }
            if (options._historyNoDuplicates.HasValue)
            {
                Options.HistoryNoDuplicates = options.HistoryNoDuplicates;
            }
            if (options._historySearchCursorMovesToEnd.HasValue)
            {
                Options.HistorySearchCursorMovesToEnd = options.HistorySearchCursorMovesToEnd;
            }
            if (options._addToHistoryHandlerSpecified)
            {
                Options.AddToHistoryHandler = options.AddToHistoryHandler;
            }
            if (options._commandValidationHandlerSpecified)
            {
                Options.CommandValidationHandler = options.CommandValidationHandler;
            }
            if (options._maximumHistoryCount.HasValue)
            {
                Options.MaximumHistoryCount = options.MaximumHistoryCount;
                if (_history != null)
                {
                    var newHistory = new HistoryQueue <HistoryItem>(Options.MaximumHistoryCount);
                    while (_history.Count > Options.MaximumHistoryCount)
                    {
                        _history.Dequeue();
                    }
                    while (_history.Count > 0)
                    {
                        newHistory.Enqueue(_history.Dequeue());
                    }
                    _history             = newHistory;
                    _currentHistoryIndex = _history.Count;
                }
            }
            if (options._maximumKillRingCount.HasValue)
            {
                Options.MaximumKillRingCount = options.MaximumKillRingCount;
                // TODO - make _killRing smaller
            }
            if (options._editMode.HasValue)
            {
                Options.EditMode = options.EditMode;

                // Switching/resetting modes - clear out chord dispatch table
                _chordDispatchTable.Clear();

                SetDefaultBindings(Options.EditMode);
            }
            if (options._showToolTips.HasValue)
            {
                Options.ShowToolTips = options.ShowToolTips;
            }
            if (options._extraPromptLineCount.HasValue)
            {
                Options.ExtraPromptLineCount = options.ExtraPromptLineCount;
            }
            if (options._dingTone.HasValue)
            {
                Options.DingTone = options.DingTone;
            }
            if (options._dingDuration.HasValue)
            {
                Options.DingDuration = options.DingDuration;
            }
            if (options._bellStyle.HasValue)
            {
                Options.BellStyle = options.BellStyle;
            }
            if (options._completionQueryItems.HasValue)
            {
                Options.CompletionQueryItems = options.CompletionQueryItems;
            }
            if (options.WordDelimiters != null)
            {
                Options.WordDelimiters = options.WordDelimiters;
            }
            if (options._historySearchCaseSensitive.HasValue)
            {
                Options.HistorySearchCaseSensitive = options.HistorySearchCaseSensitive;
            }
            if (options._historySaveStyle.HasValue)
            {
                Options.HistorySaveStyle = options.HistorySaveStyle;
            }
            if (options._viModeIndicator.HasValue)
            {
                Options.ViModeIndicator = options.ViModeIndicator;
            }
            if (options.ViModeChangeHandler != null)
            {
                if (Options.ViModeIndicator != ViModeStyle.Script)
                {
                    throw new ParameterBindingException("ViModeChangeHandler option requires ViModeStyle.Script");
                }
                Options.ViModeChangeHandler = options.ViModeChangeHandler;
            }
            if (options.HistorySavePath != null)
            {
                Options.HistorySavePath = options.HistorySavePath;
                _historyFileMutex?.Dispose();
                _historyFileMutex         = new Mutex(false, GetHistorySaveFileMutexName());
                _historyFileLastSavedSize = 0;
            }
            if (options._ansiEscapeTimeout.HasValue)
            {
                Options.AnsiEscapeTimeout = options.AnsiEscapeTimeout;
            }
            if (options.PromptText != null)
            {
                Options.PromptText = options.PromptText;
            }
            if (options.Colors != null)
            {
                IDictionaryEnumerator e = options.Colors.GetEnumerator();
                while (e.MoveNext())
                {
                    if (e.Key is string property)
                    {
                        Options.SetColor(property, e.Value);
                    }
                }
            }
        }
Beispiel #8
0
        private string MaybeAddToHistory(
            string result,
            List <EditItem> edits,
            int undoEditIndex,
            bool fromDifferentSession = false,
            bool fromInitialRead      = false)
        {
            bool AddToHistory(string line)
            {
                // Whitespace only is useless, never add.
                if (string.IsNullOrWhiteSpace(line))
                {
                    return(false);
                }

                // If the user says don't add it, then don't.
                if (Options.AddToHistoryHandler != null && !Options.AddToHistoryHandler(result))
                {
                    return(false);
                }

                // Under "no dupes" (which is on by default), immediately drop dupes of the previous line.
                if (Options.HistoryNoDuplicates && _history.Count > 0)
                {
                    return(!string.Equals(_history[_history.Count - 1].CommandLine, result, StringComparison.Ordinal));
                }

                return(true);
            }

            if (AddToHistory(result))
            {
                var fromHistoryFile = fromDifferentSession || fromInitialRead;
                _previousHistoryItem = new HistoryItem
                {
                    CommandLine      = result,
                    _edits           = edits,
                    _undoEditIndex   = undoEditIndex,
                    _saved           = fromHistoryFile,
                    FromOtherSession = fromDifferentSession,
                    FromHistoryFile  = fromInitialRead,
                };
                if (!fromHistoryFile)
                {
                    _previousHistoryItem.StartTime = DateTime.UtcNow;
                }

                _history.Enqueue(_previousHistoryItem);


                _currentHistoryIndex = _history.Count;

                if (_options.HistorySaveStyle == HistorySaveStyle.SaveIncrementally && !fromHistoryFile)
                {
                    IncrementalHistoryWrite();
                }
            }
            else
            {
                _previousHistoryItem = null;
            }

            // Clear the saved line unless we used AcceptAndGetNext in which
            // case we're really still in middle of history and might want
            // to recall the saved line.
            if (_getNextHistoryIndex == 0)
            {
                _savedCurrentLine.CommandLine    = null;
                _savedCurrentLine._edits         = null;
                _savedCurrentLine._undoEditIndex = 0;
            }
            return(result);
        }
Beispiel #9
0
        private void SetOptionsInternal(SetPSReadLineOption options)
        {
            if (options.ContinuationPrompt != null)
            {
                Options.ContinuationPrompt = options.ContinuationPrompt;
            }
            if (options._historyNoDuplicates.HasValue)
            {
                Options.HistoryNoDuplicates = options.HistoryNoDuplicates;
            }
            if (options._historySearchCursorMovesToEnd.HasValue)
            {
                Options.HistorySearchCursorMovesToEnd = options.HistorySearchCursorMovesToEnd;
            }
            if (options._addToHistoryHandlerSpecified)
            {
                Options.AddToHistoryHandler = options.AddToHistoryHandler;
            }
            if (options._commandValidationHandlerSpecified)
            {
                Options.CommandValidationHandler = options.CommandValidationHandler;
            }
            if (options._maximumHistoryCount.HasValue)
            {
                Options.MaximumHistoryCount = options.MaximumHistoryCount;
                if (_history != null)
                {
                    var newHistory = new HistoryQueue <HistoryItem>(Options.MaximumHistoryCount);
                    while (_history.Count > Options.MaximumHistoryCount)
                    {
                        _history.Dequeue();
                    }
                    while (_history.Count > 0)
                    {
                        newHistory.Enqueue(_history.Dequeue());
                    }
                    _history             = newHistory;
                    _currentHistoryIndex = _history.Count;
                }
            }
            if (options._maximumKillRingCount.HasValue)
            {
                Options.MaximumKillRingCount = options.MaximumKillRingCount;
                // TODO - make _killRing smaller
            }
            if (options._editMode.HasValue)
            {
                Options.EditMode = options.EditMode;

                // Switching/resetting modes - clear out chord dispatch table
                _chordDispatchTable.Clear();

                SetDefaultBindings(Options.EditMode);
            }
            if (options._showToolTips.HasValue)
            {
                Options.ShowToolTips = options.ShowToolTips;
            }
            if (options._extraPromptLineCount.HasValue)
            {
                Options.ExtraPromptLineCount = options.ExtraPromptLineCount;
            }
            if (options._dingTone.HasValue)
            {
                Options.DingTone = options.DingTone;
            }
            if (options._dingDuration.HasValue)
            {
                Options.DingDuration = options.DingDuration;
            }
            if (options._bellStyle.HasValue)
            {
                Options.BellStyle = options.BellStyle;
            }
            if (options._completionQueryItems.HasValue)
            {
                Options.CompletionQueryItems = options.CompletionQueryItems;
            }
            if (options.WordDelimiters != null)
            {
                Options.WordDelimiters = options.WordDelimiters;
            }
            if (options._historySearchCaseSensitive.HasValue)
            {
                Options.HistorySearchCaseSensitive = options.HistorySearchCaseSensitive;
            }
            if (options._historySaveStyle.HasValue)
            {
                Options.HistorySaveStyle = options.HistorySaveStyle;
            }
            if (options._viModeIndicator.HasValue)
            {
                Options.ViModeIndicator = options.ViModeIndicator;
            }
            if (options.ViModeChangeHandler != null)
            {
                if (Options.ViModeIndicator != ViModeStyle.Script)
                {
                    throw new ParameterBindingException("ViModeChangeHandler option requires ViModeStyle.Script");
                }
                Options.ViModeChangeHandler = options.ViModeChangeHandler;
            }
            if (options.HistorySavePath != null)
            {
                Options.HistorySavePath = options.HistorySavePath;
                _historyFileMutex?.Dispose();
                _historyFileMutex         = new Mutex(false, GetHistorySaveFileMutexName());
                _historyFileLastSavedSize = 0;
            }
            if (options._ansiEscapeTimeout.HasValue)
            {
                Options.AnsiEscapeTimeout = options.AnsiEscapeTimeout;
            }
            if (options.PromptText != null)
            {
                Options.PromptText = options.PromptText;
            }
            if (options._predictionSource.HasValue)
            {
                if (_console is PlatformWindows.LegacyWin32Console && options.PredictionSource != PredictionSource.None)
                {
                    throw new ArgumentException(PSReadLineResources.PredictiveSuggestionNotSupported);
                }

                bool notTest = ReferenceEquals(_mockableMethods, this);
                if ((options.PredictionSource & PredictionSource.Plugin) != 0 && Environment.Version.Major < 5 && notTest)
                {
                    throw new ArgumentException(PSReadLineResources.PredictionPluginNotSupported);
                }

                Options.PredictionSource = options.PredictionSource;
            }
            if (options._predictionViewStyle.HasValue)
            {
                WarnWhenWindowSizeTooSmallForView(options.PredictionViewStyle, options);
                Options.PredictionViewStyle = options.PredictionViewStyle;
                _prediction.SetViewStyle(options.PredictionViewStyle);
            }
            if (options.Colors != null)
            {
                IDictionaryEnumerator e = options.Colors.GetEnumerator();
                while (e.MoveNext())
                {
                    if (e.Key is string property)
                    {
                        Options.SetColor(property, e.Value);
                    }
                }
            }
        }