public override bool CanAssist(RichCommandLineContext context)
        {
            Providers.Clear();
            Providers.AddRange(standardProviders);

            CommandLineArgument targetArgument = null;

            if (context.PreviousNonWhitespaceToken != null && ArgParser.IsDashSpecifiedArgumentIdentifier(context.PreviousNonWhitespaceToken.Value))
            {
                var candidate = context.PreviousNonWhitespaceToken.Value.Substring(1);
                targetArgument = (from a in Definition.AllGlobalAndActionArguments where a.IsMatch(candidate) select a).SingleOrDefault();
            }

            if (targetArgument != null)
            {
                foreach (var assistant in targetArgument.Metadata.Metas <ArgContextualAssistant>())
                {
                    var dynamicProvider = assistant.GetContextAssistProvider(Definition);
                    Providers.Add(dynamicProvider);
                }
            }

            foreach (var provider in Providers)
            {
                if (provider is PowerArgsContextAwareAssistant)
                {
                    (provider as PowerArgsContextAwareAssistant).TargetArgument = targetArgument;
                }
            }

            var ret = base.CanAssist(context);

            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
        public bool TryComplete(TabCompletionContext context, out string completion)
        {
            var fixedUpCandidate = context.CompletionCandidate;

            if (ArgParser.IsDashSpecifiedArgumentIdentifier(fixedUpCandidate))
            {
                fixedUpCandidate = fixedUpCandidate.Substring(1);
            }
            else if (fixedUpCandidate.StartsWith("/"))
            {
                fixedUpCandidate = fixedUpCandidate.Substring(1);
            }
            else
            {
                completion = null;
                return(false);
            }

            var match = definition.Arguments.Where(arg => arg.IsMatch(fixedUpCandidate)).SingleOrDefault();

            if (match == null)
            {
                foreach (var action in definition.Actions)
                {
                    match = action.Arguments.Where(arg => arg.IsMatch(fixedUpCandidate)).SingleOrDefault();
                    if (match != null)
                    {
                        break;
                    }
                }
            }

            if (match == null)
            {
                completion = null;
                return(false);
            }

            if (match != argument)
            {
                completion = null;
                return(false);
            }

            return(TryComplete(new ArgumentAwareTabCompletionContext()
            {
                InnerContext = context,
                Argument = argument
            }
                               , out completion));
        }
        /// <summary>
        /// A helper that detects the argument represented by the current token given a definition.
        /// </summary>
        /// <param name="contextualAction">An action to inspect for a match if the current token does not match a global argument.  Pass null to only check global arguments.</param>
        /// <param name="currentToken">The token to inspect.  If you pass null you will get null back.</param>
        /// <param name="expectMatchingArg">This will be set to true if the current token starts with a '-' or a '/' meaning that the token was an argument indicator, even if it didn't match an argument in the definition.</param>
        /// <param name="def">The definition to inspect.  If null, the ambient definition will be used.  If there is no ambient definition and null is passed then this method throws a NullReferenceException.</param>
        /// <returns>An argument that is matched by the given token or null if there was no match</returns>
        public static CommandLineArgument FindCurrentTokenArgument(CommandLineAction contextualAction, string currentToken, out bool expectMatchingArg, CommandLineArgumentsDefinition def = null)
        {
            def = PassThroughOrTryGetAmbientDefinition(def);

            if (currentToken == null)
            {
                expectMatchingArg = false;
                return(null);
            }

            string currentTokenArgumentNameValue = null;

            expectMatchingArg = false;
            if (ArgParser.IsDashSpecifiedArgumentIdentifier(currentToken))
            {
                currentTokenArgumentNameValue = currentToken.Substring(1);
                expectMatchingArg             = true;
            }
            else if (currentToken.StartsWith("/"))
            {
                currentTokenArgumentNameValue = currentToken.Substring(1);
                expectMatchingArg             = true;
            }

            CommandLineArgument currentTokenArgument = null;

            if (currentTokenArgumentNameValue != null)
            {
                currentTokenArgument = def.Arguments.Where(arg => arg.IsMatch(currentTokenArgumentNameValue)).SingleOrDefault();

                if (currentTokenArgument == null && contextualAction != null)
                {
                    currentTokenArgument = contextualAction.Arguments.Where(arg => arg.IsMatch(currentTokenArgumentNameValue)).SingleOrDefault();
                }
            }
            return(currentTokenArgument);
        }