/// <summary> /// Prompts the user to enter a value for the given property in the case that the option was specified with no value /// </summary> /// <param name="context">the parser context</param> public override void BeforePopulateProperty(ArgHook.HookContext context) { if (string.IsNullOrEmpty(context.ArgumentValue)) { do { 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); } var result = cli.PromptForLine("Enter value for " + context.CurrentArgument.DefaultAlias); result = result == "" ? null : result; context.ArgumentValue = result; } while (KeepAsking && context.ArgumentValue == null); } }
/// <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)); } }
/// <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 Cli(); 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); } 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)); } }
/// <summary> /// Before PowerArgs parses the args, this hook inspects the command line for the indicator and if found /// takes over the command line and provides tab completion. /// </summary> /// <param name="context">The context used to inspect the command line arguments.</param> public override void BeforeParse(ArgHook.HookContext context) { if (CompletionSourceType != null && CompletionSourceType.GetInterfaces().Contains(typeof(ITabCompletionSource)) == false && CompletionSourceType.GetInterfaces().Contains(typeof(ISmartTabCompletionSource)) == false) { throw new InvalidArgDefinitionException("Type does not implement ITabCompletionSource or ISmartTabCompletionSource: " + CompletionSourceType.FullName); } if (context.Definition.IsNonInteractive) { this.REPL = false; return; } if (Indicator == "" && context.CmdLineArgs.Length != 0) { this.REPL = false; return; } if (Indicator != "" && (context.CmdLineArgs.Length != 1 || context.CmdLineArgs[0] != Indicator)) { this.REPL = false; return; } if (REPL && ShowREPLWelcome) { ConsoleString.Empty.WriteLine(); var message = REPLWelcomeMessage.Replace("{{Indicator}}", REPLExitIndicator); ConsoleString.WriteLine(message, ConsoleColor.Cyan); ConsoleString.Empty.WriteLine(); ConsoleString.Write(Indicator + "> ", ConsoleColor.Cyan); ShowREPLWelcome = false; } else if (REPL) { ConsoleString.Write(Indicator + "> ", ConsoleColor.Cyan); } else { // This is a little hacky, but I could not find a better way to make the tab completion start on the same lime // as the command line input try { var lastLine = StdConsoleProvider.ReadALineOfConsoleOutput(Console.CursorTop - 1); Console.CursorTop--; Console.WriteLine(lastLine); Console.CursorTop--; Console.CursorLeft = lastLine.Length + 1; } catch (Exception) { Console.WriteLine(); Console.Write(Indicator + "> "); } } PowerArgsRichCommandLineReader reader = new PowerArgsRichCommandLineReader(context.Definition, LoadHistory()); IHighlighterConfigurator customConfigurator; if (HighlighterConfiguratorType.TryCreate <IHighlighterConfigurator>(out customConfigurator)) { customConfigurator.Configure(reader.Highlighter); } var newCommandLineString = reader.ReadLine().ToString(); var newCommandLineArray = Args.Convert(newCommandLineString); if (REPL && newCommandLineArray.Length == 1 && string.Equals(newCommandLineArray[0], REPLExitIndicator, StringComparison.OrdinalIgnoreCase)) { throw new REPLExitException(); } if (REPL && newCommandLineArray.Length == 1 && newCommandLineArray[0] == "cls") { ConsoleProvider.Current.Clear(); throw new REPLContinueException(); } else if (REPL && newCommandLineArray.Length == 0 && string.IsNullOrWhiteSpace(REPLExitIndicator) == false) { throw new REPLContinueException(); } context.CmdLineArgs = newCommandLineArray; AddToHistory(newCommandLineString); }