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(); } }