/// <summary> /// Validates that the user actually specified a value and optionally prompts them when it is missing. /// </summary> /// <param name="argument">The argument being populated. This validator doesn't do anything with it.</param> /// <param name="arg">The value specified on the command line or null if it wasn't specified</param> public override void ValidateAlways(CommandLineArgument argument, ref string arg) { if (IsConditionallyRequired) { var matchingHook = (from h in argument.Metadata.Metas <ArgRequiredConditionalHook>() where h.parent == this select h).SingleOrDefault(); if (matchingHook == null) { argument.Metadata.Add(new ArgRequiredConditionalHook(this)); } } if (IsConditionallyRequired == false && arg == null && PromptIfMissing && ArgHook.HookContext.Current.Definition.IsNonInteractive == false) { var cli = new CliHelper(); ITabCompletionHandler tabHandler; IHighlighterConfigurator highlighterConfigurator; if (TabCompletionHandlerType.TryCreate <ITabCompletionHandler>(out tabHandler)) { cli.Reader.TabHandler.TabCompletionHandlers.Add(tabHandler); } if (HighlighterConfiguratorType.TryCreate <IHighlighterConfigurator>(out highlighterConfigurator)) { cli.Reader.Highlighter = new SimpleSyntaxHighlighter(); highlighterConfigurator.Configure(cli.Reader.Highlighter); } cli.Reader.UnregisterHandler(ConsoleKey.Escape); cli.Reader.RegisterHandler(KeyHandler.FromAction((searchReaderContext) => { TabCompletion tabCompletionInfo; if (ArgHook.HookContext.Current.Definition.IsNonInteractive == false && ArgHook.HookContext.Current.Definition.Metadata.TryGetMeta <TabCompletion>(out tabCompletionInfo) && tabCompletionInfo.REPL == true) { // if this is an interactive REPL then continue the REPL in this case as the user may have changed their mind about taking // this action - Note there are two places in this file that have this logic throw new REPLContinueException(); } else { throw new MissingArgException("The argument '" + argument.DefaultAlias + "' is required", new ArgumentNullException(argument.DefaultAlias)); } }, ConsoleKey.Escape)); arg = cli.PromptForLine("Enter value for " + argument.DefaultAlias); } if (arg == null && IsConditionallyRequired == false) { throw new MissingArgException("The argument '" + argument.DefaultAlias + "' is required", new ArgumentNullException(argument.DefaultAlias)); } }
private bool TryPreventExceptionWithPrompt(ArgHook.HookContext context) { if (parent.PromptIfMissing && ArgHook.HookContext.Current.Definition.IsNonInteractive == false) { var cli = new CliHelper(); ITabCompletionHandler tabHandler; IHighlighterConfigurator highlighterConfigurator; if (TabCompletionHandlerType.TryCreate <ITabCompletionHandler>(out tabHandler)) { cli.Reader.TabHandler.TabCompletionHandlers.Add(tabHandler); } if (HighlighterConfiguratorType.TryCreate <IHighlighterConfigurator>(out highlighterConfigurator)) { cli.Reader.Highlighter = new SimpleSyntaxHighlighter(); highlighterConfigurator.Configure(cli.Reader.Highlighter); } cli.Reader.UnregisterHandler(ConsoleKey.Escape); cli.Reader.RegisterHandler(KeyHandler.FromAction((searchReaderContext) => { TabCompletion tabCompletionInfo; if (context.Definition.IsNonInteractive == false && context.Definition.Metadata.TryGetMeta <TabCompletion>(out tabCompletionInfo) && tabCompletionInfo.REPL == true) { // if this is an interactive REPL then continue the REPL in this case as the user may have changed their mind about taking // this action - Note there are two places in this file that have this logic throw new REPLContinueException(); } else { throw new MissingArgException("The argument '" + context.CurrentArgument.DefaultAlias + "' is required", new ArgumentNullException(context.CurrentArgument.DefaultAlias)); } }, ConsoleKey.Escape)); context.ArgumentValue = cli.PromptForLine("Enter value for " + context.CurrentArgument.DefaultAlias); context.CurrentArgument.Populate(context); var property = context.CurrentArgument.Source as PropertyInfo; if (property != null && context.Args != null) { property.SetValue(context.Args, context.CurrentArgument.RevivedValue, null); } return(true); } else { return(false); } }
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(); } }