/// <summary>
        /// Reads a line of text from the console and converts it into a string array that has accounted for escape sequences and quoted string literals.
        /// </summary>
        /// <param name="initialBuffer">Optionally seed the prompt with an initial value that the end user can modify</param>
        /// <returns>the command line that was read</returns>
        public string[] ReadCommandLine(ConsoleString initialBuffer = null)
        {
            var line = ReadLine(initialBuffer).ToString();
            var ret  = Args.Convert(line);

            return(ret);
        }
        public static CommandLineArgument FindContextualArgument(FindContextualArgumentArgs args)
        {
            args.Definition = PassThroughOrTryGetAmbientDefinition(args.Definition);

            string currentTokenArgumentNameValue = null;

            if (args.PreviousToken != null && ArgParser.IsDashSpecifiedArgumentIdentifier(args.PreviousToken))
            {
                currentTokenArgumentNameValue = args.PreviousToken.Substring(1);
            }
            else if (args.PreviousToken != null && args.PreviousToken.StartsWith("/"))
            {
                currentTokenArgumentNameValue = args.PreviousToken.Substring(1);
            }
            else
            {
                // strange behavior outside of this method where we need to look back one if the current token has a non whitespace value
                var targetPosition = string.IsNullOrWhiteSpace(args.CurrentToken) ? args.CurrentTokenIndex : args.CurrentTokenIndex - 1;
                if (targetPosition < 0)
                {
                    return(null);
                }
                var positionArg = args.ActionContext == null?
                                  args.Definition.Arguments.Where(a => a.Position == targetPosition).FirstOrDefault() :
                                      args.ActionContext.Arguments.Where(a => a.Position == targetPosition).FirstOrDefault();

                var argsArray = Args.Convert(args.CommandLine);

                if (positionArg == null)
                {
                    return(positionArg);
                }

                for (var i = 0; i < Math.Min(argsArray.Length, targetPosition + 1); i++)
                {
                    // positional args must occur before any named args
                    if (argsArray[i].StartsWith("/") || Regex.IsMatch(argsArray[i], @"^-[^\d]"))
                    {
                        return(null);
                    }
                }

                return(positionArg);
            }

            CommandLineArgument currentTokenArgument = null;

            if (currentTokenArgumentNameValue != null)
            {
                currentTokenArgument = args.Definition.Arguments.Where(arg => arg.IsMatch(currentTokenArgumentNameValue) && arg.ArgumentType != typeof(bool)).SingleOrDefault();

                if (currentTokenArgument == null && args.ActionContext != null)
                {
                    currentTokenArgument = args.ActionContext.Arguments.Where(arg => arg.IsMatch(currentTokenArgumentNameValue) && arg.ArgumentType != typeof(bool)).SingleOrDefault();
                }
            }
            return(currentTokenArgument);
        }
예제 #3
0
        /// <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);
        }