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); }
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); }