Exemple #1
0
        public ConsoleCommand FindSubNodeByName(string name)
        {
            ConsoleCommand found = null;

            foreach (ConsoleCommand sub in SubCommands)
            {
                if (sub.Name == name)
                {
                    found = sub;
                    break;
                }
            }

            return(found);
        }
Exemple #2
0
        /// <summary>
        /// Builds the debugger command tree.
        /// </summary>
        private void BuildCommandTree()
        {
            // Build the flat list which will be built into the tree, by walking
            // the classes that provide the methods
            _commandList = new List <ConsoleCommand>();

            Type[] commandTypes =
            {
                typeof(ConsoleCommands),
                typeof(ConsoleExecutor),
            };

            foreach (Type type in commandTypes)
            {
                foreach (MethodInfo info in type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic))
                {
                    object[] attribs = info.GetCustomAttributes(typeof(ConsoleFunction), true);

                    if (attribs.Length > 1)
                    {
                        throw new InvalidOperationException(String.Format("More than one ConsoleFunction attribute set on {0}", info.Name));
                    }
                    else if (attribs.Length == 1)
                    {
                        // we have a debugger attribute set on this method
                        // this cast should always succeed given that we're filtering for this type above.
                        ConsoleFunction function = (ConsoleFunction)attribs[0];

                        ConsoleCommand newCommand = new ConsoleCommand(function.CommandName, function.Description, function.Usage, info);

                        _commandList.Add(newCommand);
                    }
                }
            }

            // Now actually build the command tree from the above list!
            _commandRoot = new ConsoleCommand("Root", null, null, null);

            foreach (ConsoleCommand c in _commandList)
            {
                string[] commandWords = c.Name.Split(' ');

                // This is kind of ugly, we know that at this point every command built above have only
                // one method.  When building the tree, overloaded commands may end up with more than one.
                _commandRoot.AddSubNode(new List <string>(commandWords), c.Methods[0]);
            }
        }
Exemple #3
0
        private List <MethodInfo> GetMethodsFromCommandString(string command, out string[] args)
        {
            args = null;

            List <string> cmdArgs = SplitArgs(command);

            ConsoleCommand current      = _commandRoot;
            int            commandIndex = 0;

            while (true)
            {
                // If this node has an executor, then we're done
                // (We assume that the tree is correctly built and that only
                // leaves have executors)
                if (current.Methods.Count > 0)
                {
                    break;
                }

                if (commandIndex > cmdArgs.Count - 1)
                {
                    // Out of args!
                    return(null);
                }

                // Otherwise we continue down the tree.
                current = current.FindSubNodeByName(cmdArgs[commandIndex]);
                commandIndex++;

                if (current == null)
                {
                    // If the node was not found, then the command is invalid.
                    return(null);
                }
            }

            //Now current should point to the command with the executor
            //and commandIndex should point to the first argument to the command.

            cmdArgs.RemoveRange(0, commandIndex);

            args = cmdArgs.ToArray();
            return(current.Methods);
        }
Exemple #4
0
        private string FuzzyMatch(ConsoleCommand root, List <string> tokens, bool silent)
        {
            if (tokens.Count == 0)
            {
                if (!silent)
                {
                    // If there are no tokens, just show the completion for the root.
                    PrintCompletions(root.SubCommands);
                }
                return(String.Empty);
            }

            ConsoleCommand match      = null;
            bool           exactMatch = false;

            // Search for exact matches.  If we find one it's guaranteed to be unique
            // so we can follow that node.
            foreach (ConsoleCommand c in root.SubCommands)
            {
                if (c.Name.ToLower() == tokens[0].ToLower())
                {
                    match      = c;
                    exactMatch = true;
                    break;
                }
            }

            if (match == null)
            {
                // No exact match.  Try a substring match.
                // If we have an unambiguous match then we can complete it automatically.
                // If the match is ambiguous, display possible completions and return String.Empty.
                List <ConsoleCommand> completions = new List <ConsoleCommand>();

                foreach (ConsoleCommand c in root.SubCommands)
                {
                    if (c.Name.StartsWith(tokens[0], StringComparison.InvariantCultureIgnoreCase))
                    {
                        completions.Add(c);
                    }
                }

                if (completions.Count == 1)
                {
                    // unambiguous match.  use it.
                    match = completions[0];
                }
                else if (completions.Count > 1)
                {
                    // ambiguous match.  display possible completions.
                    if (!silent)
                    {
                        PrintCompletions(completions);
                    }
                }
            }

            if (match == null)
            {
                // If we reach this point then no matches are available.  return the tokens we have...
                StringBuilder sb = new StringBuilder();
                for (int i = 0; i < tokens.Count; i++)
                {
                    if (i < tokens.Count - 1)
                    {
                        sb.AppendFormat("{0} ", tokens[i]);
                    }
                    else
                    {
                        sb.AppendFormat("{0}", tokens[i]);
                    }
                }

                return(sb.ToString());
            }
            else
            {
                // A match was found
                tokens.RemoveAt(0);

                string subMatch = String.Empty;

                if (tokens.Count > 0)
                {
                    subMatch = FuzzyMatch(match, tokens, silent);
                }
                else if (exactMatch)
                {
                    if (!silent && match.SubCommands.Count > 0)
                    {
                        // Just show the completions for this node.
                        PrintCompletions(match.SubCommands);
                    }
                }

                if (subMatch == String.Empty)
                {
                    return(String.Format("{0} ", match.Name));
                }
                else
                {
                    return(String.Format("{0} {1}", match.Name, subMatch));
                }
            }
        }
Exemple #5
0
 public ConsolePrompt(ConsoleCommand root)
 {
     _commandTree    = root;
     _commandHistory = new List <string>(64);
     _historyIndex   = 0;
 }