Example #1
0
        /// <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));
            }
        }
Example #2
0
        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();
            }
        }