コード例 #1
0
        private List <Token> RemainTokensToArgs(TokenReader reader)
        {
            var result = new List <Token>();

            while (reader.IsRemainToken)
            {
                var current = reader.Get();

                if (current.IsMatchType(TokenType.TargetSelector))
                {
                    if (reader.CheckNext(x => x.IsMatchType(TokenType.OpenSquareBracket)))
                    {
                        reader.Skip(x => x.IsMatchType(TokenType.CloseSquareBracket));
                        reader.MoveNext();
                    }
                }
                else if (current.IsMatchLiteral("minecraft"))
                {
                    if (reader.CheckNext(x => x.IsMatchType(TokenType.Colon)))
                    {
                        reader.MoveNext();
                        if (reader.CheckNext(x => x.IsMatchType(TokenType.Literal)))
                        {
                            current = reader.Get();
                        }
                        else
                        {
                            continue;
                        }
                    }
                }

                result.Add(current);
            }

            return(result);
        }
コード例 #2
0
        private IEnumerable <CompletionData> GetCompletionData(int index, string input)
        {
            if (!HandleInputStrings.Contains(input))
            {
                return(null);
            }

            var block = this._bracketSearcher.SearchCurrentBlock(this.Document, index - 1);

            var bracket = string.Empty;
            var inBlock = TokenType.StringBlock;

            if (block != null)
            {
                bracket = this.Document.GetCharAt(block.OpenBracketOffset).ToString();

                if (bracket == "{")
                {
                    inBlock = TokenType.TagBlock;
                }
                else if (bracket == "[")
                {
                    inBlock = TokenType.ArrayBlock;
                }
            }

            var tokens = this.Text.Tokenize(TokenizeType.All);

            var next = this.NextChar;
            var prev = (this.CaretOffset > 1)
                ? this.Document.GetCharAt(this.CaretOffset - 2)
                : '\0';

            var before = tokens
                         .TakeWhile(x => x.Index < index)
                         .Where(x => !x.IsMatchType(TokenType.Blank));

            var current   = before.LastOrDefault();
            var prevToken = before.SkipLast(1).LastOrDefault();

            if (before.IsEmpty() ||
                current.IsMatchType(TokenType.String, TokenType.Comment))
            {
                return(null);
            }
            if ("\r\n".Contains(input) &&
                (Keyboard.Modifiers & ModifierKeys.Shift) != ModifierKeys.None)
            {
                return(null);
            }

            before = before.Where(x => !x.IsMatchType(TokenType.Comment));

            using (var reader = new TokenReader(before, true))
            {
                try
                {
                    #region コマンド
                    if (inBlock == TokenType.StringBlock)
                    {
                        switch (input.ToLower())
                        {
                        case "/":
                            return(Minecraft.CommandCompletion);

                        case "@":
                            return(Minecraft.SelectorCompletion);

                        case "_":
                            return((inBlock == TokenType.ArrayBlock && current.IsMatchType(TokenType.Literal))
                                    ? (current.Value.IndexOf("score_") == 0)
                                        ? (current.Value == "score_")
                                            ? this.ExtendedOptions.ScoreNames.ToCompletionData()
                                            : new[] { new CompletionData("min") }
                                        : null
                                    : null);
                        }

                        /*
                         * if (!before.Any(x => x.IsMatchType(TokenType.Command)))
                         * {
                         *  return null;
                         * }
                         */

                        var command = reader.SkipGet(x => x.IsMatchType(TokenType.Command) || x.IsMatchLiteral("detect"));
                        if (command.IsEmpty())
                        {
                            return(null);
                        }

                        switch (input.ToLower())
                        {
                        case ":":
                            if (!command.IsEmpty())
                            {
                                if (reader.CheckAt(1, x => x.IsMatchLiteral("minecraft")))
                                {
                                    goto case " ";
                                }
                            }
                            break;

                        case ",":
                            break;

                        case "\r\n":
                        case "\r":
                        case "\n":
                        case " ":
                            if (!command.IsEmpty() && inBlock == TokenType.StringBlock)
                            {
                                reader.Reverse();
                                var args = this.RemainTokensToArgs(reader);
                                var def  = command.IsMatchLiteral("detect")
                                        ? Minecraft.Document.Root.Element("ExCommands").Elements("Command")
                                           .Where(x => x.Attribute("name").Value == command.Value).SingleOrDefault()
                                        : Minecraft.Document.Root.Element("Commands").Elements("Command")
                                           .Where(x => "/" + x.Attribute("name").Value == command.Value).SingleOrDefault();

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

                                var elements = def.Elements("Arg");
                                var element  = null as XElement;

                                foreach (var arg in args)
                                {
                                    if (elements.IsEmpty())
                                    {
                                        return(null);
                                    }
                                    if (elements.Count() > 1)
                                    {
                                        Console.WriteLine(arg.Value);
                                        if (elements.Any(x => x.Attribute("type").Value == "key" && arg.IsMatchLiteral(x.Attribute("key").Value)))
                                        {
                                            elements = elements.Where(x => arg.IsMatchLiteral(x.Attribute("key").Value)).Elements("Arg");
                                        }
                                        else if (elements.Any(x => x.Attributes().Any(a => a.Name == "default" && a.Value == "true")))
                                        {
                                            elements = elements.Where(x => x.Attributes().Any(a => a.Name == "default" && a.Value == "true")).Elements("Arg");
                                        }
                                        else
                                        {
                                            return(null);
                                        }
                                    }
                                    else
                                    {
                                        elements = elements.Elements("Arg");
                                    }
                                }

                                if (elements.Count() > 1)
                                {
                                    if (elements.Any(x => x.Attributes().Any(a => a.Name == "default" && a.Value == "true")))
                                    {
                                        elements = elements.Where(x => x.Attributes().Any(a => a.Name == "default" && a.Value == "true"));
                                    }
                                    else
                                    {
                                        return(elements.Attributes()
                                               .Where(x => x.Name == "key")
                                               .Select(x => new CompletionData(x.Value)));
                                    }
                                }

                                element = elements.SingleOrDefault();
                                if (element == null)
                                {
                                    return(null);
                                }

                                var type = element.Attribute("type").Value;

                                switch (type)
                                {
                                case "key":
                                    return(new[] { new CompletionData(element.Attribute("key").Value) });

                                case "keywords":
                                    return(element.Elements("Word")
                                           .Select(x =>
                                                   new
                                    {
                                        Name = x.Value.Trim(),
                                        Tip = x.Attribute("desc") != null
                                                        ? x.Attribute("desc").Value
                                                        : x.Element("Desc") != null
                                                            ? x.Element("Desc").Value
                                                            : null
                                    })
                                           .Select(x => new CompletionData(x.Name, x.Tip)));

                                case "target":
                                    return(this.ExtendedOptions.PlayerNames.ToCompletionData());

                                case "target_entity":
                                    return(new[] { new CompletionData("@e") });

                                case "score":
                                    return(this.ExtendedOptions.ScoreNames.ToCompletionData());

                                case "team":
                                    return(this.ExtendedOptions.TeamNames.ToCompletionData());

                                case "item":
                                    return(Minecraft.ItemCompletion);

                                case "block":
                                    return(Minecraft.BlockCompletion);

                                case "entity":
                                    return(Minecraft.EntityCompletion);

                                case "effect":
                                    return(prevToken.IsMatchLiteral("minecraft")
                                                ? Minecraft.EffectCompletion
                                                : Minecraft.EffectCompletion
                                           .Concat(new[] { new CompletionData("clear", "すべてのエフェクトを消去します。") }));

                                case "enchant":
                                    return(Minecraft.EnchantCompletion);

                                case "boolean":
                                    return(Minecraft.BooleanCompletion);

                                case "color":
                                    return(Minecraft.ColorCompletion);

                                case "command":
                                    if (command.Value == "/execute" || command.Value == "detect")
                                    {
                                        return(new[] { new CompletionData("detect") }
                                               .Concat(Minecraft.CommandCompletion));
                                    }
                                    return(Minecraft.CommandCompletion);

                                default:
                                    return(null);
                                }
                            }
                            break;
                        }
                    }
                    #endregion
                    #region [ ... ]
                    if (inBlock == TokenType.ArrayBlock)
                    {
                        switch (input)
                        {
                        case "!":
                            if (reader.CheckNext(x => x.IsMatchType(TokenType.Equal)))
                            {
                                reader.MoveNext();
                                goto case "=";
                            }
                            return(null);

                        case "=":
                            if (reader.IsRemainToken)
                            {
                                var selector = before.TakeWhile(x => x.Index < block.OpenBracketOffset).LastOrDefault();
                                if (!selector.IsEmpty() && selector.IsMatchType(TokenType.TargetSelector))
                                {
                                    reader.MoveNext();
                                    if (reader.CheckNext(x => x.IsMatchLiteral("team")))
                                    {
                                        return(this.ExtendedOptions.TeamNames.ToCompletionData());
                                    }
                                    if (reader.CheckNext(x => x.IsMatchLiteral("name")))
                                    {
                                        return(this.ExtendedOptions.PlayerNames.ToCompletionData());
                                    }
                                }
                            }
                            return(null);
                        }
                    }
                    #endregion
                }
                catch
                {
                    return(null);
                }
            }

            return(null);
        }