private void DoSearchInternal(RichCommandLineContext parentContext, IConsoleProvider standaloneConsole, bool allowCancel) { if (parentContext == null && standaloneConsole == null) { throw new ArgumentException("You must specify either parentContext or standaloneConsole"); } else if (parentContext != null && standaloneConsole != null) { throw new ArgumentException("You cannot specify both parentContext and standaloneConsole, you must choose one or the other"); } this.parentReaderContext = parentContext; this.console = parentContext != null ? parentContext.Console : standaloneConsole; this.menuWiper.Console = this.console; this.resultsWiper.Console = this.console; this.expireableAsyncRequestManager = new ExpireableAsyncRequestManager(); SelectedValue = null; this.menuWiper.SetTopLeftFromConsole(); if (allowCancel) { this.console.Write(new ConsoleString("Type to search. Use up/down/enter/escape to navigate/select/cancel: ", ConsoleColor.Cyan)); } else { this.console.Write(new ConsoleString("Type to search. Use up/down/enter to navigate/select: ", ConsoleColor.Cyan)); } this.resultsWiper.SetTopLeftFromConsole(); this.resultsWiper.Left = 0; this.resultsWiper.Top += 2; this.searchReader = new RichTextCommandLineReader() { Console = this.console }; this.searchReader.UnregisterHandler(ConsoleKey.UpArrow); this.searchReader.UnregisterHandler(ConsoleKey.DownArrow); this.searchReader.UnregisterHandler(ConsoleKey.Escape); this.searchReader.UnregisterHandler(ConsoleKey.Enter); this.searchReader.RegisterHandler(KeyHandler.FromAction((searchReaderContext) => { _MoveSelectedIndex(-1); searchReaderContext.Intercept = true; }, ConsoleKey.UpArrow)); this.searchReader.RegisterHandler(KeyHandler.FromAction((_searchReaderContext) => { _searchReaderContext.Intercept = true; _MoveSelectedIndex(1); }, ConsoleKey.DownArrow)); this.searchReader.RegisterHandler(KeyHandler.FromAction((searchReaderContext) => { searchReaderContext.Intercept = true; if (allowCancel) { throw new OperationCanceledException(); } }, ConsoleKey.Escape)); this.searchReader.RegisterHandler(KeyHandler.FromAction((searchReaderContext) => { _SearchReader_HandleEnterKey(searchReaderContext); }, ConsoleKey.Enter)); this.searchReader.AfterReadKey += (searchReaderContext) => { _SearchReader_HandleKeyPressed(searchReaderContext); }; try { this.DoSearch(string.Empty); this.searchReader.ReadLine(); } finally { // This next lione makes sure that we ignore any in flight search calls that come back after we return control of the main // thread. If we didn't do this then the results would get written to the screen even though the search assist code is no // longer running. this.expireableAsyncRequestManager.ExpireAll(); } }
/// <summary> /// Creates a new CLI object. /// </summary> public Cli() { Reader = new RichTextCommandLineReader() { Console = ConsoleProvider.Current }; }
/// <summary> /// Registers a keypress with the editor. /// </summary> /// <param name="key">The key press info</param> /// <param name="prototype">if specified, the foreground and background color will be taken from this prototype, otherwise the system defaults will be used</param> public void RegisterKeyPress(ConsoleKeyInfo key, ConsoleCharacter?prototype = null) { Context.Reset(); Context.KeyPressed = key; Context.CharacterToWrite = new ConsoleCharacter(Context.KeyPressed.KeyChar, prototype.HasValue ? prototype.Value.ForegroundColor : ConsoleString.DefaultForegroundColor, prototype.HasValue ? prototype.Value.BackgroundColor : ConsoleString.DefaultBackgroundColor); IKeyHandler handler = null; if (KeyHandlers.TryGetValue(Context.KeyPressed.Key, out handler) == false && RichTextCommandLineReader.IsWriteable(Context.KeyPressed)) { WriteCharacterForPressedKey(Context); DoSyntaxHighlighting(Context); } else if (handler != null) { handler.Handle(Context); if (Context.Intercept == false && RichTextCommandLineReader.IsWriteable(Context.KeyPressed)) { WriteCharacterForPressedKey(Context); } DoSyntaxHighlighting(Context); } FireValueChanged(); }