// Returns the first command that starts with the entered argument
        public static AutoCompleteResults GetAutoComplete(string commandStart)
        {
            if (commandStart.IndexOf(' ') != -1)
            {
                return(GetAutoCompleteParameters(commandStart));
            }
            AutoCompleteResults results = new AutoCompleteResults();

            foreach (var entry in methods)
            {
                if (entry.Key.StartsWith(commandStart))
                {
                    results.options.Add(entry.Key);
                }
            }
            if (results.options.Count == 0)
            {
                results.error = "Command not found: " + commandStart;
                return(results);
            }
            if (results.options.Count == 1)
            {
                results.replacement = results.options[0] + " ";
            }
            else
            {
                results.replacement = CommonPrefix(results.options);
            }
            return(results);
        }
        public static AutoCompleteResults GetAutoCompleteParameters(string commandStart)
        {
            AutoCompleteResults results       = new AutoCompleteResults();
            ParsedCommand       parsedCommand = ParseCommand(commandStart);

            if (parsedCommand.error != null)
            {
                results.error = parsedCommand.error;
                return(results);
            }
            Debug.Log("Usage: " + parsedCommand.methodInfo.signature);
            if (parsedCommand.arguments.Count > parsedCommand.methodInfo.parameterTypes.Length)
            {
                results.error = "Too many parameters";
                return(results);
            }
            int argIndex = Math.Max(0, parsedCommand.arguments.Count - 1) +
                           (parsedCommand.endsWithSpace ? 1 : 0);

            if (argIndex >= parsedCommand.methodInfo.parameterTypes.Length)
            {
                return(results);
            }
            Type type = parsedCommand.methodInfo.parameterTypes[argIndex];

            if (suggestFunctions.TryGetValue(type, out SuggestFunction suggestFunction))
            {
                string prefix = parsedCommand.arguments.Count > argIndex ?
                                parsedCommand.arguments[argIndex] : "";
                if (suggestFunction(prefix, out List <string> suggestions))
                {
                    if (suggestions.Count == 0)
                    {
                        results.error = "Parameter not found: " + prefix;
                        return(results);
                    }
                    suggestions.Sort();
                    results.options.Add(suggestions[0]);
                    for (int i = 1; i < suggestions.Count; i++)
                    {
                        if (suggestions[i] != suggestions[i - 1])
                        {
                            results.options.Add(suggestions[i]);
                        }
                    }
                    string suggestionPrefix = CommonPrefix(results.options);
                    int    argStart         = prefix == "" ? commandStart.Length - 1:
                                              commandStart.LastIndexOf(prefix) - 1;
                    int delim = IndexOfDelimiter(commandStart[argStart]);
                    if (delim != -1)
                    {
                        argStart--;
                    }
                    else if (suggestionPrefix.IndexOf(' ') != -1)
                    {
                        delim = IndexOfDelimiter('\"');
                    }
                    if (delim != -1)
                    {
                        suggestionPrefix = inputDelimiters[delim][0] + suggestionPrefix;
                    }
                    results.replacement = commandStart.Substring(0, argStart + 1) + suggestionPrefix;
                    if (results.options.Count == 1)
                    {
                        results.replacement += (delim != -1 ? inputDelimiters[delim][1] + " " : " ");
                    }
                }
            }
            return(results);
        }