From a1734d9904f6e794a7787c0709c7891ea789cb8e Mon Sep 17 00:00:00 2001 From: Svdex Date: Sun, 28 Dec 2025 07:53:19 +0700 Subject: [PATCH 01/13] Add feature rule id store --- handlers/feature_rule.go | 10 ++++++++++ stores/symbol.go | 1 + 2 files changed, 11 insertions(+) diff --git a/handlers/feature_rule.go b/handlers/feature_rule.go index 9e3c108..ecf1a31 100644 --- a/handlers/feature_rule.go +++ b/handlers/feature_rule.go @@ -10,6 +10,16 @@ import ( var FeatureRule = &JsonHandler{ Pattern: shared.FeatureRuleGlob, Entries: []JsonEntry{ + { + Store: stores.FeatureRuleId.Source, + Path: []shared.JsonPath{shared.JsonValue("minecraft:feature_rules/description/identifier")}, + Source: func(ctx *JsonContext) []core.Symbol { + return stores.FeatureRuleId.References.Get() + }, + References: func(ctx *JsonContext) []core.Symbol { + return stores.FeatureRuleId.Source.Get() + }, + }, { Store: stores.FeatureId.References, Path: []shared.JsonPath{shared.JsonValue("minecraft:feature_rules/description/places_feature")}, diff --git a/stores/symbol.go b/stores/symbol.go index 29fdfc7..b9ddb9c 100644 --- a/stores/symbol.go +++ b/stores/symbol.go @@ -100,6 +100,7 @@ var ( EntityEvent = NewSymbolBinding(nil) EntityFamily = NewSymbolBinding(vanilla.TypeFamily) FeatureId = NewSymbolBinding(vanilla.FeatureId) + FeatureRuleId = NewSymbolBinding(nil) ItemCustomComponent = NewSymbolBinding(nil) ItemId = NewSymbolBinding(vanilla.ItemId) // Blocks are contained within the "block" scope ItemTag = NewSymbolBinding(vanilla.ItemTag) From 3f484a46bee7222214b178568239c5e994a6274c Mon Sep 17 00:00:00 2001 From: Svdex Date: Sun, 28 Dec 2025 09:12:19 +0700 Subject: [PATCH 02/13] Add recipe id store --- handlers/recipe.go | 13 +++++++++++++ stores/symbol.go | 1 + 2 files changed, 14 insertions(+) diff --git a/handlers/recipe.go b/handlers/recipe.go index b0fcb19..93467c7 100644 --- a/handlers/recipe.go +++ b/handlers/recipe.go @@ -9,6 +9,19 @@ import ( var Recipe = &JsonHandler{ Pattern: shared.RecipeGlob, Entries: []JsonEntry{ + { + Store: stores.RecipeId.Source, + Path: []shared.JsonPath{ + shared.JsonValue("minecraft:recipe_shaped/description/identifier"), + shared.JsonValue("minecraft:recipe_shapeless/description/identifier"), + }, + Source: func(ctx *JsonContext) []core.Symbol { + return stores.RecipeId.References.Get() + }, + References: func(ctx *JsonContext) []core.Symbol { + return stores.RecipeId.Source.Get() + }, + }, { Store: stores.ItemId.References, Path: []shared.JsonPath{ diff --git a/stores/symbol.go b/stores/symbol.go index b9ddb9c..d7ff301 100644 --- a/stores/symbol.go +++ b/stores/symbol.go @@ -104,6 +104,7 @@ var ( ItemCustomComponent = NewSymbolBinding(nil) ItemId = NewSymbolBinding(vanilla.ItemId) // Blocks are contained within the "block" scope ItemTag = NewSymbolBinding(vanilla.ItemTag) + RecipeId = NewSymbolBinding(vanilla.RecipeId) RecipeTag = NewSymbolBinding(vanilla.RecipeTag) WorldgenProcessor = NewSymbolBinding(vanilla.WorldgenProcessorId) WorldgenTemplatePool = NewSymbolBinding(vanilla.WorldgenTemplatePoolId) From 7c30e6370c756b332afcc3d044f90529d92e4c88 Mon Sep 17 00:00:00 2001 From: Svdex Date: Tue, 30 Dec 2025 19:51:40 +0700 Subject: [PATCH 03/13] Fix jsonc wildcards matching --- internal/jsonc/path.go | 11 +++++++---- internal/jsonc/path_test.go | 2 ++ 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/internal/jsonc/path.go b/internal/jsonc/path.go index 3148841..9486a59 100644 --- a/internal/jsonc/path.go +++ b/internal/jsonc/path.go @@ -32,12 +32,15 @@ func (path Path) Matches(pattern Path) bool { return true } - // Attempt to find a matching segment for the next part of the path after "**" - for pathIndex < len(path) && path[pathIndex] != pattern[patternIndex+1] { + // Try to match the rest of the pattern starting from the current pathIndex + patternIndex++ + for pathIndex <= len(path) { + if path[pathIndex:].Matches(pattern[patternIndex:]) { + return true + } pathIndex++ } - patternIndex++ - continue + return false } // Match current segment if pattern[patternIndex] == "*" || path[pathIndex] == pattern[patternIndex] { diff --git a/internal/jsonc/path_test.go b/internal/jsonc/path_test.go index fcfcc1a..49f0c10 100644 --- a/internal/jsonc/path_test.go +++ b/internal/jsonc/path_test.go @@ -21,4 +21,6 @@ func TestPathMatches(t *testing.T) { assertPath(t, jsonc.NewPath("a/b/c"), jsonc.NewPath("b/**"), false) assertPath(t, jsonc.NewPath("a/b/c"), jsonc.NewPath("**/c"), true) assertPath(t, jsonc.NewPath("a/b/c"), jsonc.NewPath("**/d"), false) + assertPath(t, jsonc.NewPath("rawtext/0"), jsonc.NewPath("**/rawtext/*"), true) + assertPath(t, jsonc.NewPath("rawtext/0/with/rawtext/0"), jsonc.NewPath("**/rawtext/*"), true) } From 332ea8e95ee940cd0b480e7542e91cb9d4d804c1 Mon Sep 17 00:00:00 2001 From: Svdex Date: Wed, 31 Dec 2025 01:25:32 +0700 Subject: [PATCH 04/13] Add base mcfunction handler --- handlers/handler_command.go | 1028 +++++++++++ handlers/handler_json_rawmessage.go | 44 + handlers/handler_json_snippet.go | 58 + handlers/handlers.go | 1 + handlers/mcfunction.go | 20 + internal/mcfunction/lexer/lexer.go | 316 ++++ internal/mcfunction/lexer/state.go | 14 + internal/mcfunction/lexer/token.go | 46 + internal/mcfunction/node.go | 106 ++ internal/mcfunction/node_arg.go | 89 + internal/mcfunction/node_arg_chain.go | 120 ++ internal/mcfunction/node_arg_pair.go | 207 +++ internal/mcfunction/node_command.go | 79 + internal/mcfunction/overload_state.go | 365 ++++ internal/mcfunction/parser.go | 159 ++ internal/mcfunction/selector_arg.go | 107 ++ internal/mcfunction/spec.go | 107 ++ internal/mcfunction/util.go | 27 + internal/mcfunction/vanilla/aimassist.go | 63 + internal/mcfunction/vanilla/camera.go | 1531 +++++++++++++++++ internal/mcfunction/vanilla/camerashake.go | 61 + internal/mcfunction/vanilla/clear.go | 35 + .../mcfunction/vanilla/clearspawnpoint.go | 19 + internal/mcfunction/vanilla/clone.go | 75 + internal/mcfunction/vanilla/commands.go | 72 + internal/mcfunction/vanilla/controlscheme.go | 47 + internal/mcfunction/vanilla/damage.go | 94 + internal/mcfunction/vanilla/daylock.go | 20 + internal/mcfunction/vanilla/dialogue.go | 56 + internal/mcfunction/vanilla/difficulty.go | 40 + internal/mcfunction/vanilla/effect.go | 137 ++ internal/mcfunction/vanilla/enchant.go | 89 + internal/mcfunction/vanilla/event.go | 28 + internal/mcfunction/vanilla/execute.go | 464 +++++ internal/mcfunction/vanilla/fill.go | 142 ++ internal/mcfunction/vanilla/fog.go | 51 + internal/mcfunction/vanilla/function.go | 19 + internal/mcfunction/vanilla/gamemode.go | 53 + internal/mcfunction/vanilla/gamerule.go | 85 + internal/mcfunction/vanilla/gametest.go | 165 ++ internal/mcfunction/vanilla/give.go | 38 + internal/mcfunction/vanilla/hud.go | 46 + .../mcfunction/vanilla/inputpermission.go | 71 + internal/mcfunction/vanilla/kill.go | 19 + internal/mcfunction/vanilla/locate.go | 43 + internal/mcfunction/vanilla/loot.go | 835 +++++++++ internal/mcfunction/vanilla/me.go | 19 + internal/mcfunction/vanilla/mobevent.go | 29 + internal/mcfunction/vanilla/music.go | 121 ++ internal/mcfunction/vanilla/op.go | 18 + internal/mcfunction/vanilla/particle.go | 24 + internal/mcfunction/vanilla/place.go | 131 ++ internal/mcfunction/vanilla/playanimation.go | 46 + internal/mcfunction/vanilla/playsound.go | 44 + internal/mcfunction/vanilla/recipe.go | 48 + internal/mcfunction/vanilla/reload.go | 20 + internal/mcfunction/vanilla/replaceitem.go | 188 ++ internal/mcfunction/vanilla/ride.go | 129 ++ internal/mcfunction/vanilla/say.go | 19 + internal/mcfunction/vanilla/schedule.go | 304 ++++ internal/mcfunction/vanilla/scoreboard.go | 308 ++++ internal/mcfunction/vanilla/script.go | 122 ++ internal/mcfunction/vanilla/scriptevent.go | 23 + internal/mcfunction/vanilla/setblock.go | 53 + internal/mcfunction/vanilla/setmaxplayers.go | 18 + internal/mcfunction/vanilla/setworldspawn.go | 19 + internal/mcfunction/vanilla/spawnpoint.go | 24 + internal/mcfunction/vanilla/spreadplayers.go | 51 + internal/mcfunction/vanilla/stopsound.go | 24 + internal/mcfunction/vanilla/structure.go | 216 +++ internal/mcfunction/vanilla/summon.go | 133 ++ internal/mcfunction/vanilla/tag.go | 41 + internal/mcfunction/vanilla/teleport.go | 214 +++ internal/mcfunction/vanilla/tell.go | 23 + internal/mcfunction/vanilla/tellraw.go | 22 + internal/mcfunction/vanilla/testfor.go | 18 + internal/mcfunction/vanilla/testforblock.go | 29 + internal/mcfunction/vanilla/testforblocks.go | 32 + internal/mcfunction/vanilla/tickingarea.go | 167 ++ internal/mcfunction/vanilla/time.go | 75 + internal/mcfunction/vanilla/title.go | 95 + internal/mcfunction/vanilla/titleraw.go | 94 + internal/mcfunction/vanilla/toggledownfall.go | 13 + internal/mcfunction/vanilla/weather.go | 33 + internal/mcfunction/vanilla/xp.go | 37 + stores/path.go | 1 + stores/symbol.go | 4 + 87 files changed, 10320 insertions(+) create mode 100644 handlers/handler_command.go create mode 100644 handlers/handler_json_rawmessage.go create mode 100644 handlers/handler_json_snippet.go create mode 100644 handlers/mcfunction.go create mode 100644 internal/mcfunction/lexer/lexer.go create mode 100644 internal/mcfunction/lexer/state.go create mode 100644 internal/mcfunction/lexer/token.go create mode 100644 internal/mcfunction/node.go create mode 100644 internal/mcfunction/node_arg.go create mode 100644 internal/mcfunction/node_arg_chain.go create mode 100644 internal/mcfunction/node_arg_pair.go create mode 100644 internal/mcfunction/node_command.go create mode 100644 internal/mcfunction/overload_state.go create mode 100644 internal/mcfunction/parser.go create mode 100644 internal/mcfunction/selector_arg.go create mode 100644 internal/mcfunction/spec.go create mode 100644 internal/mcfunction/util.go create mode 100644 internal/mcfunction/vanilla/aimassist.go create mode 100644 internal/mcfunction/vanilla/camera.go create mode 100644 internal/mcfunction/vanilla/camerashake.go create mode 100644 internal/mcfunction/vanilla/clear.go create mode 100644 internal/mcfunction/vanilla/clearspawnpoint.go create mode 100644 internal/mcfunction/vanilla/clone.go create mode 100644 internal/mcfunction/vanilla/commands.go create mode 100644 internal/mcfunction/vanilla/controlscheme.go create mode 100644 internal/mcfunction/vanilla/damage.go create mode 100644 internal/mcfunction/vanilla/daylock.go create mode 100644 internal/mcfunction/vanilla/dialogue.go create mode 100644 internal/mcfunction/vanilla/difficulty.go create mode 100644 internal/mcfunction/vanilla/effect.go create mode 100644 internal/mcfunction/vanilla/enchant.go create mode 100644 internal/mcfunction/vanilla/event.go create mode 100644 internal/mcfunction/vanilla/execute.go create mode 100644 internal/mcfunction/vanilla/fill.go create mode 100644 internal/mcfunction/vanilla/fog.go create mode 100644 internal/mcfunction/vanilla/function.go create mode 100644 internal/mcfunction/vanilla/gamemode.go create mode 100644 internal/mcfunction/vanilla/gamerule.go create mode 100644 internal/mcfunction/vanilla/gametest.go create mode 100644 internal/mcfunction/vanilla/give.go create mode 100644 internal/mcfunction/vanilla/hud.go create mode 100644 internal/mcfunction/vanilla/inputpermission.go create mode 100644 internal/mcfunction/vanilla/kill.go create mode 100644 internal/mcfunction/vanilla/locate.go create mode 100644 internal/mcfunction/vanilla/loot.go create mode 100644 internal/mcfunction/vanilla/me.go create mode 100644 internal/mcfunction/vanilla/mobevent.go create mode 100644 internal/mcfunction/vanilla/music.go create mode 100644 internal/mcfunction/vanilla/op.go create mode 100644 internal/mcfunction/vanilla/particle.go create mode 100644 internal/mcfunction/vanilla/place.go create mode 100644 internal/mcfunction/vanilla/playanimation.go create mode 100644 internal/mcfunction/vanilla/playsound.go create mode 100644 internal/mcfunction/vanilla/recipe.go create mode 100644 internal/mcfunction/vanilla/reload.go create mode 100644 internal/mcfunction/vanilla/replaceitem.go create mode 100644 internal/mcfunction/vanilla/ride.go create mode 100644 internal/mcfunction/vanilla/say.go create mode 100644 internal/mcfunction/vanilla/schedule.go create mode 100644 internal/mcfunction/vanilla/scoreboard.go create mode 100644 internal/mcfunction/vanilla/script.go create mode 100644 internal/mcfunction/vanilla/scriptevent.go create mode 100644 internal/mcfunction/vanilla/setblock.go create mode 100644 internal/mcfunction/vanilla/setmaxplayers.go create mode 100644 internal/mcfunction/vanilla/setworldspawn.go create mode 100644 internal/mcfunction/vanilla/spawnpoint.go create mode 100644 internal/mcfunction/vanilla/spreadplayers.go create mode 100644 internal/mcfunction/vanilla/stopsound.go create mode 100644 internal/mcfunction/vanilla/structure.go create mode 100644 internal/mcfunction/vanilla/summon.go create mode 100644 internal/mcfunction/vanilla/tag.go create mode 100644 internal/mcfunction/vanilla/teleport.go create mode 100644 internal/mcfunction/vanilla/tell.go create mode 100644 internal/mcfunction/vanilla/tellraw.go create mode 100644 internal/mcfunction/vanilla/testfor.go create mode 100644 internal/mcfunction/vanilla/testforblock.go create mode 100644 internal/mcfunction/vanilla/testforblocks.go create mode 100644 internal/mcfunction/vanilla/tickingarea.go create mode 100644 internal/mcfunction/vanilla/time.go create mode 100644 internal/mcfunction/vanilla/title.go create mode 100644 internal/mcfunction/vanilla/titleraw.go create mode 100644 internal/mcfunction/vanilla/toggledownfall.go create mode 100644 internal/mcfunction/vanilla/weather.go create mode 100644 internal/mcfunction/vanilla/xp.go diff --git a/handlers/handler_command.go b/handlers/handler_command.go new file mode 100644 index 0000000..1123f73 --- /dev/null +++ b/handlers/handler_command.go @@ -0,0 +1,1028 @@ +package handlers + +import ( + "log" + "slices" + "strings" + + mapset "github.com/deckarep/golang-set/v2" + "github.com/rockide/language-server/core" + "github.com/rockide/language-server/internal/mcfunction" + "github.com/rockide/language-server/internal/protocol" + "github.com/rockide/language-server/internal/protocol/semtok" + "github.com/rockide/language-server/internal/sliceutil" + "github.com/rockide/language-server/internal/textdocument" + "github.com/rockide/language-server/shared" + "github.com/rockide/language-server/stores" +) + +type CommandHandler struct { + Pattern shared.Pattern + Parser *mcfunction.Parser + EscapeQuotes bool +} + +func (h *CommandHandler) GetPattern() shared.Pattern { + return h.Pattern +} + +func (h *CommandHandler) Parse(uri protocol.DocumentURI) error { + if strings.HasSuffix(uri.Path(), ".mcfunction") { + stores.McFunctionPath.Insert(h.Pattern, uri) + } + document, err := textdocument.GetOrReadFile(uri) + if err != nil { + return err + } + content := document.GetContent() + root, _ := h.Parser.Parse(content) + mcfunction.WalkNodeTree(root, func(i mcfunction.INode) bool { + arg, ok := i.(mcfunction.INodeArg) + if !ok { + return true + } + param, ok := arg.ArgParamSpec() + if !ok { + return true + } + for _, tag := range param.Tags { + entry, ok := commandEntries[tag] + if !ok || entry.Store == nil { + continue + } + scope := defaultScope + if entry.Scope != nil { + scope = entry.Scope(i) + } + s, e := i.Range() + entry.Store.Insert(scope, core.Symbol{ + URI: uri, + Value: arg.Text(content), + Range: &protocol.Range{ + Start: document.PositionAt(s), + End: document.PositionAt(e), + }, + }) + } + return true + }) + return nil +} + +func (h *CommandHandler) Delete(uri protocol.DocumentURI) { + if strings.HasSuffix(uri.Path(), ".mcfunction") { + stores.McFunctionPath.Delete(uri) + } + for _, entry := range commandEntries { + if entry.Store != nil { + entry.Store.Delete(uri) + } + } +} + +func (h *CommandHandler) Completions(document *textdocument.TextDocument, position protocol.Position) []protocol.CompletionItem { + result := []protocol.CompletionItem{} + context := h.parseLine(document, position) + root := context.Root + rOffset := context.RelativeOffset + startOffset := context.StartOffset + line := context.Content + + node := mcfunction.NodeAt(root, rOffset) + rStart, rEnd := node.Range() + cursorRange := protocol.Range{ + Start: position, + End: position, + } + nodeRange := protocol.Range{ + Start: document.PositionAt(startOffset + rStart), + End: document.PositionAt(startOffset + rEnd), + } + switch node.Kind() { + case mcfunction.NodeKindFile: + result = h.commandCompletions(cursorRange) + case mcfunction.NodeKindCommandLit: + result = h.commandCompletions(nodeRange) + case mcfunction.NodeKindCommandArg: + arg, ok := node.(mcfunction.INodeArg) + if ok { + switch arg.ParamKind() { + case mcfunction.ParameterKindSelectorArg: + for k := range mcfunction.SelectorArg { + result = append(result, protocol.CompletionItem{ + Label: k, + Kind: protocol.FieldCompletion, + TextEdit: &protocol.Or_CompletionItem_textEdit{ + Value: protocol.TextEdit{ + NewText: k, + Range: cursorRange, + }, + }, + }) + } + return result + case mcfunction.ParameterKindRawMessage: + doc := document.CreateVirtualDocument(nodeRange) + rawMessage.CommandHandler = h + return rawMessage.Completions(doc, position) + case mcfunction.ParameterKindItemNbt: + doc := document.CreateVirtualDocument(nodeRange) + return itemNbt.Completions(doc, position) + } + } + invalid := node.Parent().Kind() == mcfunction.NodeKindInvalidCommand + if _, ok := node.(mcfunction.INodeCommand); invalid || !ok { + root, _ := h.Parser.Parse(line[:rStart]) + n := mcfunction.NodeAt(root, rStart) + if n, ok := n.(mcfunction.INodeCommand); ok { + node = n + cursorRange = nodeRange + } + } + fallthrough + case mcfunction.NodeKindCommand: + nodeCommand, ok := node.(mcfunction.INodeCommand) + if !ok { + log.Printf("Failed to cast node to INodeCommand") + return result + } + result = h.paramCompletions(nodeCommand, cursorRange) + } + return result +} + +func (h *CommandHandler) commandCompletions(editRange protocol.Range) []protocol.CompletionItem { + result := []protocol.CompletionItem{} + set := mapset.NewThreadUnsafeSet[string]() + for name, spec := range h.Parser.RegisteredCommands() { + if set.Contains(name) { + continue + } + set.Add(name) + result = append(result, protocol.CompletionItem{ + Label: name, + Detail: spec.Description, + Kind: protocol.MethodCompletion, + TextEdit: &protocol.Or_CompletionItem_textEdit{ + Value: protocol.TextEdit{ + NewText: name, + Range: editRange, + }, + }, + }) + } + return result +} + +func (h *CommandHandler) paramCompletions(node mcfunction.INodeCommand, editRange protocol.Range) []protocol.CompletionItem { + result := []protocol.CompletionItem{} + set := mapset.NewThreadUnsafeSet[string]() + escape := func(s string) string { + if strings.ContainsAny(s, " /.") { + s = `"` + s + `"` + } + if h.EscapeQuotes { + s = strings.ReplaceAll(s, `"`, `\"`) + } + return s + } + addItem := func(value string, kind ...protocol.CompletionItemKind) { + if set.Contains(value) { + return + } + set.Add(value) + var k protocol.CompletionItemKind + if len(kind) > 0 { + k = kind[0] + } + result = append(result, protocol.CompletionItem{ + Label: value, + Kind: k, + TextEdit: &protocol.Or_CompletionItem_textEdit{ + Value: protocol.TextEdit{ + NewText: value, + Range: editRange, + }, + }, + }) + } + var addCompletions func(param mcfunction.ParameterSpec) + addCompletions = func(param mcfunction.ParameterSpec) { + if len(param.Literals) > 0 { + for _, lit := range param.Literals { + addItem(escape(lit), protocol.KeywordCompletion) + } + } + switch param.Kind { + case mcfunction.ParameterKindNumber: + addItem("0.0") + case mcfunction.ParameterKindInteger: + addItem("0") + case mcfunction.ParameterKindBoolean: + addItem("true", protocol.KeywordCompletion) + addItem("false", protocol.KeywordCompletion) + case mcfunction.ParameterKindSelector: + for sel, ok := range h.Parser.GetSelectors() { + if ok { + addItem("@" + sel) + } + } + case mcfunction.ParameterKindMap: + result = append(result, protocol.CompletionItem{ + Label: "[]", + Kind: protocol.SnippetCompletion, + InsertTextFormat: &snippetTextFormat, + InsertText: escape("[$1=$0]"), + }) + case mcfunction.ParameterKindVector2: + addItem("~~") + addItem("0 0") + addItem("^^") + case mcfunction.ParameterKindVector3: + addItem("~~~") + addItem("0 0 0") + addItem("^^^") + case mcfunction.ParameterKindRange: + addItem("0..0") + addItem("..0") + addItem("0..") + addItem("!0..0") + case mcfunction.ParameterKindSuffixedInteger: + addItem("1" + param.Suffix) + case mcfunction.ParameterKindWildcardInteger: + addItem("*") + addItem("0") + case mcfunction.ParameterKindChainedCommand: + for _, o := range node.OverloadStates() { + addCompletions(o.Parameters()[0]) + } + case mcfunction.ParameterKindCommand: + for name := range h.Parser.RegisteredCommands() { + addItem(name, protocol.MethodCompletion) + } + case mcfunction.ParameterKindRawMessage: + result = append(result, protocol.CompletionItem{ + Label: "Raw Message Snippet...", + Kind: protocol.SnippetCompletion, + InsertTextFormat: &snippetTextFormat, + InsertText: escape(`{"rawtext":[$0]}`), + }) + case mcfunction.ParameterKindItemNbt: + result = append(result, protocol.CompletionItem{ + Label: "Item NBT Snippet...", + Kind: protocol.SnippetCompletion, + InsertTextFormat: &snippetTextFormat, + InsertText: escape(`{}`), + }) + case mcfunction.ParameterKindRelativeNumber: + addItem("~") + addItem("0") + } + } + tagSet := mapset.NewThreadUnsafeSet[string]() + for _, o := range node.OverloadStates() { + if !o.Matched() { + continue + } + param, ok := o.Peek() + if !ok { + continue + } + addCompletions(param) + for _, tag := range param.Tags { + if tagSet.Contains(tag) { + continue + } + tagSet.Add(tag) + entry, ok := commandEntries[tag] + if !ok || entry.Source == nil { + continue + } + for _, item := range entry.Source(node) { + value := item.Value + if entry.Transform != nil { + value = entry.Transform(value) + } + addItem(escape(value)) + } + if entry.Store != nil && entry.Store.VanillaData != nil { + for value := range mapset.Elements(entry.Store.VanillaData) { + if entry.Namespaced && !strings.HasPrefix(value, "minecraft:") { + continue + } + addItem(escape(value), protocol.EnumCompletion) + } + } + } + } + return result +} + +func (h *CommandHandler) Definitions(document *textdocument.TextDocument, position protocol.Position) []protocol.LocationLink { + result := []protocol.LocationLink{} + context := h.parseLine(document, position) + root := context.Root + rOffset := context.RelativeOffset + startOffset := context.StartOffset + line := context.Content + if root == nil { + return nil + } + node := mcfunction.NodeAt(root, rOffset) + arg, ok := node.(mcfunction.INodeArg) + if !ok { + return result + } + paramSpec, ok := arg.ArgParamSpec() + if !ok { + return result + } + rStart, rEnd := arg.Range() + nodeRange := protocol.Range{ + Start: document.PositionAt(startOffset + rStart), + End: document.PositionAt(startOffset + rEnd), + } + nodeValue := arg.Text(line) + if h.EscapeQuotes { + nodeValue = strings.Trim(nodeValue, `\"`) + } else { + nodeValue = strings.Trim(nodeValue, `"`) + } + for _, tag := range paramSpec.Tags { + entry, ok := commandEntries[tag] + if !ok || entry.Source == nil { + continue + } + for _, item := range entry.Source(node) { + value := item.Value + if entry.Transform != nil { + value = entry.Transform(value) + } + if value != nodeValue { + continue + } + location := protocol.LocationLink{ + OriginSelectionRange: &nodeRange, + TargetURI: item.URI, + } + if item.Range != nil { + location.TargetRange = *item.Range + location.TargetSelectionRange = *item.Range + } + result = append(result, location) + } + } + return result +} + +func (h *CommandHandler) PrepareRename(document *textdocument.TextDocument, position protocol.Position) *protocol.PrepareRenamePlaceholder { + context := h.parseLine(document, position) + root := context.Root + rOffset := context.RelativeOffset + startOffset := context.StartOffset + line := context.Content + if root == nil { + return nil + } + node := mcfunction.NodeAt(root, rOffset) + arg, ok := node.(mcfunction.INodeArg) + if !ok { + return nil + } + paramSpec, ok := arg.ArgParamSpec() + if !ok { + return nil + } + rStart, rEnd := arg.Range() + nodeRange := protocol.Range{ + Start: document.PositionAt(startOffset + rStart), + End: document.PositionAt(startOffset + rEnd), + } + nodeValue := arg.Text(line) + for _, tag := range paramSpec.Tags { + entry, ok := commandEntries[tag] + if !ok || entry.DisableRename { + continue + } + return &protocol.PrepareRenamePlaceholder{ + Range: nodeRange, + Placeholder: nodeValue, + } + } + return nil +} + +func (h *CommandHandler) Rename(document *textdocument.TextDocument, position protocol.Position, newName string) *protocol.WorkspaceEdit { + context := h.parseLine(document, position) + root := context.Root + rOffset := context.RelativeOffset + line := context.Content + if root == nil { + return nil + } + node := mcfunction.NodeAt(root, rOffset) + arg, ok := node.(mcfunction.INodeArg) + if !ok { + return nil + } + paramSpec, ok := arg.ArgParamSpec() + if !ok { + return nil + } + nodeValue := arg.Text(line) + // TODO: Check cross rename between unescaped and escaped strings + changes := make(map[protocol.DocumentURI][]protocol.TextEdit) + for _, tag := range paramSpec.Tags { + entry, ok := commandEntries[tag] + if !ok || entry.DisableRename { + continue + } + items := entry.Source(node) + if entry.References != nil { + items = slices.Concat(items, entry.References(node)) + } + for _, item := range items { + if item.Value != nodeValue { + continue + } + edit := protocol.TextEdit{ + NewText: newName, + Range: *item.Range, + } + changes[item.URI] = append(changes[item.URI], edit) + } + } + return &protocol.WorkspaceEdit{Changes: changes} +} + +func (h *CommandHandler) Hover(document *textdocument.TextDocument, position protocol.Position) *protocol.Hover { + context := h.parseLine(document, position) + root := context.Root + rOffset := context.RelativeOffset + if root == nil { + return nil + } + node := mcfunction.NodeAt(root, rOffset) + var commandNode mcfunction.INodeCommand + switch n := node.(type) { + case mcfunction.INodeCommand: + commandNode = n + case mcfunction.INodeArg: + if parent, ok := n.Parent().(mcfunction.INodeCommand); ok { + commandNode = parent + } + } + if commandNode == nil { + return nil + } + spec := commandNode.Spec() + if spec == nil { + return nil + } + return &protocol.Hover{ + Contents: protocol.MarkupContent{ + Kind: protocol.Markdown, + Value: "```\n" + + commandNode.CommandName() + + "\n```\n" + + commandNode.Spec().Description, + }, + } +} + +func (h *CommandHandler) SignatureHelp(document *textdocument.TextDocument, position protocol.Position) *protocol.SignatureHelp { + context := h.parseLine(document, position) + root := context.Root + rOffset := context.RelativeOffset + line := context.Content + if root == nil { + return nil + } + node := mcfunction.NodeAt(root, rOffset) + var commandNode mcfunction.INodeCommand + flag := false +REPARSE: + rStart, _ := node.Range() + switch n := node.(type) { + case mcfunction.INodeCommand: + commandNode = n + case mcfunction.INodeArg: + if parent, ok := n.Parent().(mcfunction.INodeCommand); ok { + if parent.IsValid() { + commandNode = parent + } else if !flag { + root, _ := h.Parser.Parse(line[:rStart]) + node = mcfunction.NodeAt(root, rStart) + flag = true + goto REPARSE + } + } + } + if commandNode == nil { + return nil + } + spec := commandNode.Spec() + signatures := make([]protocol.SignatureInformation, 0, len(commandNode.OverloadStates())) + for _, o := range commandNode.OverloadStates() { + if !o.Matched() { + continue + } + params := o.Parameters() + index := uint32(o.Index()) + paramLabels := make([]string, len(params)) + for j, p := range params { + paramLabels[j] = p.ToString() + } + signatures = append(signatures, protocol.SignatureInformation{ + Label: commandNode.CommandName() + " " + strings.Join(paramLabels, " "), + Documentation: &protocol.Or_SignatureInformation_documentation{ + Value: spec.Description, + }, + Parameters: sliceutil.Map(paramLabels, func(label string) protocol.ParameterInformation { + return protocol.ParameterInformation{ + Label: label, + } + }), + ActiveParameter: index, + }) + } + return &protocol.SignatureHelp{ + Signatures: signatures, + } +} + +func (h *CommandHandler) ComputeSemanticTokens(document *textdocument.TextDocument) []semtok.Token { + content := document.GetContent() + root, _ := h.Parser.Parse(content) + tokens := []semtok.Token{} + molangRanges := []protocol.Range{} + isMolang := func(node mcfunction.INodeArg) bool { + param, ok := node.ArgParamSpec() + if ok && slices.Contains(param.Tags, mcfunction.TagMolang) { + start, end := node.Range() + length := end - start + if length >= 2 { + if content[start] == '"' && content[end-1] == '"' { + return true + } + } + } + return false + } + mcfunction.WalkNodeTree(root, func(i mcfunction.INode) bool { + start, end := i.Range() + length := end - start + pA := document.PositionAt(start) + pB := document.PositionAt(end) + switch n := i.(type) { + case mcfunction.INodeCommand: + if p, ok := i.(mcfunction.INodeArg); n.Kind() != mcfunction.NodeKindCommandArg || (ok && p.ParamKind() == mcfunction.ParameterKindCommand) { + tokens = append(tokens, semtok.Token{ + Type: semtok.TokNamespace, + Line: pA.Line, + Start: pA.Character, + Len: uint32(len(n.CommandName())), + }) + } + case mcfunction.INodeArg: + if isMolang(n) { + tokens = append(tokens, semtok.Token{ + Type: semtok.TokString, + Line: pA.Line, + Start: pA.Character, + Len: 1, + }) + tokens = append(tokens, semtok.Token{ + Type: semtok.TokString, + Line: pB.Line, + Start: pB.Character - 1, + Len: 1, + }) + pA.Character += 1 + pB.Character -= 1 + molangRanges = append(molangRanges, protocol.Range{ + Start: pA, + End: pB, + }) + } else if tokType, ok := commandParamTokenMap[n.ParamKind()]; ok { + spec, ok := n.ArgParamSpec() + if ok && slices.Contains(spec.Tags, mcfunction.TagExecuteChain) { + tokType = semtok.TokKeyword + } + tokens = append(tokens, semtok.Token{ + Type: tokType, + Line: pA.Line, + Start: pA.Character, + Len: length, + }) + } + } + return true + }) + molangDocument := document.CreateVirtualDocument(molangRanges...) + tokens = slices.Concat(tokens, Molang.ComputeSemanticTokens(molangDocument)) + return tokens +} + +func (h *CommandHandler) SemanticTokens(document *textdocument.TextDocument) *protocol.SemanticTokens { + tokens := h.ComputeSemanticTokens(document) + return &protocol.SemanticTokens{ + Data: semtok.Encode(tokens, tokenType, tokenModifier), + } +} + +func (h *CommandHandler) parseLine(document *textdocument.TextDocument, position protocol.Position) parsedCommandLine { + content := document.GetContent() + startOffset := document.OffsetAt(protocol.Position{ + Line: position.Line, + }) + offset := document.OffsetAt(position) + rOffset := offset - startOffset + line := content[startOffset:] + root, _ := h.Parser.Parse(line) + return parsedCommandLine{ + Content: line, + StartOffset: startOffset, + RelativeOffset: rOffset, + Root: root, + } +} + +type parsedCommandLine struct { + Content []rune + StartOffset uint32 + RelativeOffset uint32 + Root mcfunction.INode +} + +var commandParamTokenMap = map[mcfunction.ParameterKind]semtok.Type{ + mcfunction.ParameterKindLiteral: semtok.TokMethod, + mcfunction.ParameterKindString: semtok.TokString, + mcfunction.ParameterKindNumber: semtok.TokNumber, + mcfunction.ParameterKindInteger: semtok.TokNumber, + mcfunction.ParameterKindBoolean: semtok.TokMacro, + mcfunction.ParameterKindSelector: semtok.TokEnumMember, + mcfunction.ParameterKindMap: semtok.TokEnumMember, + mcfunction.ParameterKindRange: semtok.TokNumber, + mcfunction.ParameterKindSuffixedInteger: semtok.TokNumber, + mcfunction.ParameterKindWildcardInteger: semtok.TokNumber, + mcfunction.ParameterKindChainedCommand: semtok.TokKeyword, + mcfunction.ParameterKindRawMessage: semtok.TokString, + mcfunction.ParameterKindItemNbt: semtok.TokString, + mcfunction.ParameterKindRelativeNumber: semtok.TokNumber, +} + +type commandEntry struct { + Store *stores.SymbolStore + Source func(node mcfunction.INode) []core.Symbol + References func(node mcfunction.INode) []core.Symbol + Transform func(s string) string + Scope func(node mcfunction.INode) string + Namespaced bool + DisableRename bool +} + +var commandEntries = map[string]commandEntry{ + mcfunction.TagAimAssistId: { + Store: stores.AimAssistCategory.References, + Source: func(node mcfunction.INode) []core.Symbol { + return stores.AimAssistCategory.Source.Get() + }, + References: func(node mcfunction.INode) []core.Symbol { + return stores.AimAssistCategory.References.Get() + }, + }, + mcfunction.TagBiomeId: { + Store: stores.BiomeId.References, + Source: func(node mcfunction.INode) []core.Symbol { + return stores.BiomeId.Source.Get() + }, + References: func(node mcfunction.INode) []core.Symbol { + return stores.BiomeId.References.Get() + }, + }, + mcfunction.TagBlockId: { + Store: stores.ItemId.References, + Scope: func(node mcfunction.INode) string { + return "block" + }, + Namespaced: true, + Source: func(node mcfunction.INode) []core.Symbol { + return stores.ItemId.Source.Get("block") + }, + References: func(node mcfunction.INode) []core.Symbol { + return stores.ItemId.References.Get("block") + }, + }, + // mcfunction.TagBlockState: { + // Store: stores.BlockState.References, + // Source: func(node mcfunction.INode) []core.Symbol { + // return stores.BlockState.Source.Get() + // }, + // }, + mcfunction.TagCameraId: { + Store: stores.CameraId.References, + Source: func(node mcfunction.INode) []core.Symbol { + return stores.CameraId.Source.Get() + }, + References: func(node mcfunction.INode) []core.Symbol { + return stores.CameraId.References.Get() + }, + }, + mcfunction.TagClientAnimationId: { + Store: stores.ClientAnimation.References, + Source: func(node mcfunction.INode) []core.Symbol { + return stores.ClientAnimation.Source.Get() + }, + References: func(node mcfunction.INode) []core.Symbol { + return stores.ClientAnimation.References.Get() + }, + }, + mcfunction.TagDialogueId: { + Store: stores.DialogueId.References, + Source: func(node mcfunction.INode) []core.Symbol { + return stores.DialogueId.Source.Get() + }, + References: func(node mcfunction.INode) []core.Symbol { + return stores.DialogueId.References.Get() + }, + }, + mcfunction.TagEntityEvent: { + DisableRename: true, + Store: stores.EntityEvent.References, + Source: func(node mcfunction.INode) []core.Symbol { + return stores.EntityEvent.Source.Get() + }, + }, + mcfunction.TagEntityId: { + Store: stores.EntityId.References, + Namespaced: true, + Source: func(node mcfunction.INode) []core.Symbol { + return stores.EntityId.Source.Get() + }, + References: func(node mcfunction.INode) []core.Symbol { + return stores.EntityId.References.Get() + }, + }, + mcfunction.TagFeatureId: { + Store: stores.FeatureId.References, + Source: func(node mcfunction.INode) []core.Symbol { + return stores.FeatureId.Source.Get() + }, + References: func(node mcfunction.INode) []core.Symbol { + return stores.FeatureId.References.Get() + }, + }, + mcfunction.TagFeatureRuleId: { + Store: stores.FeatureRuleId.References, + Source: func(node mcfunction.INode) []core.Symbol { + return stores.FeatureRuleId.Source.Get() + }, + References: func(node mcfunction.INode) []core.Symbol { + return stores.FeatureRuleId.References.Get() + }, + }, + mcfunction.TagFogId: { + Store: stores.Fog.References, + Source: func(node mcfunction.INode) []core.Symbol { + return stores.Fog.Source.Get() + }, + References: func(node mcfunction.INode) []core.Symbol { + return stores.Fog.References.Get() + }, + }, + mcfunction.TagFunctionFile: { + DisableRename: true, + Source: func(node mcfunction.INode) []core.Symbol { + return stores.McFunctionPath.Get() + }, + Transform: func(s string) string { + return strings.TrimPrefix(s, "functions/") + }, + }, + mcfunction.TagItemId: { + Store: stores.ItemId.References, + Namespaced: true, + Source: func(node mcfunction.INode) []core.Symbol { + return stores.ItemId.Source.Get() + }, + References: func(node mcfunction.INode) []core.Symbol { + return stores.ItemId.References.Get() + }, + }, + mcfunction.TagJigsawId: { + Store: stores.WorldgenJigsaw.References, + Source: func(node mcfunction.INode) []core.Symbol { + return stores.WorldgenJigsaw.Source.Get() + }, + References: func(node mcfunction.INode) []core.Symbol { + return stores.WorldgenJigsaw.References.Get() + }, + }, + mcfunction.TagJigsawTemplatePoolId: { + Store: stores.WorldgenTemplatePool.References, + Source: func(node mcfunction.INode) []core.Symbol { + return stores.WorldgenTemplatePool.Source.Get() + }, + References: func(node mcfunction.INode) []core.Symbol { + return stores.WorldgenTemplatePool.References.Get() + }, + }, + mcfunction.TagLootTableFile: { + DisableRename: true, + Source: func(node mcfunction.INode) []core.Symbol { + return stores.LootTablePath.Get() + }, + Transform: func(s string) string { + s = strings.TrimPrefix(s, "loot_tables/") + s = strings.TrimSuffix(s, ".json") + return s + }, + }, + mcfunction.TagMusicId: { + Store: stores.MusicDefinition.References, + Source: func(node mcfunction.INode) []core.Symbol { + return stores.MusicDefinition.Source.Get() + }, + References: func(node mcfunction.INode) []core.Symbol { + return stores.MusicDefinition.References.Get() + }, + }, + mcfunction.TagProvidedFogId: { + Store: stores.ProvidedFogId.Source, + Source: func(node mcfunction.INode) []core.Symbol { + return stores.ProvidedFogId.Source.Get() + }, + }, + mcfunction.TagRecipeId: { + Store: stores.RecipeId.References, + Source: func(node mcfunction.INode) []core.Symbol { + return stores.RecipeId.Source.Get() + }, + References: func(node mcfunction.INode) []core.Symbol { + return stores.RecipeId.References.Get() + }, + }, + mcfunction.TagSoundId: { + Store: stores.SoundDefinition.References, + Source: func(node mcfunction.INode) []core.Symbol { + return stores.SoundDefinition.Source.Get() + }, + References: func(node mcfunction.INode) []core.Symbol { + return stores.SoundDefinition.References.Get() + }, + }, + mcfunction.TagStructureFile: { + DisableRename: true, + Source: func(node mcfunction.INode) []core.Symbol { + return stores.StructurePath.Get() + }, + }, + mcfunction.TagTagId: { + Store: stores.Tag.Source, + Source: func(node mcfunction.INode) []core.Symbol { + return stores.Tag.Source.Get() + }, + }, + mcfunction.TagTickingAreaId: { + Store: stores.TickingArea.Source, + Source: func(node mcfunction.INode) []core.Symbol { + return stores.TickingArea.Source.Get() + }, + }, + mcfunction.TagTypeFamilyId: { + Store: stores.EntityFamily.References, + Source: func(node mcfunction.INode) []core.Symbol { + return stores.EntityFamily.Source.Get() + }, + References: func(node mcfunction.INode) []core.Symbol { + return stores.EntityFamily.References.Get() + }, + }, + mcfunction.TagScoreboardObjectiveId: { + Store: stores.ScoreboardObjective.Source, + Source: func(node mcfunction.INode) []core.Symbol { + return stores.ScoreboardObjective.Source.Get() + }, + }, +} + +var rawMessage = &JsonRawMessageHandler{ + JsonSnippetHandler: &JsonSnippetHandler{ + JsonHandler: &JsonHandler{ + Entries: []JsonEntry{ + { + Store: stores.Lang.References, + Path: []shared.JsonPath{shared.JsonValue("rawtext/**/translate")}, + Source: func(ctx *JsonContext) []core.Symbol { + return stores.Lang.Source.Get() + }, + References: func(ctx *JsonContext) []core.Symbol { + return stores.Lang.References.Get() + }, + }, + { + Store: stores.ScoreboardObjective.Source, + Path: []shared.JsonPath{shared.JsonValue("rawtext/**/score/objective")}, + Source: func(ctx *JsonContext) []core.Symbol { + return stores.ScoreboardObjective.Source.Get() + }, + References: func(ctx *JsonContext) []core.Symbol { + return nil + }, + }, + }, + }, + SnippetEntries: []SnippetEntry{ + { + Path: []shared.JsonPath{shared.JsonValue("**/rawtext/*")}, + Snippets: []Snippet{ + { + Label: "Text", + Value: `{"text":"$0"}`, + }, + { + Label: "Score", + Value: `{"score":{"name":"$0","objective":"$1"}}`, + }, + { + Label: "Translate", + Value: `{"translate":"$0"}`, + }, + { + Label: "Translate with", + Value: `{"translate":"$1","with":{"rawtext":[$0]}}`, + }, + }, + }, + { + Path: []shared.JsonPath{shared.JsonKey("**/rawtext/**")}, + Snippets: []Snippet{ + { + Label: "With", + Value: `"with":{"rawtext":[$0]}`, + }, + }, + }, + { + Path: []shared.JsonPath{shared.JsonValue("**/rawtext/**/with/*")}, + Snippets: []Snippet{ + { + Label: "Rawtext", + Value: `{"rawtext":[$0]}`, + }, + }, + }, + }, + }, +} + +var itemNbt = &JsonSnippetHandler{ + JsonHandler: &JsonHandler{ + Entries: []JsonEntry{ + { + Store: stores.ItemId.References, + Path: []shared.JsonPath{ + shared.JsonValue("minecraft:can_place_on/blocks/*"), + shared.JsonValue("minecraft:can_destroy/blocks/*"), + }, + ScopeKey: func(ctx *JsonContext) string { + return "block" + }, + Source: func(ctx *JsonContext) []core.Symbol { + return stores.ItemId.Source.Get("block") + }, + References: func(ctx *JsonContext) []core.Symbol { + return stores.ItemId.References.Get("block") + }, + }, + }, + }, + SnippetEntries: []SnippetEntry{ + { + Path: []shared.JsonPath{shared.JsonKey("*")}, + Snippets: []Snippet{ + { + Label: "Can place on", + Value: `"minecraft:can_place_on":{"blocks":[$0]}`, + }, + { + Label: "Can destroy", + Value: `"minecraft:can_destroy":{"blocks":[$0]}`, + }, + { + Label: "Keep on death", + Value: `"minecraft:keep_on_death":{}`, + }, + { + Label: "Lock in inventory", + Value: `"minecraft:item_lock":{"mode":"lock_in_inventory"}"`, + }, + { + Label: "Lock in slot", + Value: `"minecraft:item_lock":{"mode":"lock_in_slot"}"`, + }, + }, + }, + }, +} diff --git a/handlers/handler_json_rawmessage.go b/handlers/handler_json_rawmessage.go new file mode 100644 index 0000000..753df1a --- /dev/null +++ b/handlers/handler_json_rawmessage.go @@ -0,0 +1,44 @@ +package handlers + +import ( + "github.com/rockide/language-server/internal/jsonc" + "github.com/rockide/language-server/internal/protocol" + "github.com/rockide/language-server/internal/textdocument" +) + +type JsonRawMessageHandler struct { + *JsonSnippetHandler + CommandHandler *CommandHandler +} + +func (j *JsonRawMessageHandler) Completions(document *textdocument.TextDocument, position protocol.Position) []protocol.CompletionItem { + offset := document.OffsetAt(position) + location := jsonc.GetLocation(document.GetText(), offset) + if location == nil { + return nil + } + node := location.PreviousNode + if location.Path.Matches(jsonc.NewPath("**/rawtext/*/score/name")) && j.CommandHandler != nil { + result := []protocol.CompletionItem{} + for selector, ok := range j.CommandHandler.Parser.GetSelectors() { + if !ok { + continue + } + value := `"@` + selector + `"` + result = append(result, protocol.CompletionItem{ + Label: value, + TextEdit: &protocol.Or_CompletionItem_textEdit{ + Value: protocol.TextEdit{ + NewText: value, + Range: protocol.Range{ + Start: document.PositionAt(node.Offset), + End: document.PositionAt(node.Offset + node.Length), + }, + }, + }, + }) + } + return result + } + return j.JsonSnippetHandler.Completions(document, position) +} diff --git a/handlers/handler_json_snippet.go b/handlers/handler_json_snippet.go new file mode 100644 index 0000000..9ba5fd3 --- /dev/null +++ b/handlers/handler_json_snippet.go @@ -0,0 +1,58 @@ +package handlers + +import ( + "github.com/rockide/language-server/internal/jsonc" + "github.com/rockide/language-server/internal/protocol" + "github.com/rockide/language-server/internal/textdocument" + "github.com/rockide/language-server/shared" +) + +type JsonSnippetHandler struct { + *JsonHandler + SnippetEntries []SnippetEntry +} + +type SnippetEntry struct { + Path []shared.JsonPath + Snippets []Snippet +} + +type Snippet struct { + Label string + Value string +} + +var snippetTextFormat = protocol.SnippetTextFormat + +func (j *JsonSnippetHandler) prepareSnippet(location *jsonc.Location) *SnippetEntry { + for _, entry := range j.SnippetEntries { + for _, jsonPath := range entry.Path { + if jsonPath.IsKey == location.IsAtPropertyKey && location.Path.Matches(jsonPath.Path) { + return &entry + } + } + } + return nil +} + +func (j *JsonSnippetHandler) Completions(document *textdocument.TextDocument, position protocol.Position) []protocol.CompletionItem { + offset := document.OffsetAt(position) + location := jsonc.GetLocation(document.GetText(), offset) + if location == nil { + return nil + } + snippetEntry := j.prepareSnippet(location) + if snippetEntry == nil { + return j.JsonHandler.Completions(document, position) + } + result := []protocol.CompletionItem{} + for _, snippet := range snippetEntry.Snippets { + result = append(result, protocol.CompletionItem{ + Label: snippet.Label, + Kind: protocol.SnippetCompletion, + InsertTextFormat: &snippetTextFormat, + InsertText: snippet.Value, + }) + } + return result +} diff --git a/handlers/handlers.go b/handlers/handlers.go index 171b408..6f8743a 100644 --- a/handlers/handlers.go +++ b/handlers/handlers.go @@ -57,6 +57,7 @@ var handlerList = []Handler{ Item, Lang, LootTable, + McFunction, Recipe, SpawnRule, Structure, diff --git a/handlers/mcfunction.go b/handlers/mcfunction.go new file mode 100644 index 0000000..5a59f42 --- /dev/null +++ b/handlers/mcfunction.go @@ -0,0 +1,20 @@ +package handlers + +import ( + "github.com/rockide/language-server/internal/mcfunction" + "github.com/rockide/language-server/internal/mcfunction/vanilla" + "github.com/rockide/language-server/shared" +) + +func newCommandParser(options mcfunction.ParserOptions) *mcfunction.Parser { + parser := mcfunction.NewParser(options) + parser.RegisterCommands(vanilla.Commands...) + return parser +} + +var defaultCommandParser = newCommandParser(mcfunction.ParserOptions{}) + +var McFunction = &CommandHandler{ + Pattern: shared.FunctionGlob, + Parser: defaultCommandParser, +} diff --git a/internal/mcfunction/lexer/lexer.go b/internal/mcfunction/lexer/lexer.go new file mode 100644 index 0000000..bcac400 --- /dev/null +++ b/internal/mcfunction/lexer/lexer.go @@ -0,0 +1,316 @@ +package lexer + +import ( + "iter" +) + +type Lexer struct { + src []rune + i int + state state +} + +func New(input []rune) *Lexer { + return &Lexer{ + src: input, + state: StateStart, + } +} + +func (l *Lexer) eof() bool { + return l.i >= len(l.src) +} + +func (l *Lexer) peek() rune { + if l.eof() { + return 0 + } + return l.src[l.i] +} + +func (l *Lexer) peekN(n int) rune { + if l.i+n >= len(l.src) { + return 0 + } + return l.src[l.i+n] +} + +func (l *Lexer) advance() rune { + if l.eof() { + return 0 + } + r := l.src[l.i] + l.i++ + return r +} + +func (l *Lexer) advanceWhile(cond func(rune) bool) { + for !l.eof() && cond(l.peek()) { + l.advance() + } +} + +func (l *Lexer) pos() uint32 { + return uint32(l.i) +} + +func (l *Lexer) emit(kind TokenKind, start uint32) Token { + end := l.pos() + return Token{ + Kind: kind, + Start: start, + End: end, + } +} + +func (l *Lexer) matchPairs(open, close rune) bool { + depth := 0 + for !l.eof() { + r := l.peek() + if r == open { + depth++ + } else if r == close { + depth-- + if depth == 0 { + l.advance() + return true + } + } else if isNewline(r) { + return false + } + l.advance() + } + return false +} + +func (l *Lexer) Next() iter.Seq[Token] { + return func(yield func(Token) bool) { + depth := -1 + for !l.eof() { + depth++ + if depth > 1000 { + panic("lexer: possible infinite loop detected") + } + r := l.peek() + start := l.pos() + switch r { + case '\r': + l.advance() + continue + case ' ', '\t': + l.advanceWhile(isWhitespace) + if !yield(l.emit(TokenWhitespace, start)) { + return + } + continue + case '\n': + l.advance() + if !yield(l.emit(TokenNewline, start)) { + return + } + l.state = StateStart + continue + case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + l.state = StateNumber + case '-': + if l.i+1 < len(l.src) && isDigit(l.src[l.i+1]) { + l.state = StateNegativeNumber + } + case '~', '^': + l.state = StateRelativeNumber + case '@': + l.state = StateSelector + case '[': + l.state = StateMap + case '{': + l.state = StateJSON + case '=': + l.advance() + if !yield(l.emit(TokenEquals, start)) { + return + } + continue + case ',': + l.advance() + if !yield(l.emit(TokenComma, start)) { + return + } + continue + case '.': + l.advance() + if l.peek() == '.' { + l.advance() + if !yield(l.emit(TokenRange, start)) { + return + } + } else { + if !yield(l.emit(TokenDot, start)) { + return + } + } + continue + case '!': + l.advance() + if !yield(l.emit(TokenBang, start)) { + return + } + continue + } + + switch l.state { + case StateStart: + if r == '#' { + if l.peek() == '#' { + l.advanceWhile(func(r rune) bool { return !isNewline(r) }) + if !yield(l.emit(TokenComment, start)) { + return + } + continue + } + } + fallthrough + case StateString: + if r == '"' { + l.advance() + l.advanceWhile(func(r rune) bool { return r != '"' && !isNewline(r) }) + if l.peek() == '"' { + l.advance() + if !yield(l.emit(TokenString, start)) { + return + } + } else { + if !yield(l.emit(TokenUnterminatedString, start)) { + return + } + l.state = StateStart + continue + } + } else { + l.advanceWhile(func(r rune) bool { return !isTerminateString(r) }) + if !yield(l.emit(TokenString, start)) { + return + } + } + case StateNegativeNumber: + l.advance() // consume '-' + a := l.i + l.advanceWhile(isDigit) + b := l.i + r := l.peek() + if r == '.' && isDigit(l.peekN(1)) { + l.advance() + l.advanceWhile(isDigit) + } + if a == b { + if !yield(l.emit(TokenString, start)) { + return + } + } else { + if !yield(l.emit(TokenNumber, start)) { + return + } + } + case StateNumber: + l.advanceWhile(isDigit) + r := l.peek() + if r == '.' && isDigit(l.peekN(1)) { + l.advance() // consume '.' + l.advanceWhile(isDigit) + } + if !yield(l.emit(TokenNumber, start)) { + return + } + case StateRelativeNumber: + // possible patterns: + // ~ + // ~2 + // ~2.2 + // ~.2 + // ~-2 + // ~-2.2 + // ~-.2 + l.advance() // consume '~' or '^' + r := l.peek() + if r == '-' { + l.advance() // consume '-' + r = l.peek() + } + if isDigit(r) { + l.advanceWhile(isDigit) + } + if r == '.' { + l.advance() // consume '.' + l.advanceWhile(isDigit) + } + if !yield(l.emit(TokenRelativeNumber, start)) { + return + } + case StateSelector: + l.advance() // consume '@' + a := l.i + l.advanceWhile(isLetter) + b := l.i + if a == b { + if !yield(l.emit(TokenString, start)) { + return + } + } else { + if !yield(l.emit(TokenSelector, start)) { + return + } + } + case StateMap: + if l.matchPairs('[', ']') { + if !yield(l.emit(TokenMap, start)) { + return + } + } else { + if !yield(l.emit(TokenUnterminatedMap, start)) { + return + } + } + case StateJSON: + if l.matchPairs('{', '}') { + if !yield(l.emit(TokenJSON, start)) { + return + } + } else { + if !yield(l.emit(TokenUnterminatedJSON, start)) { + return + } + } + } + l.state = StateString + } + } +} + +func (l *Lexer) Reset(input []rune) { + l.src = input + l.i = 0 + l.state = StateStart +} + +func isWhitespace(r rune) bool { + return r == ' ' || r == '\t' || r == '\r' +} + +func isNewline(r rune) bool { + return r == '\n' +} + +func isTerminateString(r rune) bool { + return isNewline(r) || isWhitespace(r) || isRelativeNumber(r) || r == '@' || r == '"' || r == '[' || r == '{' || r == '=' || r == ',' || r == '.' || r == '!' +} + +func isRelativeNumber(r rune) bool { + return r == '~' || r == '^' +} + +func isDigit(r rune) bool { + return r >= '0' && r <= '9' +} + +func isLetter(r rune) bool { + return (r >= 'a' && r <= 'z') || (r >= 'A' && r <= 'Z') +} diff --git a/internal/mcfunction/lexer/state.go b/internal/mcfunction/lexer/state.go new file mode 100644 index 0000000..d440600 --- /dev/null +++ b/internal/mcfunction/lexer/state.go @@ -0,0 +1,14 @@ +package lexer + +type state uint8 + +const ( + StateStart state = iota + StateString + StateNumber + StateNegativeNumber + StateRelativeNumber + StateSelector + StateMap + StateJSON +) diff --git a/internal/mcfunction/lexer/token.go b/internal/mcfunction/lexer/token.go new file mode 100644 index 0000000..e5a31a2 --- /dev/null +++ b/internal/mcfunction/lexer/token.go @@ -0,0 +1,46 @@ +package lexer + +type TokenKind uint8 + +const ( + TokenEOF TokenKind = iota + TokenWhitespace + TokenNewline + TokenComment + TokenString + TokenUnterminatedString + TokenNumber + TokenRelativeNumber + TokenSelector + TokenMap + TokenUnterminatedMap + TokenJSON + TokenUnterminatedJSON + TokenEquals + TokenComma + TokenDot + TokenRange + TokenBang +) + +type Token struct { + Kind TokenKind + Start uint32 + End uint32 +} + +func (t Token) Text(input []rune) string { + return string(input[t.Start:t.End]) +} + +func (t Token) Range() (start, end uint32) { + return t.Start, t.End +} + +func (t Token) Len() uint32 { + return t.End - t.Start +} + +func (t Token) IsInside(pos uint32) bool { + return t.Start <= pos && pos < t.End +} diff --git a/internal/mcfunction/node.go b/internal/mcfunction/node.go new file mode 100644 index 0000000..c9e4290 --- /dev/null +++ b/internal/mcfunction/node.go @@ -0,0 +1,106 @@ +package mcfunction + +type NodeKind uint8 + +// file +// ├─ comment +// ├─ command +// │ ├─ command lit +// │ ├─ command arg +// ├─ invalid command +// │ ├─ command lit +// │ ├─ command arg + +const ( + NodeKindFile NodeKind = iota + NodeKindComment + NodeKindCommand + NodeKindInvalidCommand + NodeKindCommandLit + NodeKindCommandArg +) + +type INode interface { + addChild(child INode) + setParent(parent INode) + setIndex(index int) + + Kind() NodeKind + Range() (start, end uint32) + Text([]rune) string + PrevSibling() INode + NextSibling() INode + Parent() INode + Index() int + Children() []INode + IsInside(pos uint32) bool +} + +type Node struct { + kind NodeKind + parent INode + index int + children []INode + start uint32 + end uint32 +} + +func (n *Node) addChild(child INode) { + child.setParent(n) + child.setIndex(len(n.children)) + n.children = append(n.children, child) +} + +func (n *Node) setParent(parent INode) { + n.parent = parent +} + +func (n *Node) setIndex(index int) { + n.index = index +} + +func (n *Node) Kind() NodeKind { + return n.kind +} + +func (n *Node) Range() (start, end uint32) { + return n.start, n.end +} + +func (n *Node) Text(src []rune) string { + return string(src[n.start:n.end]) +} + +func (n *Node) PrevSibling() INode { + if n.parent == nil || n.index == 0 { + return nil + } + i := n.index - 1 + if i < 0 || i >= len(n.parent.Children()) { + return nil + } + return n.parent.Children()[i] +} + +func (n *Node) NextSibling() INode { + if n.parent == nil || n.index+1 >= len(n.parent.Children()) { + return nil + } + return n.parent.Children()[n.index+1] +} + +func (n *Node) Parent() INode { + return n.parent +} + +func (n *Node) Index() int { + return n.index +} + +func (n *Node) Children() []INode { + return n.children +} + +func (n *Node) IsInside(pos uint32) bool { + return n.start <= pos && pos < n.end +} diff --git a/internal/mcfunction/node_arg.go b/internal/mcfunction/node_arg.go new file mode 100644 index 0000000..83654fe --- /dev/null +++ b/internal/mcfunction/node_arg.go @@ -0,0 +1,89 @@ +package mcfunction + +type INodeArg interface { + INode + ParamKind() ParameterKind + ArgParamSpec() (ParameterSpec, bool) +} + +type NodeArg struct { + *Node + paramKind ParameterKind +} + +func (n *NodeArg) addChild(child INode) { + child.setParent(n) + child.setIndex(len(n.children)) + n.children = append(n.children, child) +} + +func (n *NodeArg) setParent(parent INode) { + n.parent = parent +} + +func (n *NodeArg) setIndex(index int) { + n.index = index +} + +func (n *NodeArg) Kind() NodeKind { + return NodeKindCommandArg +} + +func (n *NodeArg) Range() (start, end uint32) { + return n.start, n.end +} + +func (n *NodeArg) Text(src []rune) string { + return string(src[n.start:n.end]) +} + +func (n *NodeArg) PrevSibling() INode { + if n.parent == nil || n.index == 0 { + return nil + } + i := n.index - 1 + if i < 0 || i >= len(n.parent.Children()) { + return nil + } + return n.parent.Children()[i] +} + +func (n *NodeArg) NextSibling() INode { + if n.parent == nil { + return nil + } + i := n.index + 1 + if i < 0 || i >= len(n.parent.Children()) { + return nil + } + return n.parent.Children()[i] +} + +func (n *NodeArg) Parent() INode { + return n.parent +} + +func (n *NodeArg) Index() int { + return n.index +} + +func (n *NodeArg) Children() []INode { + return n.children +} + +func (n *NodeArg) ParamKind() ParameterKind { + return n.paramKind +} + +func (n *NodeArg) IsInside(pos uint32) bool { + return n.start <= pos && pos < n.end +} + +func (n *NodeArg) ArgParamSpec() (ParameterSpec, bool) { + commandNode, ok := n.parent.(INodeCommand) + if !ok { + return ParameterSpec{}, false + } + argIndex := n.index + return commandNode.ParamSpec(argIndex) +} diff --git a/internal/mcfunction/node_arg_chain.go b/internal/mcfunction/node_arg_chain.go new file mode 100644 index 0000000..21c7941 --- /dev/null +++ b/internal/mcfunction/node_arg_chain.go @@ -0,0 +1,120 @@ +package mcfunction + +type NodeArgCommand struct { + *NodeCommand + paramKind ParameterKind +} + +func (n *NodeArgCommand) addChild(child INode) { + child.setParent(n) + child.setIndex(len(n.children)) + n.children = append(n.children, child) +} + +func (n *NodeArgCommand) setParent(parent INode) { + n.parent = parent +} + +func (n *NodeArgCommand) setIndex(index int) { + n.index = index +} + +func (n *NodeArgCommand) Kind() NodeKind { + return NodeKindCommandArg +} + +func (n *NodeArgCommand) Range() (start, end uint32) { + return n.start, n.end +} + +func (n *NodeArgCommand) Text(src []rune) string { + return string(src[n.start:n.end]) +} + +func (n *NodeArgCommand) PrevSibling() INode { + if n.parent == nil || n.index == 0 { + return nil + } + i := n.index - 1 + if i < 0 || i >= len(n.parent.Children()) { + return nil + } + return n.parent.Children()[i] +} + +func (n *NodeArgCommand) NextSibling() INode { + if n.parent == nil { + return nil + } + i := n.index + 1 + if i < 0 || i >= len(n.parent.Children()) { + return nil + } + return n.parent.Children()[i] +} + +func (n *NodeArgCommand) Parent() INode { + return n.parent +} + +func (n *NodeArgCommand) Index() int { + return n.index +} + +func (n *NodeArgCommand) Children() []INode { + return n.children +} + +func (n *NodeArgCommand) ParamKind() ParameterKind { + return n.paramKind +} + +func (n *NodeArgCommand) ArgParamSpec() (ParameterSpec, bool) { + commandNode, ok := n.parent.(INodeCommand) + if !ok { + return ParameterSpec{}, false + } + argIndex := n.index + return commandNode.ParamSpec(argIndex) +} + +func (n *NodeArgCommand) IsInside(pos uint32) bool { + return n.start <= pos && pos < n.end +} + +func (n *NodeArgCommand) CommandName() string { + return n.name +} + +func (n *NodeArgCommand) Args() []INode { + return n.children +} + +func (n *NodeArgCommand) Spec() *Spec { + return n.spec +} + +func (n *NodeArgCommand) OverloadStates() []*overloadState { + return n.overloadStates +} + +func (n *NodeArgCommand) ParamSpec(index int) (ParameterSpec, bool) { + for _, o := range n.overloadStates { + if !o.matched { + continue + } + if index >= 0 && index < len(o.ov.Parameters) { + return o.ov.Parameters[index], true + } + } + return ParameterSpec{}, false +} + +func (n *NodeArgCommand) IsValid() bool { + for _, o := range n.overloadStates { + if o.matched { + return true + } + } + return false +} diff --git a/internal/mcfunction/node_arg_pair.go b/internal/mcfunction/node_arg_pair.go new file mode 100644 index 0000000..4e3bfaf --- /dev/null +++ b/internal/mcfunction/node_arg_pair.go @@ -0,0 +1,207 @@ +package mcfunction + +import ( + "github.com/rockide/language-server/internal/mcfunction/lexer" +) + +type PairKind uint8 + +const ( + PairKindUnknown PairKind = iota + PairKindKey + PairKindEqual + PairKindValue +) + +type INodeArgPair interface { + INodeArg + PairSpec() (ParameterSpec, bool) +} + +type NodeArgPair struct { + *NodeArg + spec ParameterSpec +} + +func (n *NodeArgPair) addChild(child INode) { + child.setParent(n) + child.setIndex(len(n.children)) + n.children = append(n.children, child) +} + +func (n *NodeArgPair) setParent(parent INode) { + n.parent = parent +} + +func (n *NodeArgPair) setIndex(index int) { + n.index = index +} + +func (n *NodeArgPair) PairSpec() (ParameterSpec, bool) { + return n.spec, n.spec.Kind != ParameterKindUnknown +} + +type INodeArgPairChild interface { + INodeArg + PairKind() PairKind + PairSpec() (ParameterSpec, bool) +} + +type NodeArgPairChild struct { + *NodeArg + pairKind PairKind +} + +func (n *NodeArgPairChild) addChild(child INode) { + child.setParent(n) + child.setIndex(len(n.children)) + n.children = append(n.children, child) +} + +func (n *NodeArgPairChild) setParent(parent INode) { + n.parent = parent +} + +func (n *NodeArgPairChild) setIndex(index int) { + n.index = index +} + +func (n *NodeArgPairChild) PairKind() PairKind { + return n.pairKind +} + +func (n *NodeArgPairChild) PairSpec() (ParameterSpec, bool) { + if p, ok := n.parent.(*NodeArgPair); ok { + return p.PairSpec() + } + return ParameterSpec{}, false +} + +func createSelectorArg(input []rune, token lexer.Token) *NodeArg { + value := []rune(token.Text(input)) + if len(value) < 2 || value[0] != '[' || value[len(value)-1] != ']' { + return nil + } + result := &NodeArg{ + Node: &Node{ + kind: NodeKindCommandArg, + start: token.Start, + end: token.End, + }, + paramKind: ParameterKindSelectorArg, + } + if len(value) == 2 { + return result + } + startOffset := token.Start + 1 + value = value[1 : len(value)-1] + lex := lexer.New([]rune(value)) + keyTokens := []lexer.Token{} + var assignToken lexer.Token + valueTokens := []lexer.Token{} + createPair := func() { + tKey := mergeTokens(keyTokens...) + tValue := mergeTokens(valueTokens...) + node := &NodeArgPair{ + NodeArg: &NodeArg{ + Node: &Node{ + kind: NodeKindCommandArg, + start: tKey.Start + startOffset, + end: tValue.End + startOffset, + }, + paramKind: ParameterKindMapPair, + }, + } + key := &NodeArgPairChild{ + NodeArg: &NodeArg{ + Node: &Node{ + kind: NodeKindCommandArg, + start: tKey.Start + startOffset, + end: tKey.End + startOffset, + }, + paramKind: ParameterKindMapPair, + }, + pairKind: PairKindKey, + } + node.addChild(key) + keyValue := key.Text(input) + if spec, ok := SelectorArg[keyValue]; ok { + node.spec = spec + } + node.addChild(&NodeArgPairChild{ + NodeArg: &NodeArg{ + Node: &Node{ + kind: NodeKindCommandArg, + start: assignToken.Start + startOffset, + end: assignToken.End + startOffset, + }, + paramKind: ParameterKindMapPair, + }, + pairKind: PairKindEqual, + }) + node.addChild(&NodeArgPairChild{ + NodeArg: &NodeArg{ + Node: &Node{ + kind: NodeKindCommandArg, + start: tValue.Start + startOffset, + end: tValue.End + startOffset, + }, + paramKind: ParameterKindMapPair, + }, + pairKind: PairKindValue, + }) + keyTokens = []lexer.Token{} + valueTokens = []lexer.Token{} + assignToken = lexer.Token{} + result.addChild(node) + } + state := 0 + for t := range lex.Next() { + if t.Kind == lexer.TokenComment || t.Kind == lexer.TokenWhitespace { + continue + } + switch state { + case 0: + switch t.Kind { + case lexer.TokenEquals: + assignToken = t + state = 1 + case lexer.TokenComma: + continue + default: + keyTokens = append(keyTokens, t) + } + case 1: + if t.Kind == lexer.TokenComma { + state = 0 + } else { + valueTokens = append(valueTokens, t) + } + } + } + if len(keyTokens) > 0 { + createPair() + } + return result +} + +func mergeTokens(tokens ...lexer.Token) lexer.Token { + if len(tokens) == 0 { + return lexer.Token{} + } + start := tokens[0].Start + end := tokens[0].End + for i := 1; i < len(tokens); i++ { + if tokens[i].Start < start { + start = tokens[i].Start + } + if tokens[i].End > end { + end = tokens[i].End + } + } + return lexer.Token{ + Kind: lexer.TokenString, + Start: start, + End: end, + } +} diff --git a/internal/mcfunction/node_command.go b/internal/mcfunction/node_command.go new file mode 100644 index 0000000..124c6ad --- /dev/null +++ b/internal/mcfunction/node_command.go @@ -0,0 +1,79 @@ +package mcfunction + +type INodeCommand interface { + INode + CommandName() string + Args() []INode + Spec() *Spec + OverloadStates() []*overloadState + ParamSpec(index int) (ParameterSpec, bool) + IsValid() bool +} + +type NodeCommand struct { + *Node + name string + spec *Spec + overloadStates []*overloadState +} + +func (n *NodeCommand) addChild(child INode) { + child.setParent(n) + child.setIndex(len(n.children)) + n.children = append(n.children, child) +} + +func (n *NodeCommand) setParent(parent INode) { + n.parent = parent +} + +func (n *NodeCommand) setIndex(index int) { + n.index = index +} + +func (n *NodeCommand) CommandName() string { + return n.name +} + +func (n *NodeCommand) Args() []INode { + if len(n.children) == 0 { + return nil + } + first := n.children[0] + if first.Kind() != NodeKindCommandLit { + return n.children + } + return n.children[1:] +} + +func (n *NodeCommand) Spec() *Spec { + return n.spec +} + +func (n *NodeCommand) OverloadStates() []*overloadState { + return n.overloadStates +} + +func (n *NodeCommand) ParamSpec(index int) (ParameterSpec, bool) { + for _, o := range n.overloadStates { + if !o.matched { + continue + } + if index >= 0 && index < len(o.ov.Parameters) { + return o.ov.Parameters[index], true + } + } + return ParameterSpec{}, false +} + +func (n *NodeCommand) IsValid() bool { + if n.Kind() == NodeKindInvalidCommand { + return false + } + for _, o := range n.overloadStates { + if o.matched { + return true + } + } + return false +} diff --git a/internal/mcfunction/overload_state.go b/internal/mcfunction/overload_state.go new file mode 100644 index 0000000..0f1ad45 --- /dev/null +++ b/internal/mcfunction/overload_state.go @@ -0,0 +1,365 @@ +package mcfunction + +import ( + "fmt" + "math" + "slices" + "strconv" + "strings" + + "github.com/rockide/language-server/internal/mcfunction/lexer" +) + +type overloadState struct { + spec *Spec + ov *SpecOverload + index int + matched bool // Indicates if any parameter has been matched or partially matched + options ParserOptions + commands map[string]*Spec + eol uint32 +} + +func (o *overloadState) Peek() (ParameterSpec, bool) { + if o.eof() { + return ParameterSpec{}, false + } + return o.ov.Parameters[o.index], true +} + +func (o *overloadState) Matched() bool { + return o.matched +} + +func (o *overloadState) Index() int { + return o.index +} + +func (o *overloadState) Parameters() []ParameterSpec { + return o.ov.Parameters +} + +func (o *overloadState) ParamAt(index int) (ParameterSpec, bool) { + if index < 0 || index >= len(o.ov.Parameters) { + return ParameterSpec{}, false + } + return o.ov.Parameters[index], true +} + +func (o *overloadState) eof() bool { + return o.index >= len(o.ov.Parameters) +} + +func (o *overloadState) advance() { + o.index++ +} + +func (o *overloadState) parse(input []rune, tokens []lexer.Token) ([]INodeArg, error) { + if len(tokens) > 0 && o.eof() { + return nil, fmt.Errorf("unexpected extra arguments") + } + if len(tokens) == 0 { + if param, ok := o.Peek(); !ok || param.Optional { + return nil, nil + } else if ok && !param.Optional { + return nil, fmt.Errorf("missing required arguments") + } + } + args := []INodeArg{} + tokenIndex := 0 + for tokenIndex < len(tokens) { + param, ok := o.Peek() + if !ok { + o.matched = false + return args, fmt.Errorf("excess arguments") + } + if param.Greedy { + for ; tokenIndex < len(tokens); tokenIndex++ { + arg, _, err := o.matchParameter(input, tokens, tokenIndex, param) + if err != nil { + break + } + args = append(args, arg) + o.matched = true + } + break + } + + arg, consumed, err := o.matchParameter(input, tokens, tokenIndex, param) + if err != nil { + o.matched = false + break + } + args = append(args, arg) + o.advance() + tokenIndex += consumed + } + if !o.matched { + return args, fmt.Errorf("no overload matched") + } + return args, nil +} + +func (o *overloadState) matchParameter(input []rune, tokens []lexer.Token, tokenIndex int, param ParameterSpec) (INodeArg, int, error) { + token := tokens[tokenIndex] + text := token.Text(input) + arg := &NodeArg{ + Node: &Node{ + kind: NodeKindCommandArg, + start: token.Start, + end: token.End, + }, + paramKind: param.Kind, + } + switch param.Kind { + case ParameterKindLiteral: + if slices.Contains(param.Literals, token.Text(input)) { + return arg, 1, nil + } + case ParameterKindString: + return arg, 1, nil + case ParameterKindNumber: + if token.Kind == lexer.TokenNumber { + return arg, 1, nil + } + case ParameterKindInteger: + if token.Kind == lexer.TokenNumber { + // Strictly integer check, not allowing decimal point + if !strings.Contains(text, ".") { + return arg, 1, nil + } + } + case ParameterKindBoolean: + if text == "true" || text == "false" { + return arg, 1, nil + } + case ParameterKindSelector: + if token.Kind == lexer.TokenSelector { + selector := text[1:] // remove '@' + validSelectors := getSelectors(o.options) + if _, ok := validSelectors[selector]; ok { + advance := 1 + // Check for selector arguments + if tokenIndex+1 < len(tokens) && tokens[tokenIndex+1].Kind == lexer.TokenMap { + next := tokens[tokenIndex+1] + advance = 2 + selArg := createSelectorArg(input, next) + if selArg == nil { + arg.addChild(&NodeArg{ + Node: &Node{ + kind: NodeKindCommandArg, + start: next.Start, + end: next.End, + }, + paramKind: ParameterKindSelectorArg, + }) + } + arg.addChild(selArg) + arg.Node.end = tokens[tokenIndex+1].End + } + return arg, advance, nil + } + } + case ParameterKindMap: + if token.Kind == lexer.TokenMap { + // TODO: + return arg, 1, nil + } + case ParameterKindJSON: + if token.Kind == lexer.TokenJSON { + return arg, 1, nil + } + case ParameterKindVector2, ParameterKindVector3: + size := 2 + if param.Kind == ParameterKindVector3 { + size = 3 + } + if tokenIndex+size-1 < len(tokens) { + if isValidRelatives(input, tokens[tokenIndex:tokenIndex+size]...) { + for i := range make([]int, size) { + arg.addChild(&NodeArg{ + Node: &Node{ + kind: NodeKindCommandArg, + start: tokens[tokenIndex+i].Start, + end: tokens[tokenIndex+i].End, + }, + paramKind: ParameterKindRelativeNumber, + }) + } + arg.Node.end = tokens[tokenIndex+size-1].End + return arg, size, nil + } + } + case ParameterKindRange: + // 1. Number, Range, Number + if matchTokens(tokens, tokenIndex, lexer.TokenNumber, lexer.TokenRange, lexer.TokenNumber) { + arg.Node.end = tokens[tokenIndex+2].End + return arg, 3, nil + } + // 2. Range, Number + if matchTokens(tokens, tokenIndex, lexer.TokenRange, lexer.TokenNumber) { + arg.Node.end = tokens[tokenIndex+1].End + return arg, 2, nil + } + // 3. Number, Range + if matchTokens(tokens, tokenIndex, lexer.TokenNumber, lexer.TokenRange) { + arg.Node.end = tokens[tokenIndex+1].End + return arg, 2, nil + } + // 4. Bang, Number, Range, Number + if matchTokens(tokens, tokenIndex, lexer.TokenBang, lexer.TokenNumber, lexer.TokenRange, lexer.TokenNumber) { + arg.Node.start = tokens[tokenIndex].Start + arg.Node.end = tokens[tokenIndex+3].End + return arg, 4, nil + } + // 5. Bang, Range, Number + if matchTokens(tokens, tokenIndex, lexer.TokenBang, lexer.TokenRange, lexer.TokenNumber) { + arg.Node.start = tokens[tokenIndex].Start + arg.Node.end = tokens[tokenIndex+2].End + return arg, 3, nil + } + // 6. Bang, Number, Range + if matchTokens(tokens, tokenIndex, lexer.TokenBang, lexer.TokenNumber, lexer.TokenRange) { + arg.Node.start = tokens[tokenIndex].Start + arg.Node.end = tokens[tokenIndex+2].End + return arg, 3, nil + } + case ParameterKindSuffixedInteger: + if token.Kind == lexer.TokenNumber && !strings.Contains(text, ".") && tokenIndex+1 < len(tokens) { + suffixToken := tokens[tokenIndex+1] + suffix := param.Suffix + suffixText := suffixToken.Text(input) + if suffixText == suffix { + arg.Node.end = suffixToken.End + return arg, 2, nil + } + } + case ParameterKindWildcardInteger: + _, err := strconv.Atoi(text) + if token.Text(input) == "*" || (err == nil && !strings.Contains(text, ".")) { + return arg, 1, nil + } + case ParameterKindChainedCommand: + arg := &NodeArgCommand{ + NodeCommand: &NodeCommand{ + Node: &Node{ + kind: NodeKindCommandArg, + start: token.Start, + end: o.eol, + }, + name: o.spec.Name, + spec: o.spec, + }, + paramKind: ParameterKindChainedCommand, + } + rest := tokens[tokenIndex:] + if len(rest) == 0 { + return arg, 1, nil + } + overloadStates := make([]*overloadState, 0, len(o.spec.Overloads)) + for i := range o.spec.Overloads { + state := &overloadState{ + spec: o.spec, + ov: &o.spec.Overloads[i], + options: o.options, + commands: o.commands, + matched: true, + eol: o.eol, + } + overloadStates = append(overloadStates, state) + args, _ := state.parse(input, rest) + if state.matched { + arg.children = make([]INode, 0, len(args)) + for _, a := range args { + arg.addChild(a) + } + } + } + if len(arg.children) == 0 { + for i := range rest { + arg.addChild(&NodeArg{ + Node: &Node{ + kind: NodeKindCommandArg, + start: rest[i].Start, + end: rest[i].End, + }, + }) + } + } + arg.overloadStates = overloadStates + return arg, math.MaxInt32, nil + case ParameterKindCommand: + rest := tokens[tokenIndex:] + commandNode := parseCommand(rest, input, o.commands, o.options, o.eol) + arg := &NodeArgCommand{ + NodeCommand: commandNode, + paramKind: ParameterKindCommand, + } + return arg, math.MaxInt32, nil + case ParameterKindRawMessage, ParameterKindItemNbt: + if token.Kind == lexer.TokenJSON { + return arg, 1, nil + } + case ParameterKindRelativeNumber: + if token.Kind == lexer.TokenRelativeNumber || token.Kind == lexer.TokenNumber { + return arg, 1, nil + } + } + return nil, 0, fmt.Errorf("parameter did not match") +} + +func isValidRelatives(input []rune, tokens ...lexer.Token) bool { + var b byte + for _, token := range tokens { + if token.Kind != lexer.TokenRelativeNumber && token.Kind != lexer.TokenNumber { + return false + } + if f := token.Text(input)[0]; f == '~' || f == '^' { + if b == 0 { + b = f + } else if b != f { + return false + } + } + } + return true +} + +func getSelectors(options ParserOptions) map[string]bool { + res := map[string]bool{ + "p": true, + "a": true, + "r": true, + "s": true, + "e": true, + "n": true, + "initiator": true, + "c": true, + "v": true, + } + for sel := range res { + if sel == "initiator" && !options.InitiatorSelector { + res[sel] = false + continue + } + if sel == "c" || sel == "v" { + if !options.EducationMode { + res[sel] = false + continue + } + } + } + return res +} + +func matchTokens(tokens []lexer.Token, index int, kinds ...lexer.TokenKind) bool { + if index+len(kinds) > len(tokens) { + return false + } + for i, kind := range kinds { + if tokens[index+i].Kind != kind { + return false + } + } + return true +} diff --git a/internal/mcfunction/parser.go b/internal/mcfunction/parser.go new file mode 100644 index 0000000..681f1d1 --- /dev/null +++ b/internal/mcfunction/parser.go @@ -0,0 +1,159 @@ +package mcfunction + +import ( + "fmt" + + "github.com/rockide/language-server/internal/mcfunction/lexer" +) + +type Parser struct { + lexer *lexer.Lexer + commands map[string]*Spec + options ParserOptions +} + +type ParserOptions struct { + InitiatorSelector bool // enables @initiator selector + EducationMode bool // enables education edition specific commands and arguments +} + +func NewParser(options ParserOptions, commands ...*Spec) *Parser { + return &Parser{ + lexer: lexer.New([]rune{}), + commands: make(map[string]*Spec), + options: options, + } +} + +func (p *Parser) RegisterCommands(specs ...*Spec) { + for _, spec := range specs { + p.commands[spec.Name] = spec + for _, alias := range spec.Aliases { + p.commands[alias] = spec + } + } +} + +func (p *Parser) RegisteredCommands() map[string]*Spec { + return p.commands +} + +func (p *Parser) GetSelectors() map[string]bool { + return getSelectors(p.options) +} + +func (p *Parser) Parse(input []rune) (INode, error) { + if len(p.commands) == 0 { + return nil, fmt.Errorf("no commands registered") + } + p.lexer.Reset(input) + root := &Node{} + tokens := []lexer.Token{} + eol := uint32(0) + parse := func() { + if len(tokens) == 0 { + return + } + node := parseCommand(tokens, input, p.commands, p.options, eol) + node.end = eol + root.addChild(node) + } + for token := range p.lexer.Next() { + eol = token.End + switch token.Kind { + case lexer.TokenWhitespace: + continue + case lexer.TokenComment: + root.addChild(&Node{ + kind: NodeKindComment, + start: token.Start, + end: token.End, + }) + case lexer.TokenNewline: + parse() + tokens = []lexer.Token{} + default: + tokens = append(tokens, token) + } + } + parse() + root.end = uint32(len(input)) + return root, nil +} + +func parseCommand(tokens []lexer.Token, input []rune, commands map[string]*Spec, options ParserOptions, eol uint32) *NodeCommand { + first := tokens[0] + commandInput := first.Text(input) + spec, ok := commands[commandInput] + node := &NodeCommand{ + Node: &Node{ + kind: NodeKindInvalidCommand, + start: first.Start, + end: eol, + }, + } + addDefaultArgs := func() { + for i := 1; i < len(tokens); i++ { + node.addChild(&NodeArg{ + Node: &Node{ + kind: NodeKindCommandArg, + start: tokens[i].Start, + end: tokens[i].End, + }, + }) + } + } + node.addChild(&Node{ + kind: NodeKindCommandLit, + start: first.Start, + end: first.End, + }) + if !ok { + node.name = commandInput + addDefaultArgs() + return node + } + if len(spec.Overloads) == 0 && len(tokens) > 1 { + // Immediately invalidate if no overloads exist but arguments are provided + node.name = commandInput + node.spec = spec + addDefaultArgs() + return node + } + if len(spec.Overloads) == 0 && len(tokens) == 1 { + node.kind = NodeKindCommand + node.name = commandInput + node.spec = spec + return node + } + overloadStates := make([]*overloadState, len(spec.Overloads)) + for i := range spec.Overloads { + state := &overloadState{ + spec: spec, + ov: &spec.Overloads[i], + options: options, + commands: commands, + matched: true, + eol: eol, + } + overloadStates[i] = state + args, _ := state.parse(input, tokens[1:]) + if state.matched { + node.kind = NodeKindCommand + node.name = commandInput + node.spec = spec + node.children = make([]INode, 0, len(args)) + for _, arg := range args { + node.addChild(arg) + } + } + } + if node.kind == NodeKindInvalidCommand { + node.name = commandInput + node.spec = spec + addDefaultArgs() + } else { + node.overloadStates = overloadStates + } + return node +} diff --git a/internal/mcfunction/selector_arg.go b/internal/mcfunction/selector_arg.go new file mode 100644 index 0000000..eae2411 --- /dev/null +++ b/internal/mcfunction/selector_arg.go @@ -0,0 +1,107 @@ +package mcfunction + +var SelectorArg = map[string]ParameterSpec{ + "c": { + Kind: ParameterKindNumber, + }, + "dx": { + Kind: ParameterKindRelativeNumber, + }, + "dy": { + Kind: ParameterKindRelativeNumber, + }, + "dz": { + Kind: ParameterKindRelativeNumber, + }, + "family": { + Kind: ParameterKindString, + Tags: []string{TagTypeFamilyId}, + }, + // TODO: This + // "has_property": { + // Kind: ParameterKindJSON, + // }, + // TODO: This + // "hasitem": { + // data: integer + // item: string + // location: slot location + // quantity: integer range + // slot: integer range + // Kind: ParameterKindJSON, + // }, + // TODO: This + // "haspermission": { + // = + // Kind: ParameterKindJSON, + // }, + "l": { + Kind: ParameterKindInteger, + }, + "lm": { + Kind: ParameterKindInteger, + }, + "m": { + Kind: ParameterKindLiteral, + Literals: []string{ + "a", + "adventure", + "c", + "creative", + "d", + "default", + "s", + "spectator", + "survival", + "!a", + "!adventure", + "!c", + "!creative", + "!d", + "!default", + "!s", + "!spectator", + "!survival", + }, + }, + "name": { + Kind: ParameterKindString, + }, + "r": { + Kind: ParameterKindNumber, + }, + "rm": { + Kind: ParameterKindNumber, + }, + "rx": { + Kind: ParameterKindRelativeNumber, + }, + "rxm": { + Kind: ParameterKindRelativeNumber, + }, + "ry": { + Kind: ParameterKindRelativeNumber, + }, + "rym": { + Kind: ParameterKindRelativeNumber, + }, + // TODO: This + // "scores": { + // }, + "tag": { + Kind: ParameterKindString, + }, + "type": { + Kind: ParameterKindString, + Tags: []string{TagTypeFamilyId}, + }, + "x": { + Kind: ParameterKindRelativeNumber, + }, + "y": { + Kind: ParameterKindRelativeNumber, + }, + "z": { + Kind: ParameterKindRelativeNumber, + }, +} diff --git a/internal/mcfunction/spec.go b/internal/mcfunction/spec.go new file mode 100644 index 0000000..fe41a66 --- /dev/null +++ b/internal/mcfunction/spec.go @@ -0,0 +1,107 @@ +package mcfunction + +type Spec struct { + Name string + Aliases []string + Description string + Overloads []SpecOverload +} + +type SpecOverload struct { + Parameters []ParameterSpec +} + +type ParameterKind int8 + +const ( + ParameterKindUnknown ParameterKind = iota + ParameterKindLiteral // fixed set of string literals + ParameterKindString // arbitrary string + ParameterKindNumber // allows float + ParameterKindInteger // strictly integer + ParameterKindBoolean // true or false + ParameterKindSelector // @p, @a, @r, @s, @e, @n, @initiator + ParameterKindSelectorArg // selector arguments + ParameterKindMap // [key=value,...] + ParameterKindJSON // JSON object or array + ParameterKindVector2 // x y or rotX rotY + ParameterKindVector3 // x y z + // Misc + ParameterKindRange // start..end + ParameterKindSuffixedInteger // int with suffix like 10L, 10D, 10S, 10T. + ParameterKindWildcardInteger // * or number + ParameterKindChainedCommand // chained command + ParameterKindCommand // commands + ParameterKindRawMessage + ParameterKindItemNbt // item NBT data + ParameterKindRelativeNumber // ~number or ^number (part of vector) + ParameterKindMapPair // key=value (only as part of map) +) + +type Tag string + +const ( + TagAimAssistId = "aim_assist_id" + TagBiomeId = "biome_id" + TagBlockId = "block_id" + TagBlockState = "block_state" + TagCameraId = "camera_id" + TagClientAnimationId = "client_animation_id" + TagDialogueId = "dialogue_id" + TagDimensionId = "dimension_id" + TagEntityEvent = "entity_event" + TagEntityId = "entity_id" + TagExecuteChain = "execute_chain" + TagTypeFamilyId = "type_family_id" + TagFeatureId = "feature_id" + TagFeatureRuleId = "feature_rule_id" + TagFogId = "fog_id" + TagFunctionFile = "function_file" + TagItemId = "item_id" + TagJigsawId = "jigsaw_id" + TagJigsawTemplatePoolId = "jigsaw_template_pool_id" + TagLootTableFile = "loot_table_file" + TagMolang = "molang" + TagMusicId = "music_id" + TagParticleId = "particle_id" + TagPitch = "pitch" + TagProvidedFogId = "provided_fog_id" + TagRecipeId = "recipe_id" + TagScoreboardObjectiveId = "scoreboard_objective_id" + TagScriptEventId = "script_event_id" + TagSoundId = "sound_definition_id" + TagStructureFile = "structure_file" + TagTagId = "tag" + TagTickingAreaId = "ticking_area_id" + TagYaw = "yaw" +) + +type ParameterSpec struct { + Kind ParameterKind + Name string + Optional bool + Literals []string // only for ParameterKindLiteral + Range *NumberRange // For number, integer, and range + Tags []string + Greedy bool // only for KindString + Suffix string // only for KindSuffixedInteger +} + +func (p ParameterSpec) ToString() string { + s := p.Name + if len(p.Literals) == 1 && p.Kind == ParameterKindLiteral { + if !p.Optional { + return p.Literals[0] + } + s = p.Literals[0] + } + if p.Optional { + return "[" + s + "]" + } + return "<" + s + ">" +} + +type NumberRange struct { + Min float64 + Max float64 +} diff --git a/internal/mcfunction/util.go b/internal/mcfunction/util.go new file mode 100644 index 0000000..7e93a64 --- /dev/null +++ b/internal/mcfunction/util.go @@ -0,0 +1,27 @@ +package mcfunction + +func WalkNodeTree(root INode, fn func(INode) bool) { + if !fn(root) { + return + } + for _, child := range root.Children() { + WalkNodeTree(child, fn) + } +} + +func IsInside(n INode, pos uint32) bool { + start, end := n.Range() + return pos >= start && pos <= end +} + +func NodeAt(root INode, pos uint32) INode { + var result INode + WalkNodeTree(root, func(n INode) bool { + matched := IsInside(n, pos) + if matched { + result = n + } + return true + }) + return result +} diff --git a/internal/mcfunction/vanilla/aimassist.go b/internal/mcfunction/vanilla/aimassist.go new file mode 100644 index 0000000..9e9384c --- /dev/null +++ b/internal/mcfunction/vanilla/aimassist.go @@ -0,0 +1,63 @@ +package vanilla + +import "github.com/rockide/language-server/internal/mcfunction" + +var Aimassist = &mcfunction.Spec{ + Name: "aimassist", + Description: "Enable Aim Assist", + Overloads: []mcfunction.SpecOverload{ + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindSelector, + Name: "players", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "set", + Literals: []string{"set"}, + }, + { + Kind: mcfunction.ParameterKindNumber, + Name: "x angle", + Optional: true, + }, + { + Kind: mcfunction.ParameterKindNumber, + Name: "y angle", + Optional: true, + }, + { + Kind: mcfunction.ParameterKindNumber, + Name: "max distance", + Optional: true, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "target mode", + Optional: true, + Literals: []string{"angle", "distance"}, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "preset id", + Optional: true, + Tags: []string{mcfunction.TagAimAssistId}, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindSelector, + Name: "players", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "clear", + Literals: []string{"clear"}, + }, + }, + }, + }, +} diff --git a/internal/mcfunction/vanilla/camera.go b/internal/mcfunction/vanilla/camera.go new file mode 100644 index 0000000..b11db18 --- /dev/null +++ b/internal/mcfunction/vanilla/camera.go @@ -0,0 +1,1531 @@ +package vanilla + +import "github.com/rockide/language-server/internal/mcfunction" + +var easeLiterals = []string{ + "linear", + "spring", + "in_quad", + "out_quad", + "in_out_quad", + "in_cubic", + "out_cubic", + "in_out_cubic", + "in_quart", + "out_quart", + "in_out_quart", + "in_quint", + "out_quint", + "in_out_quint", + "in_sine", + "out_sine", + "in_out_sine", + "in_expo", + "out_expo", + "in_out_expo", + "in_circ", + "out_circ", + "in_out_circ", + "in_bounce", + "out_bounce", + "in_out_bounce", + "in_back", + "out_back", + "in_out_back", + "in_elastic", + "out_elastic", + "in_out_elastic", +} + +var ease = mcfunction.ParameterSpec{ + Kind: mcfunction.ParameterKindLiteral, + Name: "ease", + Literals: easeLiterals, +} + +var colorRange = &mcfunction.NumberRange{ + Min: 0, + Max: 255, +} + +var Camera = &mcfunction.Spec{ + Name: "camera", + Description: "Issues a camera instruction", + Overloads: []mcfunction.SpecOverload{ + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindSelector, + Name: "players", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "set", + Literals: []string{"set"}, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "preset", + Tags: []string{mcfunction.TagAimAssistId}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "ease", + Literals: []string{"ease"}, + }, + { + Kind: mcfunction.ParameterKindNumber, + Name: "easeTime", + }, + ease, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "pos", + Literals: []string{"pos"}, + }, + { + Kind: mcfunction.ParameterKindVector3, + Name: "position", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "rot", + Literals: []string{"rot"}, + }, + { + Kind: mcfunction.ParameterKindRelativeNumber, + Name: "xRot", + Tags: []string{mcfunction.TagPitch}, + }, + { + Kind: mcfunction.ParameterKindRelativeNumber, + Name: "yRot", + Tags: []string{mcfunction.TagYaw}, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindSelector, + Name: "players", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "set", + Literals: []string{"set"}, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "preset", + Tags: []string{mcfunction.TagAimAssistId}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "ease", + Literals: []string{"ease"}, + }, + { + Kind: mcfunction.ParameterKindNumber, + Name: "easeTime", + }, + ease, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "pos", + Literals: []string{"pos"}, + }, + { + Kind: mcfunction.ParameterKindVector3, + Name: "position", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "facing", + Literals: []string{"facing"}, + }, + { + Kind: mcfunction.ParameterKindSelector, + Name: "lookAtEntity", + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindSelector, + Name: "players", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "set", + Literals: []string{"set"}, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "preset", + Tags: []string{mcfunction.TagAimAssistId}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "ease", + Literals: []string{"ease"}, + }, + { + Kind: mcfunction.ParameterKindNumber, + Name: "easeTime", + }, + ease, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "pos", + Literals: []string{"pos"}, + }, + { + Kind: mcfunction.ParameterKindVector3, + Name: "position", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "facing", + Literals: []string{"facing"}, + }, + { + Kind: mcfunction.ParameterKindVector3, + Name: "lookAtPosition", + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindSelector, + Name: "players", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "set", + Literals: []string{"set"}, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "preset", + Tags: []string{mcfunction.TagAimAssistId}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "ease", + Literals: []string{"ease"}, + }, + { + Kind: mcfunction.ParameterKindNumber, + Name: "easeTime", + }, + ease, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "pos", + Literals: []string{"pos"}, + }, + { + Kind: mcfunction.ParameterKindVector3, + Name: "position", + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindSelector, + Name: "players", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "set", + Literals: []string{"set"}, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "preset", + Tags: []string{mcfunction.TagAimAssistId}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "ease", + Literals: []string{"ease"}, + }, + { + Kind: mcfunction.ParameterKindNumber, + Name: "easeTime", + }, + ease, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "rot", + Literals: []string{"rot"}, + }, + { + Kind: mcfunction.ParameterKindRelativeNumber, + Name: "xRot", + Tags: []string{mcfunction.TagPitch}, + }, + { + Kind: mcfunction.ParameterKindRelativeNumber, + Name: "yRot", + Tags: []string{mcfunction.TagYaw}, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindSelector, + Name: "players", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "set", + Literals: []string{"set"}, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "preset", + Tags: []string{mcfunction.TagAimAssistId}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "ease", + Literals: []string{"ease"}, + }, + { + Kind: mcfunction.ParameterKindNumber, + Name: "easeTime", + }, + ease, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "facing", + Literals: []string{"facing"}, + }, + { + Kind: mcfunction.ParameterKindSelector, + Name: "lookAtEntity", + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindSelector, + Name: "players", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "set", + Literals: []string{"set"}, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "preset", + Tags: []string{mcfunction.TagAimAssistId}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "ease", + Literals: []string{"ease"}, + }, + { + Kind: mcfunction.ParameterKindNumber, + Name: "easeTime", + }, + ease, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "facing", + Literals: []string{"facing"}, + }, + { + Kind: mcfunction.ParameterKindVector3, + Name: "lookAtPosition", + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindSelector, + Name: "players", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "set", + Literals: []string{"set"}, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "preset", + Tags: []string{mcfunction.TagAimAssistId}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "ease", + Literals: []string{"ease"}, + }, + { + Kind: mcfunction.ParameterKindNumber, + Name: "easeTime", + }, + ease, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "default", + Optional: true, + Literals: []string{"default"}, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindSelector, + Name: "players", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "set", + Literals: []string{"set"}, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "preset", + Tags: []string{mcfunction.TagAimAssistId}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "pos", + Literals: []string{"pos"}, + }, + { + Kind: mcfunction.ParameterKindVector3, + Name: "position", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "rot", + Literals: []string{"rot"}, + }, + { + Kind: mcfunction.ParameterKindRelativeNumber, + Name: "xRot", + Tags: []string{mcfunction.TagPitch}, + }, + { + Kind: mcfunction.ParameterKindRelativeNumber, + Name: "yRot", + Tags: []string{mcfunction.TagYaw}, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindSelector, + Name: "players", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "set", + Literals: []string{"set"}, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "preset", + Tags: []string{mcfunction.TagAimAssistId}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "pos", + Literals: []string{"pos"}, + }, + { + Kind: mcfunction.ParameterKindVector3, + Name: "position", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "facing", + Literals: []string{"facing"}, + }, + { + Kind: mcfunction.ParameterKindSelector, + Name: "lookAtEntity", + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindSelector, + Name: "players", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "set", + Literals: []string{"set"}, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "preset", + Tags: []string{mcfunction.TagAimAssistId}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "pos", + Literals: []string{"pos"}, + }, + { + Kind: mcfunction.ParameterKindVector3, + Name: "position", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "facing", + Literals: []string{"facing"}, + }, + { + Kind: mcfunction.ParameterKindVector3, + Name: "lookAtPosition", + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindSelector, + Name: "players", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "attach_to_entity", + Literals: []string{"attach_to_entity"}, + }, + { + Kind: mcfunction.ParameterKindSelector, + Name: "entity", + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindSelector, + Name: "players", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "detach_from_entity", + Literals: []string{"detach_from_entity"}, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindSelector, + Name: "players", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "targetEntity", + Literals: []string{"target_entity"}, + }, + { + Kind: mcfunction.ParameterKindSelector, + Name: "entity", + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindSelector, + Name: "players", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "targetEntity", + Literals: []string{"target_entity"}, + }, + { + Kind: mcfunction.ParameterKindSelector, + Name: "entity", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "targetCenterOffset", + Literals: []string{"targetCenterOffset"}, + }, + { + Kind: mcfunction.ParameterKindNumber, + Name: "xTargetCenterOffset", + }, + { + Kind: mcfunction.ParameterKindNumber, + Name: "yTargetCenterOffset", + }, + { + Kind: mcfunction.ParameterKindNumber, + Name: "zTargetCenterOffset", + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindSelector, + Name: "players", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "removeTarget", + Literals: []string{"remove_target"}, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindSelector, + Name: "players", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "set", + Literals: []string{"set"}, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "preset", + Tags: []string{mcfunction.TagAimAssistId}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "view_offset", + Literals: []string{"view_offset"}, + }, + { + Kind: mcfunction.ParameterKindNumber, + Name: "xViewOffset", + }, + { + Kind: mcfunction.ParameterKindNumber, + Name: "yViewOffset", + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindSelector, + Name: "players", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "set", + Literals: []string{"set"}, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "preset", + Tags: []string{mcfunction.TagAimAssistId}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "entity_offset", + Literals: []string{"entity_offset"}, + }, + { + Kind: mcfunction.ParameterKindNumber, + Name: "xEntityOffset", + }, + { + Kind: mcfunction.ParameterKindNumber, + Name: "yEntityOffset", + }, + { + Kind: mcfunction.ParameterKindNumber, + Name: "zEntityOffset", + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindSelector, + Name: "players", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "set", + Literals: []string{"set"}, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "preset", + Tags: []string{mcfunction.TagAimAssistId}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "rot", + Literals: []string{"rot"}, + }, + { + Kind: mcfunction.ParameterKindRelativeNumber, + Name: "xRot", + Tags: []string{mcfunction.TagPitch}, + }, + { + Kind: mcfunction.ParameterKindRelativeNumber, + Name: "yRot", + Tags: []string{mcfunction.TagYaw}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "view_offset", + Literals: []string{"view_offset"}, + }, + { + Kind: mcfunction.ParameterKindNumber, + Name: "xViewOffset", + }, + { + Kind: mcfunction.ParameterKindNumber, + Name: "yViewOffset", + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindSelector, + Name: "players", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "set", + Literals: []string{"set"}, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "preset", + Tags: []string{mcfunction.TagAimAssistId}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "rot", + Literals: []string{"rot"}, + }, + { + Kind: mcfunction.ParameterKindRelativeNumber, + Name: "xRot", + Tags: []string{mcfunction.TagPitch}, + }, + { + Kind: mcfunction.ParameterKindRelativeNumber, + Name: "yRot", + Tags: []string{mcfunction.TagYaw}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "entity_offset", + Literals: []string{"entity_offset"}, + }, + { + Kind: mcfunction.ParameterKindNumber, + Name: "xEntityOffset", + }, + { + Kind: mcfunction.ParameterKindNumber, + Name: "yEntityOffset", + }, + { + Kind: mcfunction.ParameterKindNumber, + Name: "zEntityOffset", + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindSelector, + Name: "players", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "set", + Literals: []string{"set"}, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "preset", + Tags: []string{mcfunction.TagAimAssistId}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "view_offset", + Literals: []string{"view_offset"}, + }, + { + Kind: mcfunction.ParameterKindNumber, + Name: "xViewOffset", + }, + { + Kind: mcfunction.ParameterKindNumber, + Name: "yViewOffset", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "entity_offset", + Literals: []string{"entity_offset"}, + }, + { + Kind: mcfunction.ParameterKindNumber, + Name: "xEntityOffset", + }, + { + Kind: mcfunction.ParameterKindNumber, + Name: "yEntityOffset", + }, + { + Kind: mcfunction.ParameterKindNumber, + Name: "zEntityOffset", + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindSelector, + Name: "players", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "set", + Literals: []string{"set"}, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "preset", + Tags: []string{mcfunction.TagAimAssistId}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "rot", + Literals: []string{"rot"}, + }, + { + Kind: mcfunction.ParameterKindRelativeNumber, + Name: "xRot", + Tags: []string{mcfunction.TagPitch}, + }, + { + Kind: mcfunction.ParameterKindRelativeNumber, + Name: "yRot", + Tags: []string{mcfunction.TagYaw}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "view_offset", + Literals: []string{"view_offset"}, + }, + { + Kind: mcfunction.ParameterKindNumber, + Name: "xViewOffset", + }, + { + Kind: mcfunction.ParameterKindNumber, + Name: "yViewOffset", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "entity_offset", + Literals: []string{"entity_offset"}, + }, + { + Kind: mcfunction.ParameterKindNumber, + Name: "xEntityOffset", + }, + { + Kind: mcfunction.ParameterKindNumber, + Name: "yEntityOffset", + }, + { + Kind: mcfunction.ParameterKindNumber, + Name: "zEntityOffset", + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindSelector, + Name: "players", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "set", + Literals: []string{"set"}, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "preset", + Tags: []string{mcfunction.TagAimAssistId}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "ease", + Literals: []string{"ease"}, + }, + { + Kind: mcfunction.ParameterKindNumber, + Name: "easeTime", + }, + ease, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "view_offset", + Literals: []string{"view_offset"}, + }, + { + Kind: mcfunction.ParameterKindNumber, + Name: "xViewOffset", + }, + { + Kind: mcfunction.ParameterKindNumber, + Name: "yViewOffset", + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindSelector, + Name: "players", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "set", + Literals: []string{"set"}, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "preset", + Tags: []string{mcfunction.TagAimAssistId}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "ease", + Literals: []string{"ease"}, + }, + { + Kind: mcfunction.ParameterKindNumber, + Name: "easeTime", + }, + ease, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "entity_offset", + Literals: []string{"entity_offset"}, + }, + { + Kind: mcfunction.ParameterKindNumber, + Name: "xEntityOffset", + }, + { + Kind: mcfunction.ParameterKindNumber, + Name: "yEntityOffset", + }, + { + Kind: mcfunction.ParameterKindNumber, + Name: "zEntityOffset", + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindSelector, + Name: "players", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "set", + Literals: []string{"set"}, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "preset", + Tags: []string{mcfunction.TagAimAssistId}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "ease", + Literals: []string{"ease"}, + }, + { + Kind: mcfunction.ParameterKindNumber, + Name: "easeTime", + }, + ease, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "rot", + Literals: []string{"rot"}, + }, + { + Kind: mcfunction.ParameterKindRelativeNumber, + Name: "xRot", + Tags: []string{mcfunction.TagPitch}, + }, + { + Kind: mcfunction.ParameterKindRelativeNumber, + Name: "yRot", + Tags: []string{mcfunction.TagYaw}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "view_offset", + Literals: []string{"view_offset"}, + }, + { + Kind: mcfunction.ParameterKindNumber, + Name: "xViewOffset", + }, + { + Kind: mcfunction.ParameterKindNumber, + Name: "yViewOffset", + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindSelector, + Name: "players", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "set", + Literals: []string{"set"}, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "preset", + Tags: []string{mcfunction.TagAimAssistId}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "ease", + Literals: []string{"ease"}, + }, + { + Kind: mcfunction.ParameterKindNumber, + Name: "easeTime", + }, + ease, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "rot", + Literals: []string{"rot"}, + }, + { + Kind: mcfunction.ParameterKindRelativeNumber, + Name: "xRot", + Tags: []string{mcfunction.TagPitch}, + }, + { + Kind: mcfunction.ParameterKindRelativeNumber, + Name: "yRot", + Tags: []string{mcfunction.TagYaw}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "entity_offset", + Literals: []string{"entity_offset"}, + }, + { + Kind: mcfunction.ParameterKindNumber, + Name: "xEntityOffset", + }, + { + Kind: mcfunction.ParameterKindNumber, + Name: "yEntityOffset", + }, + { + Kind: mcfunction.ParameterKindNumber, + Name: "zEntityOffset", + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindSelector, + Name: "players", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "set", + Literals: []string{"set"}, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "preset", + Tags: []string{mcfunction.TagAimAssistId}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "ease", + Literals: []string{"ease"}, + }, + { + Kind: mcfunction.ParameterKindNumber, + Name: "easeTime", + }, + ease, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "view_offset", + Literals: []string{"view_offset"}, + }, + { + Kind: mcfunction.ParameterKindNumber, + Name: "xViewOffset", + }, + { + Kind: mcfunction.ParameterKindNumber, + Name: "yViewOffset", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "entity_offset", + Literals: []string{"entity_offset"}, + }, + { + Kind: mcfunction.ParameterKindNumber, + Name: "xEntityOffset", + }, + { + Kind: mcfunction.ParameterKindNumber, + Name: "yEntityOffset", + }, + { + Kind: mcfunction.ParameterKindNumber, + Name: "zEntityOffset", + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindSelector, + Name: "players", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "set", + Literals: []string{"set"}, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "preset", + Tags: []string{mcfunction.TagAimAssistId}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "ease", + Literals: []string{"ease"}, + }, + { + Kind: mcfunction.ParameterKindNumber, + Name: "easeTime", + }, + ease, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "rot", + Literals: []string{"rot"}, + }, + { + Kind: mcfunction.ParameterKindRelativeNumber, + Name: "xRot", + Tags: []string{mcfunction.TagPitch}, + }, + { + Kind: mcfunction.ParameterKindRelativeNumber, + Name: "yRot", + Tags: []string{mcfunction.TagYaw}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "view_offset", + Literals: []string{"view_offset"}, + }, + { + Kind: mcfunction.ParameterKindNumber, + Name: "xViewOffset", + }, + { + Kind: mcfunction.ParameterKindNumber, + Name: "yViewOffset", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "entity_offset", + Literals: []string{"entity_offset"}, + }, + { + Kind: mcfunction.ParameterKindNumber, + Name: "xEntityOffset", + }, + { + Kind: mcfunction.ParameterKindNumber, + Name: "yEntityOffset", + }, + { + Kind: mcfunction.ParameterKindNumber, + Name: "zEntityOffset", + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindSelector, + Name: "players", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "set", + Literals: []string{"set"}, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "preset", + Tags: []string{mcfunction.TagAimAssistId}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "pos", + Literals: []string{"pos"}, + }, + { + Kind: mcfunction.ParameterKindVector3, + Name: "position", + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindSelector, + Name: "players", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "set", + Literals: []string{"set"}, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "preset", + Tags: []string{mcfunction.TagAimAssistId}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "rot", + Literals: []string{"rot"}, + }, + { + Kind: mcfunction.ParameterKindRelativeNumber, + Name: "xRot", + Tags: []string{mcfunction.TagPitch}, + }, + { + Kind: mcfunction.ParameterKindRelativeNumber, + Name: "yRot", + Tags: []string{mcfunction.TagYaw}, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindSelector, + Name: "players", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "set", + Literals: []string{"set"}, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "preset", + Tags: []string{mcfunction.TagAimAssistId}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "facing", + Literals: []string{"facing"}, + }, + { + Kind: mcfunction.ParameterKindSelector, + Name: "lookAtEntity", + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindSelector, + Name: "players", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "set", + Literals: []string{"set"}, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "preset", + Tags: []string{mcfunction.TagAimAssistId}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "facing", + Literals: []string{"facing"}, + }, + { + Kind: mcfunction.ParameterKindVector3, + Name: "lookAtPosition", + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindSelector, + Name: "players", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "set", + Literals: []string{"set"}, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "preset", + Tags: []string{mcfunction.TagAimAssistId}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "default", + Optional: true, + Literals: []string{"default"}, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindSelector, + Name: "players", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "clear", + Literals: []string{"clear"}, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindSelector, + Name: "players", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "fade", + Literals: []string{"fade"}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "time", + Literals: []string{"time"}, + }, + { + Kind: mcfunction.ParameterKindNumber, + Name: "fadeInSeconds", + }, + { + Kind: mcfunction.ParameterKindNumber, + Name: "holdSeconds", + }, + { + Kind: mcfunction.ParameterKindNumber, + Name: "fadeOutSeconds", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "color", + Literals: []string{"color"}, + }, + { + Kind: mcfunction.ParameterKindInteger, + Name: "red", + Range: colorRange, + }, + { + Kind: mcfunction.ParameterKindInteger, + Name: "green", + Range: colorRange, + }, + { + Kind: mcfunction.ParameterKindInteger, + Name: "blue", + Range: colorRange, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindSelector, + Name: "players", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "fade", + Literals: []string{"fade"}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "time", + Literals: []string{"time"}, + }, + { + Kind: mcfunction.ParameterKindNumber, + Name: "fadeInSeconds", + }, + { + Kind: mcfunction.ParameterKindNumber, + Name: "holdSeconds", + }, + { + Kind: mcfunction.ParameterKindNumber, + Name: "fadeOutSeconds", + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindSelector, + Name: "players", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "fade", + Literals: []string{"fade"}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "color", + Literals: []string{"color"}, + }, + { + Kind: mcfunction.ParameterKindInteger, + Name: "red", + Range: colorRange, + }, + { + Kind: mcfunction.ParameterKindInteger, + Name: "green", + Range: colorRange, + }, + { + Kind: mcfunction.ParameterKindInteger, + Name: "blue", + Range: colorRange, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindSelector, + Name: "players", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "fade", + Literals: []string{"fade"}, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindSelector, + Name: "players", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "fov_set", + Literals: []string{"fov_set"}, + }, + { + Kind: mcfunction.ParameterKindNumber, + Name: "fov_value", + }, + { + Kind: mcfunction.ParameterKindNumber, + Name: "fovEaseTime", + Optional: true, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "fovEaseType", + Optional: true, + Literals: ease.Literals, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindSelector, + Name: "players", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "fov_clear", + Literals: []string{"fov_clear"}, + }, + { + Kind: mcfunction.ParameterKindNumber, + Name: "fovEaseTime", + Optional: true, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "fovEaseType", + Optional: true, + Literals: ease.Literals, + }, + }, + }, + }, +} diff --git a/internal/mcfunction/vanilla/camerashake.go b/internal/mcfunction/vanilla/camerashake.go new file mode 100644 index 0000000..01751bc --- /dev/null +++ b/internal/mcfunction/vanilla/camerashake.go @@ -0,0 +1,61 @@ +package vanilla + +import ( + "math" + + "github.com/rockide/language-server/internal/mcfunction" +) + +var Camerashake = &mcfunction.Spec{ + Name: "camerashake", + Description: "Applies shaking to the players' camera with a specified intensity and duration.", + Overloads: []mcfunction.SpecOverload{ + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "action", + Literals: []string{"add"}, + }, + { + Kind: mcfunction.ParameterKindSelector, + Name: "player", + }, + { + Kind: mcfunction.ParameterKindNumber, + Name: "intensity", + Optional: true, + }, + { + Kind: mcfunction.ParameterKindNumber, + Name: "seconds", + Optional: true, + Range: &mcfunction.NumberRange{ + Min: 0, + Max: math.MaxFloat64, + }, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "shakeType", + Optional: true, + Literals: []string{"positional", "rotational"}, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "action", + Literals: []string{"stop"}, + }, + { + Kind: mcfunction.ParameterKindSelector, + Name: "player", + Optional: true, + }, + }, + }, + }, +} diff --git a/internal/mcfunction/vanilla/clear.go b/internal/mcfunction/vanilla/clear.go new file mode 100644 index 0000000..1ccf0d7 --- /dev/null +++ b/internal/mcfunction/vanilla/clear.go @@ -0,0 +1,35 @@ +package vanilla + +import "github.com/rockide/language-server/internal/mcfunction" + +var Clear = &mcfunction.Spec{ + Name: "clear", + Description: "Clears items from player inventory.", + Overloads: []mcfunction.SpecOverload{ + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindSelector, + Name: "player", + Optional: true, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "itemName", + Optional: true, + Tags: []string{mcfunction.TagItemId}, + }, + { + Kind: mcfunction.ParameterKindInteger, + Name: "data", + Optional: true, + }, + { + Kind: mcfunction.ParameterKindInteger, + Name: "maxCount", + Optional: true, + }, + }, + }, + }, +} diff --git a/internal/mcfunction/vanilla/clearspawnpoint.go b/internal/mcfunction/vanilla/clearspawnpoint.go new file mode 100644 index 0000000..44de50b --- /dev/null +++ b/internal/mcfunction/vanilla/clearspawnpoint.go @@ -0,0 +1,19 @@ +package vanilla + +import "github.com/rockide/language-server/internal/mcfunction" + +var Clearspawnpoint = &mcfunction.Spec{ + Name: "clearspawnpoint", + Description: "Removes the spawn point for a player.", + Overloads: []mcfunction.SpecOverload{ + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindSelector, + Name: "player", + Optional: true, + }, + }, + }, + }, +} diff --git a/internal/mcfunction/vanilla/clone.go b/internal/mcfunction/vanilla/clone.go new file mode 100644 index 0000000..e7f1440 --- /dev/null +++ b/internal/mcfunction/vanilla/clone.go @@ -0,0 +1,75 @@ +package vanilla + +import "github.com/rockide/language-server/internal/mcfunction" + +var Clone = &mcfunction.Spec{ + Name: "clone", + Description: "Clones blocks from one region to another.", + Overloads: []mcfunction.SpecOverload{ + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindVector3, + Name: "begin", + }, + { + Kind: mcfunction.ParameterKindVector3, + Name: "end", + }, + { + Kind: mcfunction.ParameterKindVector3, + Name: "destination", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "maskMode", + Optional: true, + Literals: []string{"replace", "masked"}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "cloneMode", + Optional: true, + Literals: []string{"normal", "force", "move"}, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindVector3, + Name: "begin", + }, + { + Kind: mcfunction.ParameterKindVector3, + Name: "end", + }, + { + Kind: mcfunction.ParameterKindVector3, + Name: "destination", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "maskMode", + Literals: []string{"replace", "masked"}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "cloneMode", + Literals: []string{"normal", "force", "move"}, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "tileName", + Tags: []string{mcfunction.TagBlockId}, + }, + { + Kind: mcfunction.ParameterKindMap, + Name: "blockStates", + Optional: true, + Tags: []string{mcfunction.TagBlockState}, + }, + }, + }, + }, +} diff --git a/internal/mcfunction/vanilla/commands.go b/internal/mcfunction/vanilla/commands.go new file mode 100644 index 0000000..16d24a5 --- /dev/null +++ b/internal/mcfunction/vanilla/commands.go @@ -0,0 +1,72 @@ +package vanilla + +import "github.com/rockide/language-server/internal/mcfunction" + +var Commands = []*mcfunction.Spec{ + Aimassist, + Camera, + Camerashake, + Clear, + Clearspawnpoint, + Clone, + Controlscheme, + Damage, + Daylock, + Dialogue, + Difficulty, + Effect, + Enchant, + Event, + Execute, + Fill, + Fog, + Function, + Gamemode, + Gamerule, + Gametest, + Give, + Hud, + Inputpermission, + Kill, + Locate, + Loot, + Me, + Mobevent, + Music, + Op, + Particle, + Place, + Playanimation, + Playsound, + Recipe, + Reload, + Replaceitem, + Ride, + Say, + Schedule, + Scoreboard, + Script, + Scriptevent, + Setblock, + Setmaxplayers, + Setworldspawn, + Spawnpoint, + Spreadplayers, + Stopsound, + Structure, + Summon, + Tag, + Teleport, + Tell, + Tellraw, + Testfor, + Testforblock, + Testforblocks, + Tickingarea, + Time, + Title, + Titleraw, + Toggledownfall, + Weather, + Xp, +} diff --git a/internal/mcfunction/vanilla/controlscheme.go b/internal/mcfunction/vanilla/controlscheme.go new file mode 100644 index 0000000..9c88c1b --- /dev/null +++ b/internal/mcfunction/vanilla/controlscheme.go @@ -0,0 +1,47 @@ +package vanilla + +import "github.com/rockide/language-server/internal/mcfunction" + +var Controlscheme = &mcfunction.Spec{ + Name: "controlscheme", + Description: "Sets or clears control scheme.", + Overloads: []mcfunction.SpecOverload{ + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindSelector, + Name: "players", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "set", + Literals: []string{"set"}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "control scheme", + Literals: []string{ + "camera_relative", + "camera_relative_strafe", + "player_relative", + "player_relative_strafe", + "locked_player_relative_strafe", + }, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindSelector, + Name: "players", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "clear", + Literals: []string{"clear"}, + }, + }, + }, + }, +} diff --git a/internal/mcfunction/vanilla/damage.go b/internal/mcfunction/vanilla/damage.go new file mode 100644 index 0000000..2a2c9db --- /dev/null +++ b/internal/mcfunction/vanilla/damage.go @@ -0,0 +1,94 @@ +package vanilla + +import "github.com/rockide/language-server/internal/mcfunction" + +var damageCauseLiterals = []string{ + "anvil", + "block_explosion", + "campfire", + "charging", + "contact", + "drowning", + "entity_attack", + "entity_explosion", + "fall", + "falling_block", + "fire", + "fire_tick", + "fireworks", + "fly_into_wall", + "freezing", + "lava", + "lightning", + "mace_smash", + "magic", + "magma", + "none", + "override", + "piston", + "projectile", + "ram_attack", + "self_destruct", + "sonic_boom", + "soul_campfire", + "stalactite", + "stalagmite", + "starve", + "suffocation", + "suicide", + "temperature", + "thorns", + "void", + "wither", +} + +var Damage = &mcfunction.Spec{ + Name: "damage", + Description: "Apply damage to the specified entities.", + Overloads: []mcfunction.SpecOverload{ + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindSelector, + Name: "target", + }, + { + Kind: mcfunction.ParameterKindNumber, + Name: "amount", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "cause", + Optional: true, + Literals: damageCauseLiterals, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindSelector, + Name: "target", + }, + { + Kind: mcfunction.ParameterKindNumber, + Name: "amount", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "cause", + Literals: damageCauseLiterals, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "origin", + Literals: []string{"entity"}, + }, + { + Kind: mcfunction.ParameterKindSelector, + Name: "damager", + }, + }, + }, + }, +} diff --git a/internal/mcfunction/vanilla/daylock.go b/internal/mcfunction/vanilla/daylock.go new file mode 100644 index 0000000..5ad4ca9 --- /dev/null +++ b/internal/mcfunction/vanilla/daylock.go @@ -0,0 +1,20 @@ +package vanilla + +import "github.com/rockide/language-server/internal/mcfunction" + +var Daylock = &mcfunction.Spec{ + Name: "daylock", + Aliases: []string{"alwaysday"}, + Description: "Locks and unlocks the day-night cycle.", + Overloads: []mcfunction.SpecOverload{ + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindBoolean, + Name: "lock", + Optional: true, + }, + }, + }, + }, +} diff --git a/internal/mcfunction/vanilla/dialogue.go b/internal/mcfunction/vanilla/dialogue.go new file mode 100644 index 0000000..6151ac0 --- /dev/null +++ b/internal/mcfunction/vanilla/dialogue.go @@ -0,0 +1,56 @@ +package vanilla + +import "github.com/rockide/language-server/internal/mcfunction" + +var Dialogue = &mcfunction.Spec{ + Name: "dialogue", + Description: "Opens NPC dialogue for a player.", + Overloads: []mcfunction.SpecOverload{ + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "open", + Literals: []string{"open"}, + }, + { + Kind: mcfunction.ParameterKindSelector, + Name: "npc", + }, + { + Kind: mcfunction.ParameterKindSelector, + Name: "player", + }, + { + Kind: mcfunction.ParameterKindString, + Name: "sceneName", + Optional: true, + Tags: []string{mcfunction.TagDialogueId}, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "change", + Literals: []string{"change"}, + }, + { + Kind: mcfunction.ParameterKindSelector, + Name: "npc", + }, + { + Kind: mcfunction.ParameterKindString, + Name: "sceneName", + Tags: []string{mcfunction.TagDialogueId}, + }, + { + Kind: mcfunction.ParameterKindSelector, + Name: "players", + Optional: true, + }, + }, + }, + }, +} diff --git a/internal/mcfunction/vanilla/difficulty.go b/internal/mcfunction/vanilla/difficulty.go new file mode 100644 index 0000000..700a074 --- /dev/null +++ b/internal/mcfunction/vanilla/difficulty.go @@ -0,0 +1,40 @@ +package vanilla + +import "github.com/rockide/language-server/internal/mcfunction" + +var Difficulty = &mcfunction.Spec{ + Name: "difficulty", + Description: "Sets the difficulty level.", + Overloads: []mcfunction.SpecOverload{ + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "difficulty", + Literals: []string{ + "e", + "easy", + "n", + "normal", + "h", + "hard", + "p", + "peaceful", + }, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindInteger, + Name: "difficulty", + Range: &mcfunction.NumberRange{ + Min: 0, + Max: 3, + }, + }, + }, + }, + }, +} diff --git a/internal/mcfunction/vanilla/effect.go b/internal/mcfunction/vanilla/effect.go new file mode 100644 index 0000000..cdd198c --- /dev/null +++ b/internal/mcfunction/vanilla/effect.go @@ -0,0 +1,137 @@ +package vanilla + +import ( + "math" + + "github.com/rockide/language-server/internal/mcfunction" +) + +var effects = []string{ + "absorption", + "bad_omen", + "blindness", + "breath_of_the_nautilus", + "conduit_power", + "darkness", + "fatal_poison", + "fire_resistance", + "haste", + "health_boost", + "hunger", + "infested", + "instant_damage", + "instant_health", + "invisibility", + "jump_boost", + "levitation", + "mining_fatigue", + "nausea", + "night_vision", + "oozing", + "poison", + "raid_omen", + "regeneration", + "resistance", + "saturation", + "slow_falling", + "slowness", + "speed", + "strength", + "trial_omen", + "village_hero", + "water_breathing", + "weakness", + "weaving", + "wind_charged", + "wither", +} + +var Effect = &mcfunction.Spec{ + Name: "effect", + Description: "Add or remove status effects.", + Overloads: []mcfunction.SpecOverload{ + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindSelector, + Name: "player", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "Mode", + Literals: []string{"clear"}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "effect", + Optional: true, + Literals: effects, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindSelector, + Name: "player", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "effect", + Literals: effects, + }, + { + Kind: mcfunction.ParameterKindInteger, + Name: "seconds", + Optional: true, + Range: &mcfunction.NumberRange{ + Min: 0, + Max: math.MaxFloat64, + }, + }, + { + Kind: mcfunction.ParameterKindInteger, + Name: "amplifier", + Optional: true, + Range: &mcfunction.NumberRange{ + Min: 0, + Max: 255, + }, + }, + { + Kind: mcfunction.ParameterKindBoolean, + Name: "hideParticles", + Optional: true, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindSelector, + Name: "player", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "effect", + Literals: effects, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "Mode", + Literals: []string{"infinite"}, + }, + { + Kind: mcfunction.ParameterKindInteger, + Name: "amplifier", + Optional: true, + }, + { + Kind: mcfunction.ParameterKindBoolean, + Name: "hideParticles", + Optional: true, + }, + }, + }, + }, +} diff --git a/internal/mcfunction/vanilla/enchant.go b/internal/mcfunction/vanilla/enchant.go new file mode 100644 index 0000000..48008f5 --- /dev/null +++ b/internal/mcfunction/vanilla/enchant.go @@ -0,0 +1,89 @@ +package vanilla + +import "github.com/rockide/language-server/internal/mcfunction" + +var enchantments = []string{ + "protection", + "fire_protection", + "feather_falling", + "blast_protection", + "projectile_protection", + "thorns", + "respiration", + "depth_strider", + "aqua_affinity", + "sharpness", + "smite", + "bane_of_arthropods", + "knockback", + "fire_aspect", + "looting", + "efficiency", + "silk_touch", + "unbreaking", + "fortune", + "power", + "punch", + "flame", + "infinity", + "luck_of_the_sea", + "lure", + "frost_walker", + "mending", + "binding", + "vanishing", + "impaling", + "riptide", + "loyalty", + "channeling", + "multishot", + "piercing", + "quick_charge", + "soul_speed", + "swift_sneak", + "wind_burst", + "density", + "breach", +} + +var Enchant = &mcfunction.Spec{ + Name: "enchant", + Description: "Adds an enchantment to a player's selected item.", + Overloads: []mcfunction.SpecOverload{ + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindSelector, + Name: "player", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "enchantmentName", + Literals: enchantments, + }, + { + Kind: mcfunction.ParameterKindInteger, + Name: "level", + Optional: true, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindSelector, + Name: "player", + }, + { + Kind: mcfunction.ParameterKindInteger, + Name: "enchantmentId", + }, + { + Kind: mcfunction.ParameterKindInteger, + Name: "level", + Optional: true, + }, + }, + }, + }, +} diff --git a/internal/mcfunction/vanilla/event.go b/internal/mcfunction/vanilla/event.go new file mode 100644 index 0000000..b6cc993 --- /dev/null +++ b/internal/mcfunction/vanilla/event.go @@ -0,0 +1,28 @@ +package vanilla + +import "github.com/rockide/language-server/internal/mcfunction" + +var Event = &mcfunction.Spec{ + Name: "event", + Description: "Triggers an event for the specified object(s)", + Overloads: []mcfunction.SpecOverload{ + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "entity", + Literals: []string{"entity"}, + }, + { + Kind: mcfunction.ParameterKindSelector, + Name: "target", + }, + { + Kind: mcfunction.ParameterKindString, + Name: "eventName", + Tags: []string{mcfunction.TagEntityEvent}, + }, + }, + }, + }, +} diff --git a/internal/mcfunction/vanilla/execute.go b/internal/mcfunction/vanilla/execute.go new file mode 100644 index 0000000..d68e55f --- /dev/null +++ b/internal/mcfunction/vanilla/execute.go @@ -0,0 +1,464 @@ +package vanilla + +import "github.com/rockide/language-server/internal/mcfunction" + +var ifUnless = []string{"if", "unless"} + +var Execute = &mcfunction.Spec{ + Name: "execute", + Description: "Executes a command on behalf of one or more entities.", + Overloads: []mcfunction.SpecOverload{ + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "subcommand", + Literals: []string{"as"}, + Tags: []string{mcfunction.TagExecuteChain}, + }, + { + Kind: mcfunction.ParameterKindSelector, + Name: "origin", + }, + { + Kind: mcfunction.ParameterKindChainedCommand, + Name: "chainedCommand", + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "subcommand", + Literals: []string{"at"}, + Tags: []string{mcfunction.TagExecuteChain}, + }, + { + Kind: mcfunction.ParameterKindSelector, + Name: "origin", + }, + { + Kind: mcfunction.ParameterKindChainedCommand, + Name: "chainedCommand", + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "subcommand", + Literals: []string{"in"}, + Tags: []string{mcfunction.TagExecuteChain}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "dimension", + Literals: []string{"overworld", "nether", "the_end"}, + Tags: []string{mcfunction.TagDimensionId}, + }, + { + Kind: mcfunction.ParameterKindChainedCommand, + Name: "chainedCommand", + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "subcommand", + Literals: []string{"positioned"}, + Tags: []string{mcfunction.TagExecuteChain}, + }, + { + Kind: mcfunction.ParameterKindVector3, + Name: "position", + }, + { + Kind: mcfunction.ParameterKindChainedCommand, + Name: "chainedCommand", + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "subcommand", + Literals: []string{"positioned"}, + Tags: []string{mcfunction.TagExecuteChain}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "secondary subcommand", + Literals: []string{"as"}, + }, + { + Kind: mcfunction.ParameterKindSelector, + Name: "origin", + }, + { + Kind: mcfunction.ParameterKindChainedCommand, + Name: "chainedCommand", + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "subcommand", + Literals: []string{"rotated"}, + Tags: []string{mcfunction.TagExecuteChain}, + }, + { + Kind: mcfunction.ParameterKindNumber, + Name: "yaw", + Tags: []string{mcfunction.TagYaw}, + }, + { + Kind: mcfunction.ParameterKindNumber, + Name: "pitch", + Tags: []string{mcfunction.TagPitch}, + }, + { + Kind: mcfunction.ParameterKindChainedCommand, + Name: "chainedCommand", + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "subcommand", + Literals: []string{"rotated"}, + Tags: []string{mcfunction.TagExecuteChain}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "secondary subcommand", + Literals: []string{"as"}, + }, + { + Kind: mcfunction.ParameterKindSelector, + Name: "origin", + }, + { + Kind: mcfunction.ParameterKindChainedCommand, + Name: "chainedCommand", + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "subcommand", + Literals: []string{"facing"}, + Tags: []string{mcfunction.TagExecuteChain}, + }, + { + Kind: mcfunction.ParameterKindVector3, + Name: "position", + }, + { + Kind: mcfunction.ParameterKindChainedCommand, + Name: "chainedCommand", + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "subcommand", + Literals: []string{"facing"}, + Tags: []string{mcfunction.TagExecuteChain}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "secondary subcommand", + Literals: []string{"entity"}, + }, + { + Kind: mcfunction.ParameterKindSelector, + Name: "origin", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "anchor", + Literals: []string{"eyes", "feet"}, + }, + { + Kind: mcfunction.ParameterKindChainedCommand, + Name: "chainedCommand", + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "subcommand", + Literals: []string{"align"}, + Tags: []string{mcfunction.TagExecuteChain}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "axes", + Literals: []string{"xyz", "xy", "xz", "yz", "x", "y", "z"}, + }, + { + Kind: mcfunction.ParameterKindChainedCommand, + Name: "chainedCommand", + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "subcommand", + Literals: []string{"anchored"}, + Tags: []string{mcfunction.TagExecuteChain}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "anchored", + Literals: []string{"eyes", "feet"}, + }, + { + Kind: mcfunction.ParameterKindChainedCommand, + Name: "chainedCommand", + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "subcommand", + Literals: ifUnless, + Tags: []string{mcfunction.TagExecuteChain}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "secondary subcommand", + Literals: []string{"block"}, + }, + { + Kind: mcfunction.ParameterKindVector3, + Name: "position", + }, + { + Kind: mcfunction.ParameterKindString, + Name: "block", + Tags: []string{mcfunction.TagBlockId}, + }, + { + Kind: mcfunction.ParameterKindChainedCommand, + Name: "chainedCommand", + Optional: true, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "subcommand", + Literals: ifUnless, + Tags: []string{mcfunction.TagExecuteChain}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "secondary subcommand", + Literals: []string{"block"}, + }, + { + Kind: mcfunction.ParameterKindVector3, + Name: "position", + }, + { + Kind: mcfunction.ParameterKindString, + Name: "block", + Tags: []string{mcfunction.TagBlockId}, + }, + { + Kind: mcfunction.ParameterKindMap, + Name: "blockStates", + Tags: []string{mcfunction.TagBlockState}, + }, + { + Kind: mcfunction.ParameterKindChainedCommand, + Name: "chainedCommand", + Optional: true, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "subcommand", + Literals: ifUnless, + Tags: []string{mcfunction.TagExecuteChain}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "secondary subcommand", + Literals: []string{"blocks"}, + }, + { + Kind: mcfunction.ParameterKindVector3, + Name: "begin", + }, + { + Kind: mcfunction.ParameterKindVector3, + Name: "end", + }, + { + Kind: mcfunction.ParameterKindVector3, + Name: "destination", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "scan mode", + Literals: []string{"masked", "all"}, + }, + { + Kind: mcfunction.ParameterKindChainedCommand, + Name: "chainedCommand", + Optional: true, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "subcommand", + Literals: ifUnless, + Tags: []string{mcfunction.TagExecuteChain}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "secondary subcommand", + Literals: []string{"entity"}, + }, + { + Kind: mcfunction.ParameterKindSelector, + Name: "target", + }, + { + Kind: mcfunction.ParameterKindChainedCommand, + Name: "chainedCommand", + Optional: true, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "subcommand", + Literals: ifUnless, + Tags: []string{mcfunction.TagExecuteChain}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "secondary subcommand", + Literals: []string{"score"}, + }, + { + Kind: mcfunction.ParameterKindSelector, + Name: "target", + }, + { + Kind: mcfunction.ParameterKindString, + Name: "objective", + Tags: []string{mcfunction.TagScoreboardObjectiveId}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "operation", + Literals: []string{ + "<", + "<=", + ">", + ">=", + }, + }, + { + Kind: mcfunction.ParameterKindSelector, + Name: "source", + }, + { + Kind: mcfunction.ParameterKindString, + Name: "objective", + Tags: []string{mcfunction.TagScoreboardObjectiveId}, + }, + { + Kind: mcfunction.ParameterKindChainedCommand, + Name: "chainedCommand", + Optional: true, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "subcommand", + Literals: ifUnless, + Tags: []string{mcfunction.TagExecuteChain}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "secondary subcommand", + Literals: []string{"score"}, + }, + { + Kind: mcfunction.ParameterKindSelector, + Name: "target", + }, + { + Kind: mcfunction.ParameterKindString, + Name: "objective", + Tags: []string{mcfunction.TagScoreboardObjectiveId}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "matches", + Literals: []string{"matches"}, + }, + { + Kind: mcfunction.ParameterKindRange, + Name: "range", + }, + { + Kind: mcfunction.ParameterKindChainedCommand, + Name: "chainedCommand", + Optional: true, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "subcommand", + Literals: []string{"run"}, + Tags: []string{mcfunction.TagExecuteChain}, + }, + { + Kind: mcfunction.ParameterKindCommand, + Name: "command", + }, + }, + }, + }, +} diff --git a/internal/mcfunction/vanilla/fill.go b/internal/mcfunction/vanilla/fill.go new file mode 100644 index 0000000..1ad8c8d --- /dev/null +++ b/internal/mcfunction/vanilla/fill.go @@ -0,0 +1,142 @@ +package vanilla + +import "github.com/rockide/language-server/internal/mcfunction" + +var oldBlockHandling = []string{ + "destroy", + "hollow", + "keep", + "outline", + "replace", +} + +var Fill = &mcfunction.Spec{ + Name: "fill", + Description: "Fills all or parts of a region with a specific block.", + Overloads: []mcfunction.SpecOverload{ + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindVector3, + Name: "from", + }, + { + Kind: mcfunction.ParameterKindVector3, + Name: "to", + }, + { + Kind: mcfunction.ParameterKindString, + Name: "tileName", + Tags: []string{mcfunction.TagBlockId}, + }, + { + Kind: mcfunction.ParameterKindMap, + Name: "blockStates", + Tags: []string{mcfunction.TagBlockState}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "oldBlockHandling", + Optional: true, + Literals: oldBlockHandling, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindVector3, + Name: "from", + }, + { + Kind: mcfunction.ParameterKindVector3, + Name: "to", + }, + { + Kind: mcfunction.ParameterKindString, + Name: "tileName", + Tags: []string{mcfunction.TagBlockId}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "oldBlockHandling", + Optional: true, + Literals: oldBlockHandling, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindVector3, + Name: "from", + }, + { + Kind: mcfunction.ParameterKindVector3, + Name: "to", + }, + { + Kind: mcfunction.ParameterKindString, + Name: "tileName", + Tags: []string{mcfunction.TagBlockId}, + }, + { + Kind: mcfunction.ParameterKindMap, + Name: "blockStates", + Tags: []string{mcfunction.TagBlockState}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "oldBlockHandling", + Literals: oldBlockHandling, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "replaceTileName", + Optional: true, + Tags: []string{mcfunction.TagBlockId}, + }, + { + Kind: mcfunction.ParameterKindMap, + Name: "replaceBlockStates", + Optional: true, + Tags: []string{mcfunction.TagBlockState}, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindVector3, + Name: "from", + }, + { + Kind: mcfunction.ParameterKindVector3, + Name: "to", + }, + { + Kind: mcfunction.ParameterKindString, + Tags: []string{mcfunction.TagBlockId}, + Name: "tileName", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "oldBlockHandling", + Literals: oldBlockHandling, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "replaceTileName", + Optional: true, + Tags: []string{mcfunction.TagBlockId}, + }, + { + Kind: mcfunction.ParameterKindMap, + Name: "replaceBlockStates", + Optional: true, + Tags: []string{mcfunction.TagBlockState}, + }, + }, + }, + }, +} diff --git a/internal/mcfunction/vanilla/fog.go b/internal/mcfunction/vanilla/fog.go new file mode 100644 index 0000000..4d3d3da --- /dev/null +++ b/internal/mcfunction/vanilla/fog.go @@ -0,0 +1,51 @@ +package vanilla + +import "github.com/rockide/language-server/internal/mcfunction" + +var Fog = &mcfunction.Spec{ + Name: "fog", + Description: "Add or remove fog settings file", + Overloads: []mcfunction.SpecOverload{ + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindSelector, + Name: "victim", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "mode", + Literals: []string{"push"}, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "fogId", + Tags: []string{mcfunction.TagFogId}, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "userProvidedId", + Tags: []string{mcfunction.TagProvidedFogId}, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindSelector, + Name: "victim", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "mode", + Literals: []string{"pop", "remove"}, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "userProvidedId", + Tags: []string{mcfunction.TagProvidedFogId}, + }, + }, + }, + }, +} diff --git a/internal/mcfunction/vanilla/function.go b/internal/mcfunction/vanilla/function.go new file mode 100644 index 0000000..ad4b779 --- /dev/null +++ b/internal/mcfunction/vanilla/function.go @@ -0,0 +1,19 @@ +package vanilla + +import "github.com/rockide/language-server/internal/mcfunction" + +var Function = &mcfunction.Spec{ + Name: "function", + Description: "Runs commands found in the corresponding function file.", + Overloads: []mcfunction.SpecOverload{ + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindString, + Name: "name", + Tags: []string{mcfunction.TagFunctionFile}, + }, + }, + }, + }, +} diff --git a/internal/mcfunction/vanilla/gamemode.go b/internal/mcfunction/vanilla/gamemode.go new file mode 100644 index 0000000..e96f203 --- /dev/null +++ b/internal/mcfunction/vanilla/gamemode.go @@ -0,0 +1,53 @@ +package vanilla + +import "github.com/rockide/language-server/internal/mcfunction" + +var gamemodes = []string{ + "a", + "adventure", + "c", + "creative", + "d", + "default", + "s", + "spectator", + "survival", +} + +var Gamemode = &mcfunction.Spec{ + Name: "gamemode", + Description: "Sets a player's game mode.", + Overloads: []mcfunction.SpecOverload{ + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "gameMode", + Literals: gamemodes, + }, + { + Kind: mcfunction.ParameterKindSelector, + Name: "player", + Optional: true, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindInteger, + Name: "gameMode", + Range: &mcfunction.NumberRange{ + Min: 0, + Max: 2, + }, + }, + { + Kind: mcfunction.ParameterKindSelector, + Name: "player", + Optional: true, + }, + }, + }, + }, +} diff --git a/internal/mcfunction/vanilla/gamerule.go b/internal/mcfunction/vanilla/gamerule.go new file mode 100644 index 0000000..e51ff7a --- /dev/null +++ b/internal/mcfunction/vanilla/gamerule.go @@ -0,0 +1,85 @@ +package vanilla + +import "github.com/rockide/language-server/internal/mcfunction" + +var boolGameRules = []string{ + "commandblockoutput", + "dodaylightcycle", + "doentitydrops", + "dofiretick", + "recipesunlock", + "dolimitedcrafting", + "domobloot", + "domobspawning", + "dotiledrops", + "doweathercycle", + "drowningdamage", + "falldamage", + "firedamage", + "keepinventory", + "mobgriefing", + "pvp", + "showcoordinates", + "locatorbar", + "showdaysplayed", + "naturalregeneration", + "tntexplodes", + "sendcommandfeedback", + "doinsomnia", + "commandblocksenabled", + "doimmediaterespawn", + "showdeathmessages", + "showtags", + "freezedamage", + "respawnblocksexplode", + "showbordereffect", + "showrecipemessages", + "projectilescanbreakblocks", + "tntexplosiondropdecay", +} + +var intGameRules = []string{ + "maxcommandchainlength", + "randomtickspeed", + "functioncommandlimit", + "spawnradius", + "playerssleepingpercentage", +} + +var Gamerule = &mcfunction.Spec{ + Name: "gamerule", + Description: "Sets or queries a game rule value.", + Overloads: []mcfunction.SpecOverload{ + { + Parameters: []mcfunction.ParameterSpec{}, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "rule", + Literals: boolGameRules, + }, + { + Kind: mcfunction.ParameterKindBoolean, + Name: "value", + Optional: true, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "rule", + Literals: intGameRules, + }, + { + Kind: mcfunction.ParameterKindInteger, + Name: "value", + Optional: true, + }, + }, + }, + }, +} diff --git a/internal/mcfunction/vanilla/gametest.go b/internal/mcfunction/vanilla/gametest.go new file mode 100644 index 0000000..f9bad5a --- /dev/null +++ b/internal/mcfunction/vanilla/gametest.go @@ -0,0 +1,165 @@ +package vanilla + +import "github.com/rockide/language-server/internal/mcfunction" + +var Gametest = &mcfunction.Spec{ + Name: "gametest", + Description: "Interacts with gametest.", + Overloads: []mcfunction.SpecOverload{ + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "mode", + Literals: []string{"runthis"}, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "mode", + Literals: []string{"run"}, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "testName", + }, + { + Kind: mcfunction.ParameterKindNumber, + Name: "rotationSteps", + Optional: true, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "mode", + Literals: []string{"run"}, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "testName", + }, + { + Kind: mcfunction.ParameterKindBoolean, + Name: "stopOnFailure", + }, + { + Kind: mcfunction.ParameterKindInteger, + Name: "repeatCount", + }, + { + Kind: mcfunction.ParameterKindInteger, + Name: "rotationSteps", + Optional: true, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "mode", + Literals: []string{"runset"}, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "tag", + Optional: true, + }, + { + Kind: mcfunction.ParameterKindInteger, + Name: "rotationSteps", + Optional: true, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "mode", + Literals: []string{"runsetuntilfail"}, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "tag", + Optional: true, + }, + { + Kind: mcfunction.ParameterKindInteger, + Name: "rotationSteps", + Optional: true, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "mode", + Literals: []string{"clearall"}, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "mode", + Literals: []string{"pos"}, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "mode", + Literals: []string{"create"}, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "testName", + }, + { + Kind: mcfunction.ParameterKindInteger, + Name: "width", + Optional: true, + }, + { + Kind: mcfunction.ParameterKindInteger, + Name: "height", + Optional: true, + }, + { + Kind: mcfunction.ParameterKindInteger, + Name: "depth", + Optional: true, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "mode", + Literals: []string{"runthese"}, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "mode", + Literals: []string{"stopall"}, + }, + }, + }, + }, +} diff --git a/internal/mcfunction/vanilla/give.go b/internal/mcfunction/vanilla/give.go new file mode 100644 index 0000000..40c12f8 --- /dev/null +++ b/internal/mcfunction/vanilla/give.go @@ -0,0 +1,38 @@ +package vanilla + +import "github.com/rockide/language-server/internal/mcfunction" + +var Give = &mcfunction.Spec{ + Name: "give", + Description: "Gives an item to a player.", + Overloads: []mcfunction.SpecOverload{ + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindSelector, + Name: "player", + }, + { + Kind: mcfunction.ParameterKindString, + Name: "itemName", + Tags: []string{mcfunction.TagItemId}, + }, + { + Kind: mcfunction.ParameterKindInteger, + Name: "amount", + Optional: true, + }, + { + Kind: mcfunction.ParameterKindInteger, + Name: "data", + Optional: true, + }, + { + Kind: mcfunction.ParameterKindItemNbt, + Name: "components", + Optional: true, + }, + }, + }, + }, +} diff --git a/internal/mcfunction/vanilla/hud.go b/internal/mcfunction/vanilla/hud.go new file mode 100644 index 0000000..427530d --- /dev/null +++ b/internal/mcfunction/vanilla/hud.go @@ -0,0 +1,46 @@ +package vanilla + +import "github.com/rockide/language-server/internal/mcfunction" + +var hudElements = []string{ + "air_bubbles", + "all", + "armor", + "crosshair", + "health", + "horse_health", + "hotbar", + "hunger", + "item_text", + "paperdoll", + "progress_bar", + "status_effects", + "tooltips", + "touch_controls", +} + +var Hud = &mcfunction.Spec{ + Name: "hud", + Description: "Changes the visibility of hud elements.", + Overloads: []mcfunction.SpecOverload{ + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindSelector, + Name: "target", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "visible", + Literals: []string{"hide", "reset"}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "hud_element", + Optional: true, + Literals: hudElements, + }, + }, + }, + }, +} diff --git a/internal/mcfunction/vanilla/inputpermission.go b/internal/mcfunction/vanilla/inputpermission.go new file mode 100644 index 0000000..26e3ee5 --- /dev/null +++ b/internal/mcfunction/vanilla/inputpermission.go @@ -0,0 +1,71 @@ +package vanilla + +import "github.com/rockide/language-server/internal/mcfunction" + +var permission = []string{ + "camera", + "dismount", + "jump", + "lateral_movement", + "mount", + "move_backward", + "move_forward", + "move_left", + "move_right", + "movement", + "sneak", +} + +var Inputpermission = &mcfunction.Spec{ + Name: "inputpermission", + Description: "Sets whether or not a player's input can affect their character.", + Overloads: []mcfunction.SpecOverload{ + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "option", + Literals: []string{"set"}, + }, + { + Kind: mcfunction.ParameterKindSelector, + Name: "targets", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "permission", + Literals: permission, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "state", + Literals: []string{"enabled", "disabled"}, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "option", + Literals: []string{"query"}, + }, + { + Kind: mcfunction.ParameterKindSelector, + Name: "targets", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "permission", + Literals: permission, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "state", + Optional: true, + Literals: []string{"enabled", "disabled"}, + }, + }, + }, + }, +} diff --git a/internal/mcfunction/vanilla/kill.go b/internal/mcfunction/vanilla/kill.go new file mode 100644 index 0000000..b952d77 --- /dev/null +++ b/internal/mcfunction/vanilla/kill.go @@ -0,0 +1,19 @@ +package vanilla + +import "github.com/rockide/language-server/internal/mcfunction" + +var Kill = &mcfunction.Spec{ + Name: "kill", + Description: "Kills entities (players, mobs, etc.).", + Overloads: []mcfunction.SpecOverload{ + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindSelector, + Name: "target", + Optional: true, + }, + }, + }, + }, +} diff --git a/internal/mcfunction/vanilla/locate.go b/internal/mcfunction/vanilla/locate.go new file mode 100644 index 0000000..80d8b16 --- /dev/null +++ b/internal/mcfunction/vanilla/locate.go @@ -0,0 +1,43 @@ +package vanilla + +import "github.com/rockide/language-server/internal/mcfunction" + +var Locate = &mcfunction.Spec{ + Name: "locate", + Description: "Displays the coordinates for the closest structure or biome of a given type.", + Overloads: []mcfunction.SpecOverload{ + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "subcommand", + Literals: []string{"structure"}, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "structure", + Tags: []string{mcfunction.TagJigsawId}, + }, + { + Kind: mcfunction.ParameterKindBoolean, + Name: "useNewChunksOnly", + Optional: true, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "subcommand", + Literals: []string{"biome"}, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "biome", + Tags: []string{mcfunction.TagBiomeId}, + }, + }, + }, + }, +} diff --git a/internal/mcfunction/vanilla/loot.go b/internal/mcfunction/vanilla/loot.go new file mode 100644 index 0000000..4e948ce --- /dev/null +++ b/internal/mcfunction/vanilla/loot.go @@ -0,0 +1,835 @@ +package vanilla + +import "github.com/rockide/language-server/internal/mcfunction" + +var slotTypes = []string{ + "slot.armor", + "slot.armor.body", + "slot.armor.chest", + "slot.armor.feet", + "slot.armor.head", + "slot.armor.legs", + "slot.chest", + "slot.enderchest", + "slot.equippable", + "slot.hotbar", + "slot.inventory", + "slot.saddle", + "slot.weapon.mainhand", + "slot.weapon.offhand", +} + +var Loot = &mcfunction.Spec{ + Name: "loot", + Description: "Drops the given loot table into the specified inventory or into the world.", + Overloads: []mcfunction.SpecOverload{ + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "target", + Literals: []string{"spawn"}, + }, + { + Kind: mcfunction.ParameterKindVector3, + Name: "position", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "source", + Literals: []string{"loot"}, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "loot_table", + Tags: []string{mcfunction.TagLootTableFile}, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "|mainhand|offhand", + Optional: true, + Literals: []string{"mainhand", "offhand"}, + Tags: []string{mcfunction.TagItemId}, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "target", + Literals: []string{"spawn"}, + }, + { + Kind: mcfunction.ParameterKindVector3, + Name: "position", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "source", + Literals: []string{"kill"}, + }, + { + Kind: mcfunction.ParameterKindSelector, + Name: "entity", + }, + { + Kind: mcfunction.ParameterKindString, + Name: "|mainhand|offhand", + Optional: true, + Literals: []string{"mainhand", "offhand"}, + Tags: []string{mcfunction.TagItemId}, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "target", + Literals: []string{"spawn"}, + }, + { + Kind: mcfunction.ParameterKindVector3, + Name: "position", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "source", + Literals: []string{"mine"}, + }, + { + Kind: mcfunction.ParameterKindVector3, + Name: "TargetBlockPosition", + }, + { + Kind: mcfunction.ParameterKindString, + Name: "|mainhand|offhand", + Optional: true, + Literals: []string{"mainhand", "offhand"}, + Tags: []string{mcfunction.TagItemId}, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "target", + Literals: []string{"give"}, + }, + { + Kind: mcfunction.ParameterKindSelector, + Name: "players", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "source", + Literals: []string{"loot"}, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "loot_table", + Tags: []string{mcfunction.TagLootTableFile}, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "|mainhand|offhand", + Optional: true, + Literals: []string{"mainhand", "offhand"}, + Tags: []string{mcfunction.TagItemId}, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "target", + Literals: []string{"give"}, + }, + { + Kind: mcfunction.ParameterKindSelector, + Name: "players", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "source", + Literals: []string{"kill"}, + }, + { + Kind: mcfunction.ParameterKindSelector, + Name: "entity", + }, + { + Kind: mcfunction.ParameterKindString, + Name: "|mainhand|offhand", + Optional: true, + Literals: []string{"mainhand", "offhand"}, + Tags: []string{mcfunction.TagItemId}, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "target", + Literals: []string{"give"}, + }, + { + Kind: mcfunction.ParameterKindSelector, + Name: "players", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "source", + Literals: []string{"mine"}, + }, + { + Kind: mcfunction.ParameterKindVector3, + Name: "TargetBlockPosition", + }, + { + Kind: mcfunction.ParameterKindString, + Name: "|mainhand|offhand", + Optional: true, + Literals: []string{"mainhand", "offhand"}, + Tags: []string{mcfunction.TagItemId}, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "target", + Literals: []string{"insert"}, + }, + { + Kind: mcfunction.ParameterKindVector3, + Name: "position", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "source", + Literals: []string{"loot"}, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "loot_table", + Tags: []string{mcfunction.TagLootTableFile}, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "|mainhand|offhand", + Optional: true, + Literals: []string{"mainhand", "offhand"}, + Tags: []string{mcfunction.TagItemId}, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "target", + Literals: []string{"insert"}, + }, + { + Kind: mcfunction.ParameterKindVector3, + Name: "position", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "source", + Literals: []string{"kill"}, + }, + { + Kind: mcfunction.ParameterKindSelector, + Name: "entity", + }, + { + Kind: mcfunction.ParameterKindString, + Name: "|mainhand|offhand", + Optional: true, + Literals: []string{"mainhand", "offhand"}, + Tags: []string{mcfunction.TagItemId}, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "target", + Literals: []string{"insert"}, + }, + { + Kind: mcfunction.ParameterKindVector3, + Name: "position", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "source", + Literals: []string{"mine"}, + }, + { + Kind: mcfunction.ParameterKindVector3, + Name: "TargetBlockPosition", + }, + { + Kind: mcfunction.ParameterKindString, + Name: "|mainhand|offhand", + Optional: true, + Literals: []string{"mainhand", "offhand"}, + Tags: []string{mcfunction.TagItemId}, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "target", + Literals: []string{"replace"}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "entity", + Literals: []string{"entity"}, + }, + { + Kind: mcfunction.ParameterKindSelector, + Name: "entity", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "slotType", + Literals: slotTypes, + }, + { + Kind: mcfunction.ParameterKindInteger, + Name: "slotId", + }, + { + Kind: mcfunction.ParameterKindInteger, + Name: "count", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "source", + Literals: []string{"loot"}, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "loot_table", + Tags: []string{mcfunction.TagLootTableFile}, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "|mainhand|offhand", + Optional: true, + Literals: []string{"mainhand", "offhand"}, + Tags: []string{mcfunction.TagItemId}, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "target", + Literals: []string{"replace"}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "entity", + Literals: []string{"entity"}, + }, + { + Kind: mcfunction.ParameterKindSelector, + Name: "entity", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "slotType", + Literals: slotTypes, + }, + { + Kind: mcfunction.ParameterKindInteger, + Name: "slotId", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "source", + Literals: []string{"loot"}, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "loot_table", + Tags: []string{mcfunction.TagLootTableFile}, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "|mainhand|offhand", + Optional: true, + Literals: []string{"mainhand", "offhand"}, + Tags: []string{mcfunction.TagItemId}, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "target", + Literals: []string{"replace"}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "entity", + Literals: []string{"entity"}, + }, + { + Kind: mcfunction.ParameterKindSelector, + Name: "entity", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "slotType", + Literals: slotTypes, + }, + { + Kind: mcfunction.ParameterKindInteger, + Name: "slotId", + }, + { + Kind: mcfunction.ParameterKindInteger, + Name: "count", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "source", + Literals: []string{"kill"}, + }, + { + Kind: mcfunction.ParameterKindSelector, + Name: "entity", + }, + { + Kind: mcfunction.ParameterKindString, + Name: "|mainhand|offhand", + Optional: true, + Literals: []string{"mainhand", "offhand"}, + Tags: []string{mcfunction.TagItemId}, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "target", + Literals: []string{"replace"}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "entity", + Literals: []string{"entity"}, + }, + { + Kind: mcfunction.ParameterKindSelector, + Name: "entity", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "slotType", + Literals: slotTypes, + }, + { + Kind: mcfunction.ParameterKindInteger, + Name: "slotId", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "source", + Literals: []string{"kill"}, + }, + { + Kind: mcfunction.ParameterKindSelector, + Name: "entity", + }, + { + Kind: mcfunction.ParameterKindString, + Name: "|mainhand|offhand", + Optional: true, + Literals: []string{"mainhand", "offhand"}, + Tags: []string{mcfunction.TagItemId}, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "target", + Literals: []string{"replace"}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "entity", + Literals: []string{"entity"}, + }, + { + Kind: mcfunction.ParameterKindSelector, + Name: "entity", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "slotType", + Literals: slotTypes, + }, + { + Kind: mcfunction.ParameterKindInteger, + Name: "slotId", + }, + { + Kind: mcfunction.ParameterKindInteger, + Name: "count", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "source", + Literals: []string{"mine"}, + }, + { + Kind: mcfunction.ParameterKindVector3, + Name: "TargetBlockPosition", + }, + { + Kind: mcfunction.ParameterKindString, + Name: "|mainhand|offhand", + Optional: true, + Literals: []string{"mainhand", "offhand"}, + Tags: []string{mcfunction.TagItemId}, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "target", + Literals: []string{"replace"}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "entity", + Literals: []string{"entity"}, + }, + { + Kind: mcfunction.ParameterKindSelector, + Name: "entity", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "slotType", + Literals: slotTypes, + }, + { + Kind: mcfunction.ParameterKindInteger, + Name: "slotId", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "source", + Literals: []string{"mine"}, + }, + { + Kind: mcfunction.ParameterKindVector3, + Name: "TargetBlockPosition", + }, + { + Kind: mcfunction.ParameterKindString, + Name: "|mainhand|offhand", + Optional: true, + Literals: []string{"mainhand", "offhand"}, + Tags: []string{mcfunction.TagItemId}, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "target", + Literals: []string{"replace"}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "block", + Literals: []string{"block"}, + }, + { + Kind: mcfunction.ParameterKindVector3, + Name: "position", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "slotType", + Literals: []string{"slot.container"}, + }, + { + Kind: mcfunction.ParameterKindInteger, + Name: "slotId", + }, + { + Kind: mcfunction.ParameterKindInteger, + Name: "count", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "source", + Literals: []string{"loot"}, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "loot_table", + Tags: []string{mcfunction.TagLootTableFile}, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "|mainhand|offhand", + Optional: true, + Literals: []string{"mainhand", "offhand"}, + Tags: []string{mcfunction.TagItemId}, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "target", + Literals: []string{"replace"}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "block", + Literals: []string{"block"}, + }, + { + Kind: mcfunction.ParameterKindVector3, + Name: "position", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "slotType", + Literals: []string{"slot.container"}, + }, + { + Kind: mcfunction.ParameterKindInteger, + Name: "slotId", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "source", + Literals: []string{"loot"}, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "loot_table", + Tags: []string{mcfunction.TagLootTableFile}, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "|mainhand|offhand", + Optional: true, + Tags: []string{mcfunction.TagItemId}, + Literals: []string{"mainhand", "offhand"}, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "target", + Literals: []string{"replace"}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "block", + Literals: []string{"block"}, + }, + { + Kind: mcfunction.ParameterKindVector3, + Name: "position", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "slotType", + Literals: []string{"slot.container"}, + }, + { + Kind: mcfunction.ParameterKindInteger, + Name: "slotId", + }, + { + Kind: mcfunction.ParameterKindInteger, + Name: "count", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "source", + Literals: []string{"kill"}, + }, + { + Kind: mcfunction.ParameterKindSelector, + Name: "entity", + }, + { + Kind: mcfunction.ParameterKindString, + Name: "|mainhand|offhand", + Optional: true, + Literals: []string{"mainhand", "offhand"}, + Tags: []string{mcfunction.TagItemId}, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "target", + Literals: []string{"replace"}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "block", + Literals: []string{"block"}, + }, + { + Kind: mcfunction.ParameterKindVector3, + Name: "position", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "slotType", + Literals: []string{"slot.container"}, + }, + { + Kind: mcfunction.ParameterKindInteger, + Name: "slotId", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "source", + Literals: []string{"kill"}, + }, + { + Kind: mcfunction.ParameterKindSelector, + Name: "entity", + }, + { + Kind: mcfunction.ParameterKindString, + Name: "|mainhand|offhand", + Optional: true, + Literals: []string{"mainhand", "offhand"}, + Tags: []string{mcfunction.TagItemId}, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "target", + Literals: []string{"replace"}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "block", + Literals: []string{"block"}, + }, + { + Kind: mcfunction.ParameterKindVector3, + Name: "position", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "slotType", + Literals: []string{"slot.container"}, + }, + { + Kind: mcfunction.ParameterKindInteger, + Name: "slotId", + }, + { + Kind: mcfunction.ParameterKindInteger, + Name: "count", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "source", + Literals: []string{"mine"}, + }, + { + Kind: mcfunction.ParameterKindVector3, + Name: "TargetBlockPosition", + }, + { + Kind: mcfunction.ParameterKindString, + Name: "|mainhand|offhand", + Optional: true, + Literals: []string{"mainhand", "offhand"}, + Tags: []string{mcfunction.TagItemId}, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "target", + Literals: []string{"replace"}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "block", + Literals: []string{"block"}, + }, + { + Kind: mcfunction.ParameterKindVector3, + Name: "position", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "slotType", + Literals: []string{"slot.container"}, + }, + { + Kind: mcfunction.ParameterKindInteger, + Name: "slotId", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "source", + Literals: []string{"mine"}, + }, + { + Kind: mcfunction.ParameterKindVector3, + Name: "TargetBlockPosition", + }, + { + Kind: mcfunction.ParameterKindString, + Name: "|mainhand|offhand", + Optional: true, + Literals: []string{"mainhand", "offhand"}, + Tags: []string{mcfunction.TagItemId}, + }, + }, + }, + }, +} diff --git a/internal/mcfunction/vanilla/me.go b/internal/mcfunction/vanilla/me.go new file mode 100644 index 0000000..03deb37 --- /dev/null +++ b/internal/mcfunction/vanilla/me.go @@ -0,0 +1,19 @@ +package vanilla + +import "github.com/rockide/language-server/internal/mcfunction" + +var Me = &mcfunction.Spec{ + Name: "me", + Description: "Displays a message about yourself.", + Overloads: []mcfunction.SpecOverload{ + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindString, + Name: "message", + Greedy: true, + }, + }, + }, + }, +} diff --git a/internal/mcfunction/vanilla/mobevent.go b/internal/mcfunction/vanilla/mobevent.go new file mode 100644 index 0000000..7ed4669 --- /dev/null +++ b/internal/mcfunction/vanilla/mobevent.go @@ -0,0 +1,29 @@ +package vanilla + +import "github.com/rockide/language-server/internal/mcfunction" + +var Mobevent = &mcfunction.Spec{ + Name: "mobevent", + Description: "Controls what mob events are allowed to run.", + Overloads: []mcfunction.SpecOverload{ + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "event", + Literals: []string{ + "events_enabled", + "minecraft:ender_dragon_event", + "minecraft:pillager_patrols_event", + "minecraft:wandering_trader_event", + }, + }, + { + Kind: mcfunction.ParameterKindBoolean, + Name: "value", + Optional: true, + }, + }, + }, + }, +} diff --git a/internal/mcfunction/vanilla/music.go b/internal/mcfunction/vanilla/music.go new file mode 100644 index 0000000..5134483 --- /dev/null +++ b/internal/mcfunction/vanilla/music.go @@ -0,0 +1,121 @@ +package vanilla + +import "github.com/rockide/language-server/internal/mcfunction" + +var Music = &mcfunction.Spec{ + Name: "music", + Description: "Allows you to control playing music tracks.", + Overloads: []mcfunction.SpecOverload{ + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "action", + Literals: []string{"queue"}, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "trackName", + Tags: []string{mcfunction.TagMusicId}, + }, + { + Kind: mcfunction.ParameterKindNumber, + Name: "volume", + Optional: true, + Range: &mcfunction.NumberRange{ + Min: 0.01, + Max: 1, + }, + }, + { + Kind: mcfunction.ParameterKindNumber, + Name: "fadeSeconds", + Optional: true, + Range: &mcfunction.NumberRange{ + Min: 0, + Max: 10, + }, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "repeatMode", + Optional: true, + Literals: []string{"loop", "play_once"}, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "action", + Literals: []string{"play"}, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "trackName", + Tags: []string{mcfunction.TagMusicId}, + }, + { + Kind: mcfunction.ParameterKindNumber, + Name: "volume", + Optional: true, + Range: &mcfunction.NumberRange{ + Min: 0.01, + Max: 1, + }, + }, + { + Kind: mcfunction.ParameterKindNumber, + Name: "fadeSeconds", + Optional: true, + Range: &mcfunction.NumberRange{ + Min: 0, + Max: 10, + }, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "repeatMode", + Optional: true, + Literals: []string{"loop", "play_once"}, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "action", + Literals: []string{"stop"}, + }, + { + Kind: mcfunction.ParameterKindNumber, + Name: "fadeSeconds", + Optional: true, + Range: &mcfunction.NumberRange{ + Min: 0, + Max: 10, + }, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "action", + Literals: []string{"volume"}, + }, + { + Kind: mcfunction.ParameterKindNumber, + Name: "volume", + Range: &mcfunction.NumberRange{ + Min: 0.01, + Max: 1, + }, + }, + }, + }, + }, +} diff --git a/internal/mcfunction/vanilla/op.go b/internal/mcfunction/vanilla/op.go new file mode 100644 index 0000000..1830dde --- /dev/null +++ b/internal/mcfunction/vanilla/op.go @@ -0,0 +1,18 @@ +package vanilla + +import "github.com/rockide/language-server/internal/mcfunction" + +var Op = &mcfunction.Spec{ + Name: "op", + Description: "Grants operator status to a player.", + Overloads: []mcfunction.SpecOverload{ + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindSelector, + Name: "player", + }, + }, + }, + }, +} diff --git a/internal/mcfunction/vanilla/particle.go b/internal/mcfunction/vanilla/particle.go new file mode 100644 index 0000000..90883f0 --- /dev/null +++ b/internal/mcfunction/vanilla/particle.go @@ -0,0 +1,24 @@ +package vanilla + +import "github.com/rockide/language-server/internal/mcfunction" + +var Particle = &mcfunction.Spec{ + Name: "particle", + Description: "Creates a particle emitter", + Overloads: []mcfunction.SpecOverload{ + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindString, + Name: "effect", + Tags: []string{mcfunction.TagParticleId}, + }, + { + Kind: mcfunction.ParameterKindVector3, + Name: "position", + Optional: true, + }, + }, + }, + }, +} diff --git a/internal/mcfunction/vanilla/place.go b/internal/mcfunction/vanilla/place.go new file mode 100644 index 0000000..1c04ea8 --- /dev/null +++ b/internal/mcfunction/vanilla/place.go @@ -0,0 +1,131 @@ +package vanilla + +import "github.com/rockide/language-server/internal/mcfunction" + +var Place = &mcfunction.Spec{ + Name: "place", + Description: "Places a jigsaw structure, feature, or feature rule in the world.", + Overloads: []mcfunction.SpecOverload{ + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "action", + Literals: []string{"place"}, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "structure", + Tags: []string{mcfunction.TagJigsawId}, + }, + { + Kind: mcfunction.ParameterKindVector3, + Name: "pos", + Optional: true, + }, + { + Kind: mcfunction.ParameterKindBoolean, + Name: "ignoreStartHeight", + Optional: true, + }, + { + Kind: mcfunction.ParameterKindBoolean, + Name: "keepJigsaws", + Optional: true, + }, + { + Kind: mcfunction.ParameterKindBoolean, + Name: "includeEntities", + Optional: true, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "liquidSettings", + Optional: true, + Literals: []string{"apply_waterlogging", "ignore_waterlogging"}, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "action", + Literals: []string{"place"}, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "pool", + Tags: []string{mcfunction.TagJigsawTemplatePoolId}, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "jigsawTarget", + }, + { + Kind: mcfunction.ParameterKindNumber, + Name: "maxDepth", + }, + { + Kind: mcfunction.ParameterKindVector3, + Name: "pos", + Optional: true, + }, + { + Kind: mcfunction.ParameterKindBoolean, + Name: "keepJigsaws", + Optional: true, + }, + { + Kind: mcfunction.ParameterKindBoolean, + Name: "includeEntities", + Optional: true, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "liquidSettings", + Optional: true, + Literals: []string{"apply_waterlogging", "ignore_waterlogging"}, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "action", + Literals: []string{"feature"}, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "feature", + Tags: []string{mcfunction.TagFeatureId}, + }, + { + Kind: mcfunction.ParameterKindVector3, + Name: "position", + Optional: true, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "action", + Literals: []string{"featurerule"}, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "featurerule", + Tags: []string{mcfunction.TagFeatureRuleId}, + }, + { + Kind: mcfunction.ParameterKindVector3, + Name: "position", + Optional: true, + }, + }, + }, + }, +} diff --git a/internal/mcfunction/vanilla/playanimation.go b/internal/mcfunction/vanilla/playanimation.go new file mode 100644 index 0000000..3438445 --- /dev/null +++ b/internal/mcfunction/vanilla/playanimation.go @@ -0,0 +1,46 @@ +package vanilla + +import "github.com/rockide/language-server/internal/mcfunction" + +var Playanimation = &mcfunction.Spec{ + Name: "playanimation", + Description: "Makes one or more entities play a one-off animation. Assumes all variables are setup correctly.", + Overloads: []mcfunction.SpecOverload{ + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindSelector, + Name: "entity", + }, + { + Kind: mcfunction.ParameterKindString, + Name: "animation", + Tags: []string{mcfunction.TagClientAnimationId}, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "next_state", + Optional: true, + Tags: []string{mcfunction.TagClientAnimationId}, + }, + { + Kind: mcfunction.ParameterKindNumber, + Name: "blend_out_time", + Optional: true, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "stop_expression", + Optional: true, + Literals: []string{`""`}, + Tags: []string{mcfunction.TagMolang}, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "controller", + Optional: true, + }, + }, + }, + }, +} diff --git a/internal/mcfunction/vanilla/playsound.go b/internal/mcfunction/vanilla/playsound.go new file mode 100644 index 0000000..9372b42 --- /dev/null +++ b/internal/mcfunction/vanilla/playsound.go @@ -0,0 +1,44 @@ +package vanilla + +import "github.com/rockide/language-server/internal/mcfunction" + +var Playsound = &mcfunction.Spec{ + Name: "playsound", + Description: "Plays a sound.", + Overloads: []mcfunction.SpecOverload{ + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindString, + Name: "sound", + Tags: []string{mcfunction.TagSoundId}, + }, + { + Kind: mcfunction.ParameterKindSelector, + Name: "player", + Optional: true, + }, + { + Kind: mcfunction.ParameterKindVector3, + Name: "position", + Optional: true, + }, + { + Kind: mcfunction.ParameterKindNumber, + Name: "volume", + Optional: true, + }, + { + Kind: mcfunction.ParameterKindNumber, + Name: "pitch", + Optional: true, + }, + { + Kind: mcfunction.ParameterKindNumber, + Name: "minimumVolume", + Optional: true, + }, + }, + }, + }, +} diff --git a/internal/mcfunction/vanilla/recipe.go b/internal/mcfunction/vanilla/recipe.go new file mode 100644 index 0000000..1028ac7 --- /dev/null +++ b/internal/mcfunction/vanilla/recipe.go @@ -0,0 +1,48 @@ +package vanilla + +import "github.com/rockide/language-server/internal/mcfunction" + +var Recipe = &mcfunction.Spec{ + Name: "recipe", + Description: "Unlocks recipe in the recipe book for a player.", + Overloads: []mcfunction.SpecOverload{ + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "give", + Literals: []string{"give"}, + }, + { + Kind: mcfunction.ParameterKindSelector, + Name: "player", + }, + { + Kind: mcfunction.ParameterKindString, + Name: "recipe", + Tags: []string{mcfunction.TagRecipeId}, + Literals: []string{"*"}, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "take", + Literals: []string{"take"}, + }, + { + Kind: mcfunction.ParameterKindSelector, + Name: "player", + }, + { + Kind: mcfunction.ParameterKindString, + Name: "recipe", + Tags: []string{mcfunction.TagRecipeId}, + Literals: []string{"*"}, + }, + }, + }, + }, +} diff --git a/internal/mcfunction/vanilla/reload.go b/internal/mcfunction/vanilla/reload.go new file mode 100644 index 0000000..841ad1e --- /dev/null +++ b/internal/mcfunction/vanilla/reload.go @@ -0,0 +1,20 @@ +package vanilla + +import "github.com/rockide/language-server/internal/mcfunction" + +var Reload = &mcfunction.Spec{ + Name: "reload", + Description: "Reloads all function and script files from all behavior packs, or optionally reloads the world and all resource and behavior packs.", + Overloads: []mcfunction.SpecOverload{ + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "all", + Optional: true, + Literals: []string{"all"}, + }, + }, + }, + }, +} diff --git a/internal/mcfunction/vanilla/replaceitem.go b/internal/mcfunction/vanilla/replaceitem.go new file mode 100644 index 0000000..20ea76f --- /dev/null +++ b/internal/mcfunction/vanilla/replaceitem.go @@ -0,0 +1,188 @@ +package vanilla + +import "github.com/rockide/language-server/internal/mcfunction" + +var Replaceitem = &mcfunction.Spec{ + Name: "replaceitem", + Description: "Replaces items in inventories.", + Overloads: []mcfunction.SpecOverload{ + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "block", + Literals: []string{"block"}, + }, + { + Kind: mcfunction.ParameterKindVector3, + Name: "position", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "slotType", + Literals: []string{"slot.container"}, + }, + { + Kind: mcfunction.ParameterKindInteger, + Name: "slotId", + }, + { + Kind: mcfunction.ParameterKindString, + Name: "itemName", + Tags: []string{mcfunction.TagItemId}, + }, + { + Kind: mcfunction.ParameterKindInteger, + Name: "amount", + Optional: true, + }, + { + Kind: mcfunction.ParameterKindInteger, + Name: "data", + Optional: true, + }, + { + Kind: mcfunction.ParameterKindItemNbt, + Name: "components", + Optional: true, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "entity", + Literals: []string{"entity"}, + }, + { + Kind: mcfunction.ParameterKindSelector, + Name: "target", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "slotType", + Literals: slotTypes, + }, + { + Kind: mcfunction.ParameterKindInteger, + Name: "slotId", + }, + { + Kind: mcfunction.ParameterKindString, + Name: "itemName", + Tags: []string{mcfunction.TagItemId}, + }, + { + Kind: mcfunction.ParameterKindInteger, + Name: "amount", + Optional: true, + }, + { + Kind: mcfunction.ParameterKindInteger, + Name: "data", + Optional: true, + }, + { + Kind: mcfunction.ParameterKindItemNbt, + Name: "components", + Optional: true, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "block", + Literals: []string{"block"}, + }, + { + Kind: mcfunction.ParameterKindVector3, + Name: "position", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "slotType", + Literals: []string{"slot.container"}, + }, + { + Kind: mcfunction.ParameterKindInteger, + Name: "slotId", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "oldItemHandling", + Literals: []string{"keep", "replace"}, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "itemName", + Tags: []string{mcfunction.TagItemId}, + }, + { + Kind: mcfunction.ParameterKindInteger, + Name: "amount", + Optional: true, + }, + { + Kind: mcfunction.ParameterKindInteger, + Name: "data", + Optional: true, + }, + { + Kind: mcfunction.ParameterKindItemNbt, + Name: "components", + Optional: true, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "entity", + Literals: []string{"entity"}, + }, + { + Kind: mcfunction.ParameterKindSelector, + Name: "target", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "slotType", + Literals: slotTypes, + }, + { + Kind: mcfunction.ParameterKindInteger, + Name: "slotId", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "oldItemHandling", + Literals: []string{"keep", "replace"}, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "itemName", + Tags: []string{mcfunction.TagItemId}, + }, + { + Kind: mcfunction.ParameterKindInteger, + Name: "amount", + Optional: true, + }, + { + Kind: mcfunction.ParameterKindInteger, + Name: "data", + Optional: true, + }, + { + Kind: mcfunction.ParameterKindItemNbt, + Name: "components", + Optional: true, + }, + }, + }, + }, +} diff --git a/internal/mcfunction/vanilla/ride.go b/internal/mcfunction/vanilla/ride.go new file mode 100644 index 0000000..3893228 --- /dev/null +++ b/internal/mcfunction/vanilla/ride.go @@ -0,0 +1,129 @@ +package vanilla + +import "github.com/rockide/language-server/internal/mcfunction" + +var Ride = &mcfunction.Spec{ + Name: "ride", + Description: "Makes entities ride other entities, stops entities from riding, makes rides evict their riders, or summons rides or riders.", + Overloads: []mcfunction.SpecOverload{ + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindSelector, + Name: "riders", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "mode", + Literals: []string{"start_riding"}, + }, + { + Kind: mcfunction.ParameterKindSelector, + Name: "ride", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "teleportRules", + Optional: true, + Literals: []string{"teleport_ride", "teleport_rider"}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "howToFill", + Optional: true, + Literals: []string{"if_group_fits", "until_full"}, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindSelector, + Name: "riders", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "mode", + Literals: []string{"stop_riding"}, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindSelector, + Name: "rides", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "mode", + Literals: []string{"evict_riders"}, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindSelector, + Name: "rides", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "mode", + Literals: []string{"summon_rider"}, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "entityType", + Tags: []string{mcfunction.TagEntityId}, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "spawnEvent", + Optional: true, + Tags: []string{mcfunction.TagEntityEvent}, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "nameTag", + Optional: true, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindSelector, + Name: "riders", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "mode", + Literals: []string{"summon_ride"}, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "entityType", + Tags: []string{mcfunction.TagEntityId}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "rideRules", + Optional: true, + Literals: []string{"no_ride_change", "reassign_rides", "skip_rides"}, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "spawnEvent", + Optional: true, + Tags: []string{mcfunction.TagEntityEvent}, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "nameTag", + Optional: true, + }, + }, + }, + }, +} diff --git a/internal/mcfunction/vanilla/say.go b/internal/mcfunction/vanilla/say.go new file mode 100644 index 0000000..43db5c4 --- /dev/null +++ b/internal/mcfunction/vanilla/say.go @@ -0,0 +1,19 @@ +package vanilla + +import "github.com/rockide/language-server/internal/mcfunction" + +var Say = &mcfunction.Spec{ + Name: "say", + Description: "Sends a message in the chat to other players.", + Overloads: []mcfunction.SpecOverload{ + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindString, + Name: "message", + Greedy: true, + }, + }, + }, + }, +} diff --git a/internal/mcfunction/vanilla/schedule.go b/internal/mcfunction/vanilla/schedule.go new file mode 100644 index 0000000..4ca61bf --- /dev/null +++ b/internal/mcfunction/vanilla/schedule.go @@ -0,0 +1,304 @@ +package vanilla + +import "github.com/rockide/language-server/internal/mcfunction" + +var Schedule = &mcfunction.Spec{ + Name: "schedule", + Description: "Schedules an action to be executed once an area is loaded, or after a certain amount of time.", + Overloads: []mcfunction.SpecOverload{ + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "mode", + Literals: []string{"delay"}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "condition", + Literals: []string{"add"}, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "function", + Tags: []string{mcfunction.TagFunctionFile}, + }, + { + Kind: mcfunction.ParameterKindNumber, + Name: "time", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "DelayMode", + Optional: true, + Literals: []string{"append", "replace"}, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "mode", + Literals: []string{"delay"}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "condition", + Literals: []string{"add"}, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "function", + Tags: []string{mcfunction.TagFunctionFile}, + }, + { + Kind: mcfunction.ParameterKindSuffixedInteger, + Name: "time", + Suffix: "t", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "DelayMode", + Literals: []string{"append", "replace"}, + Optional: true, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "mode", + Literals: []string{"delay"}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "condition", + Literals: []string{"add"}, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "function", + Tags: []string{mcfunction.TagFunctionFile}, + }, + { + Kind: mcfunction.ParameterKindSuffixedInteger, + Name: "time", + Suffix: "s", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "DelayMode", + Literals: []string{"append", "replace"}, + Optional: true, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "mode", + Literals: []string{"delay"}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "condition", + Literals: []string{"add"}, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "function", + Tags: []string{mcfunction.TagFunctionFile}, + }, + { + Kind: mcfunction.ParameterKindSuffixedInteger, + Name: "time", + Suffix: "d", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "DelayMode", + Literals: []string{"append", "replace"}, + Optional: true, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "mode", + Literals: []string{"delay"}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "condition", + Literals: []string{"clear"}, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "function", + Tags: []string{mcfunction.TagFunctionFile}, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "mode", + Literals: []string{"clear"}, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "function", + Tags: []string{mcfunction.TagFunctionFile}, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "mode", + Literals: []string{"on_area_loaded"}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "condition", + Literals: []string{"add"}, + }, + { + Kind: mcfunction.ParameterKindVector3, + Name: "from", + }, + { + Kind: mcfunction.ParameterKindVector3, + Name: "to", + }, + { + Kind: mcfunction.ParameterKindString, + Name: "function", + Tags: []string{mcfunction.TagFunctionFile}, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "mode", + Literals: []string{"on_area_loaded"}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "condition", + Literals: []string{"add"}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "type", + Literals: []string{"circle"}, + }, + { + Kind: mcfunction.ParameterKindVector3, + Name: "center", + }, + { + Kind: mcfunction.ParameterKindNumber, + Name: "radius", + }, + { + Kind: mcfunction.ParameterKindString, + Name: "function", + Tags: []string{mcfunction.TagFunctionFile}, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "mode", + Literals: []string{"on_area_loaded"}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "condition", + Literals: []string{"add"}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "type", + Literals: []string{"tickingarea"}, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "name", + Tags: []string{mcfunction.TagTickingAreaId}, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "function", + Tags: []string{mcfunction.TagFunctionFile}, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "mode", + Literals: []string{"on_area_loaded"}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "condition", + Literals: []string{"clear"}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "cleartype", + Literals: []string{"tickingarea"}, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "name", + Tags: []string{mcfunction.TagTickingAreaId}, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "function", + Tags: []string{mcfunction.TagFunctionFile}, + Optional: true, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "mode", + Literals: []string{"on_area_loaded"}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "condition", + Literals: []string{"clear"}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "cleartype", + Literals: []string{"function"}, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "function", + Tags: []string{mcfunction.TagFunctionFile}, + }, + }, + }, + }, +} diff --git a/internal/mcfunction/vanilla/scoreboard.go b/internal/mcfunction/vanilla/scoreboard.go new file mode 100644 index 0000000..db5dd77 --- /dev/null +++ b/internal/mcfunction/vanilla/scoreboard.go @@ -0,0 +1,308 @@ +package vanilla + +import "github.com/rockide/language-server/internal/mcfunction" + +var Scoreboard = &mcfunction.Spec{ + Name: "scoreboard", + Description: "Tracks and displays scores for various objectives.", + Overloads: []mcfunction.SpecOverload{ + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "category", + Literals: []string{"objectives"}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "action", + Literals: []string{"add"}, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "objective", + Tags: []string{mcfunction.TagScoreboardObjectiveId}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "criteria", + Literals: []string{"dummy"}, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "displayName", + Optional: true, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "category", + Literals: []string{"objectives"}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "action", + Literals: []string{"remove"}, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "objective", + Tags: []string{mcfunction.TagScoreboardObjectiveId}, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "category", + Literals: []string{"objectives"}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "action", + Literals: []string{"list"}, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "category", + Literals: []string{"objectives"}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "action", + Literals: []string{"setdisplay"}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "displaySlot", + Literals: []string{"belowname", "list", "sidebar"}, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "objective", + Optional: true, + Tags: []string{mcfunction.TagScoreboardObjectiveId}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "sortOrder", + Optional: true, + Literals: []string{"ascending", "descending"}, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "category", + Literals: []string{"objectives"}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "action", + Literals: []string{"setdisplay"}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "displaySlot", + Literals: []string{"belowname"}, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "objective", + Optional: true, + Tags: []string{mcfunction.TagScoreboardObjectiveId}, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "category", + Literals: []string{"players"}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "action", + Literals: []string{"list"}, + }, + { + Kind: mcfunction.ParameterKindSelector, + Name: "playername", + Optional: true, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "category", + Literals: []string{"players"}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "action", + Literals: []string{"reset"}, + }, + { + Kind: mcfunction.ParameterKindSelector, + Name: "player", + }, + { + Kind: mcfunction.ParameterKindString, + Name: "objective", + Tags: []string{mcfunction.TagScoreboardObjectiveId}, + Optional: true, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "category", + Literals: []string{"players"}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "action", + Literals: []string{"test"}, + }, + { + Kind: mcfunction.ParameterKindSelector, + Name: "player", + }, + { + Kind: mcfunction.ParameterKindString, + Name: "objective", + Tags: []string{mcfunction.TagScoreboardObjectiveId}, + }, + { + Kind: mcfunction.ParameterKindWildcardInteger, + Name: "min", + }, + { + Kind: mcfunction.ParameterKindWildcardInteger, + Name: "max", + Optional: true, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "category", + Literals: []string{"players"}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "action", + Literals: []string{"random"}, + }, + { + Kind: mcfunction.ParameterKindSelector, + Name: "player", + }, + { + Kind: mcfunction.ParameterKindString, + Name: "objective", + Tags: []string{mcfunction.TagScoreboardObjectiveId}, + }, + { + Kind: mcfunction.ParameterKindInteger, + Name: "min", + }, + { + Kind: mcfunction.ParameterKindInteger, + Name: "max", + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "category", + Literals: []string{"players"}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "action", + Literals: []string{"set", "add", "remove"}, + }, + { + Kind: mcfunction.ParameterKindSelector, + Name: "player", + }, + { + Kind: mcfunction.ParameterKindString, + Name: "objective", + Tags: []string{mcfunction.TagScoreboardObjectiveId}, + }, + { + Kind: mcfunction.ParameterKindInteger, + Name: "count", + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "category", + Literals: []string{"players"}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "action", + Literals: []string{"operation"}, + }, + { + Kind: mcfunction.ParameterKindSelector, + Name: "targetName", + }, + { + Kind: mcfunction.ParameterKindString, + Name: "targetObjective", + Tags: []string{mcfunction.TagScoreboardObjectiveId}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "operation", + Literals: []string{ + "%=", + "*=", + "+=", + "-=", + "/=", + "<", + "=", + ">", + "><", + }, + }, + { + Kind: mcfunction.ParameterKindSelector, + Name: "selector", + }, + { + Kind: mcfunction.ParameterKindString, + Name: "objective", + Tags: []string{mcfunction.TagScoreboardObjectiveId}, + }, + }, + }, + }, +} diff --git a/internal/mcfunction/vanilla/script.go b/internal/mcfunction/vanilla/script.go new file mode 100644 index 0000000..9b86996 --- /dev/null +++ b/internal/mcfunction/vanilla/script.go @@ -0,0 +1,122 @@ +package vanilla + +import "github.com/rockide/language-server/internal/mcfunction" + +var Script = &mcfunction.Spec{ + Name: "script", + Description: "Script debugger commands.", + Overloads: []mcfunction.SpecOverload{ + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "mode", + Literals: []string{"debugger"}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "action", + Literals: []string{"listen"}, + }, + { + Kind: mcfunction.ParameterKindInteger, + Name: "port", + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "mode", + Literals: []string{"debugger"}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "action", + Literals: []string{"connect"}, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "host", + Optional: true, + }, + { + Kind: mcfunction.ParameterKindInteger, + Name: "port", + Optional: true, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "mode", + Literals: []string{"debugger"}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "action", + Literals: []string{"close"}, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "mode", + Literals: []string{"profiler"}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "action", + Literals: []string{"start"}, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "mode", + Literals: []string{"profiler"}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "action", + Literals: []string{"stop"}, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "mode", + Literals: []string{"diagnostics"}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "action", + Literals: []string{"startcapture"}, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "mode", + Literals: []string{"diagnostics"}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "action", + Literals: []string{"stopcapture"}, + }, + }, + }, + }, +} diff --git a/internal/mcfunction/vanilla/scriptevent.go b/internal/mcfunction/vanilla/scriptevent.go new file mode 100644 index 0000000..2b11e43 --- /dev/null +++ b/internal/mcfunction/vanilla/scriptevent.go @@ -0,0 +1,23 @@ +package vanilla + +import "github.com/rockide/language-server/internal/mcfunction" + +var Scriptevent = &mcfunction.Spec{ + Name: "scriptevent", + Description: "Triggers a script event with an ID and message.", + Overloads: []mcfunction.SpecOverload{ + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindString, + Name: "messageId", + }, + { + Kind: mcfunction.ParameterKindString, + Name: "message", + Greedy: true, + }, + }, + }, + }, +} diff --git a/internal/mcfunction/vanilla/setblock.go b/internal/mcfunction/vanilla/setblock.go new file mode 100644 index 0000000..33446c1 --- /dev/null +++ b/internal/mcfunction/vanilla/setblock.go @@ -0,0 +1,53 @@ +package vanilla + +import "github.com/rockide/language-server/internal/mcfunction" + +var Setblock = &mcfunction.Spec{ + Name: "setblock", + Description: "Changes a block to another block.", + Overloads: []mcfunction.SpecOverload{ + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindVector3, + Name: "position", + }, + { + Kind: mcfunction.ParameterKindString, + Name: "tileName", + Tags: []string{mcfunction.TagBlockId}, + }, + { + Kind: mcfunction.ParameterKindMap, + Name: "blockStates", + Tags: []string{mcfunction.TagBlockState}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "oldBlockHandling", + Optional: true, + Literals: []string{"destroy", "keep", "replace"}, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindVector3, + Name: "position", + }, + { + Kind: mcfunction.ParameterKindString, + Name: "tileName", + Tags: []string{mcfunction.TagBlockId}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "oldBlockHandling", + Optional: true, + Literals: []string{"destroy", "keep", "replace"}, + }, + }, + }, + }, +} diff --git a/internal/mcfunction/vanilla/setmaxplayers.go b/internal/mcfunction/vanilla/setmaxplayers.go new file mode 100644 index 0000000..35c09aa --- /dev/null +++ b/internal/mcfunction/vanilla/setmaxplayers.go @@ -0,0 +1,18 @@ +package vanilla + +import "github.com/rockide/language-server/internal/mcfunction" + +var Setmaxplayers = &mcfunction.Spec{ + Name: "setmaxplayers", + Description: "Sets the maximum number of players for this game session.", + Overloads: []mcfunction.SpecOverload{ + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindInteger, + Name: "maxPlayers", + }, + }, + }, + }, +} diff --git a/internal/mcfunction/vanilla/setworldspawn.go b/internal/mcfunction/vanilla/setworldspawn.go new file mode 100644 index 0000000..bdbb8d5 --- /dev/null +++ b/internal/mcfunction/vanilla/setworldspawn.go @@ -0,0 +1,19 @@ +package vanilla + +import "github.com/rockide/language-server/internal/mcfunction" + +var Setworldspawn = &mcfunction.Spec{ + Name: "setworldspawn", + Description: "Sets the world spawn.", + Overloads: []mcfunction.SpecOverload{ + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindVector3, + Name: "spawnPoint", + Optional: true, + }, + }, + }, + }, +} diff --git a/internal/mcfunction/vanilla/spawnpoint.go b/internal/mcfunction/vanilla/spawnpoint.go new file mode 100644 index 0000000..e96568b --- /dev/null +++ b/internal/mcfunction/vanilla/spawnpoint.go @@ -0,0 +1,24 @@ +package vanilla + +import "github.com/rockide/language-server/internal/mcfunction" + +var Spawnpoint = &mcfunction.Spec{ + Name: "spawnpoint", + Description: "Sets the spawn point for a player.", + Overloads: []mcfunction.SpecOverload{ + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindSelector, + Name: "player", + Optional: true, + }, + { + Kind: mcfunction.ParameterKindVector3, + Name: "spawnPos", + Optional: true, + }, + }, + }, + }, +} diff --git a/internal/mcfunction/vanilla/spreadplayers.go b/internal/mcfunction/vanilla/spreadplayers.go new file mode 100644 index 0000000..0569fdb --- /dev/null +++ b/internal/mcfunction/vanilla/spreadplayers.go @@ -0,0 +1,51 @@ +package vanilla + +import ( + "math" + + "github.com/rockide/language-server/internal/mcfunction" +) + +var Spreadplayers = &mcfunction.Spec{ + Name: "spreadplayers", + Description: "Teleports entities to random locations.", + Overloads: []mcfunction.SpecOverload{ + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindRelativeNumber, + Name: "x", + }, + { + Kind: mcfunction.ParameterKindRelativeNumber, + Name: "z", + }, + { + Kind: mcfunction.ParameterKindNumber, + Name: "spreadDistance", + Range: &mcfunction.NumberRange{ + Min: 0, + Max: math.MaxFloat64, + }, + }, + { + Kind: mcfunction.ParameterKindNumber, + Name: "maxRange", + Range: &mcfunction.NumberRange{ + Min: 1, + Max: math.MaxFloat64, + }, + }, + { + Kind: mcfunction.ParameterKindSelector, + Name: "victim", + }, + { + Kind: mcfunction.ParameterKindNumber, + Name: "maxHeight", + Optional: true, + }, + }, + }, + }, +} diff --git a/internal/mcfunction/vanilla/stopsound.go b/internal/mcfunction/vanilla/stopsound.go new file mode 100644 index 0000000..77f5baf --- /dev/null +++ b/internal/mcfunction/vanilla/stopsound.go @@ -0,0 +1,24 @@ +package vanilla + +import "github.com/rockide/language-server/internal/mcfunction" + +var Stopsound = &mcfunction.Spec{ + Name: "stopsound", + Description: "Stops a sound.", + Overloads: []mcfunction.SpecOverload{ + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindSelector, + Name: "player", + }, + { + Kind: mcfunction.ParameterKindString, + Name: "sound", + Optional: true, + Tags: []string{mcfunction.TagSoundId}, + }, + }, + }, + }, +} diff --git a/internal/mcfunction/vanilla/structure.go b/internal/mcfunction/vanilla/structure.go new file mode 100644 index 0000000..25db6a8 --- /dev/null +++ b/internal/mcfunction/vanilla/structure.go @@ -0,0 +1,216 @@ +package vanilla + +import ( + "math" + + "github.com/rockide/language-server/internal/mcfunction" +) + +var Structure = &mcfunction.Spec{ + Name: "structure", + Description: "Saves or loads a structure in the world.", + Overloads: []mcfunction.SpecOverload{ + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "action", + Literals: []string{"save"}, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "name", + Tags: []string{mcfunction.TagStructureFile}, + }, + { + Kind: mcfunction.ParameterKindVector3, + Name: "from", + }, + { + Kind: mcfunction.ParameterKindVector3, + Name: "to", + }, + { + Kind: mcfunction.ParameterKindBoolean, + Name: "includeEntities", + Optional: true, + }, + { + Kind: mcfunction.ParameterKindBoolean, + Name: "includeBlocks", + Optional: true, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "action", + Literals: []string{"delete"}, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "name", + Tags: []string{mcfunction.TagStructureFile}, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "action", + Literals: []string{"load"}, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "name", + Tags: []string{mcfunction.TagStructureFile}, + }, + { + Kind: mcfunction.ParameterKindVector3, + Name: "to", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "rotation", + Optional: true, + Literals: []string{ + "0_degrees", + "90_degrees", + "180_degrees", + "270_degrees", + }, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "mirror", + Optional: true, + Literals: []string{ + "none", + "x", + "xz", + "z", + }, + }, + { + Kind: mcfunction.ParameterKindBoolean, + Name: "includeEntities", + Optional: true, + }, + { + Kind: mcfunction.ParameterKindBoolean, + Name: "includeBlocks", + Optional: true, + }, + { + Kind: mcfunction.ParameterKindBoolean, + Name: "waterlogged", + Optional: true, + }, + { + Kind: mcfunction.ParameterKindNumber, + Name: "integrity", + Optional: true, + Range: &mcfunction.NumberRange{ + Min: 0, + Max: 100, + }, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "seed", + Optional: true, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "action", + Literals: []string{"load"}, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "name", + Tags: []string{mcfunction.TagStructureFile}, + }, + { + Kind: mcfunction.ParameterKindVector3, + Name: "to", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "rotation", + Optional: true, + Literals: []string{ + "0_degrees", + "90_degrees", + "180_degrees", + "270_degrees", + }, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "mirror", + Optional: true, + Literals: []string{ + "none", + "x", + "xz", + "z", + }, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "animationMode", + Optional: true, + Literals: []string{ + "block_by_block", + "layer_by_layer", + }, + }, + { + Kind: mcfunction.ParameterKindInteger, + Name: "animationSeconds", + Optional: true, + Range: &mcfunction.NumberRange{ + Min: 0, + Max: math.MaxFloat64, + }, + }, + { + Kind: mcfunction.ParameterKindBoolean, + Name: "includeEntities", + Optional: true, + }, + { + Kind: mcfunction.ParameterKindBoolean, + Name: "includeBlocks", + Optional: true, + }, + { + Kind: mcfunction.ParameterKindBoolean, + Name: "waterlogged", + Optional: true, + }, + { + Kind: mcfunction.ParameterKindNumber, + Name: "integrity", + Optional: true, + Range: &mcfunction.NumberRange{ + Min: 0, + Max: 100, + }, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "seed", + Optional: true, + }, + }, + }, + }, +} diff --git a/internal/mcfunction/vanilla/summon.go b/internal/mcfunction/vanilla/summon.go new file mode 100644 index 0000000..b1876ac --- /dev/null +++ b/internal/mcfunction/vanilla/summon.go @@ -0,0 +1,133 @@ +package vanilla + +import "github.com/rockide/language-server/internal/mcfunction" + +var Summon = &mcfunction.Spec{ + Name: "summon", + Description: "Summons an entity.", + Overloads: []mcfunction.SpecOverload{ + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindString, + Name: "entityType", + Tags: []string{mcfunction.TagEntityId}, + }, + { + Kind: mcfunction.ParameterKindVector3, + Name: "spawnPos", + Optional: true, + }, + { + Kind: mcfunction.ParameterKindRelativeNumber, + Name: "yRot", + Optional: true, + Tags: []string{mcfunction.TagYaw}, + }, + { + Kind: mcfunction.ParameterKindRelativeNumber, + Name: "xRot", + Optional: true, + Tags: []string{mcfunction.TagPitch}, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "spawnEvent", + Tags: []string{mcfunction.TagEntityEvent}, + Optional: true, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "nameTag", + Optional: true, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindString, + Name: "entityType", + Tags: []string{mcfunction.TagEntityId}, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "nameTag", + }, + { + Kind: mcfunction.ParameterKindVector3, + Name: "spawnPos", + Optional: true, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindString, + Name: "entityType", + Tags: []string{mcfunction.TagEntityId}, + }, + { + Kind: mcfunction.ParameterKindVector3, + Name: "spawnPos", + Optional: true, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "facing", + Literals: []string{"facing"}, + }, + { + Kind: mcfunction.ParameterKindVector3, + Name: "lookAtPosition", + }, + { + Kind: mcfunction.ParameterKindString, + Name: "spawnEvent", + Tags: []string{mcfunction.TagEntityEvent}, + Optional: true, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "nameTag", + Optional: true, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindString, + Name: "entityType", + Tags: []string{mcfunction.TagEntityId}, + }, + { + Kind: mcfunction.ParameterKindVector3, + Name: "spawnPos", + Optional: true, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "facing", + Literals: []string{"facing"}, + }, + { + Kind: mcfunction.ParameterKindSelector, + Name: "lookAtEntity", + }, + { + Kind: mcfunction.ParameterKindString, + Name: "spawnEvent", + Tags: []string{mcfunction.TagEntityEvent}, + Optional: true, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "nameTag", + Optional: true, + }, + }, + }, + }, +} diff --git a/internal/mcfunction/vanilla/tag.go b/internal/mcfunction/vanilla/tag.go new file mode 100644 index 0000000..7475714 --- /dev/null +++ b/internal/mcfunction/vanilla/tag.go @@ -0,0 +1,41 @@ +package vanilla + +import "github.com/rockide/language-server/internal/mcfunction" + +var Tag = &mcfunction.Spec{ + Name: "tag", + Description: "Manages tags stored in entities.", + Overloads: []mcfunction.SpecOverload{ + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindSelector, + Name: "entity", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "action", + Literals: []string{"add", "remove"}, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "name", + Tags: []string{mcfunction.TagTagId}, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindSelector, + Name: "entity", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "action", + Literals: []string{"list"}, + }, + }, + }, + }, +} diff --git a/internal/mcfunction/vanilla/teleport.go b/internal/mcfunction/vanilla/teleport.go new file mode 100644 index 0000000..c8599b8 --- /dev/null +++ b/internal/mcfunction/vanilla/teleport.go @@ -0,0 +1,214 @@ +package vanilla + +import "github.com/rockide/language-server/internal/mcfunction" + +var Teleport = &mcfunction.Spec{ + Name: "teleport", + Aliases: []string{"tp"}, + Description: "Teleports entities (players, mobs, etc.).", + Overloads: []mcfunction.SpecOverload{ + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindVector3, + Name: "destination", + }, + { + Kind: mcfunction.ParameterKindBoolean, + Name: "checkForBlocks", + Optional: true, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindVector3, + Name: "destination", + }, + { + Kind: mcfunction.ParameterKindRelativeNumber, + Name: "yRot", + Optional: true, + Tags: []string{mcfunction.TagYaw}, + }, + { + Kind: mcfunction.ParameterKindRelativeNumber, + Name: "xRot", + Optional: true, + Tags: []string{mcfunction.TagPitch}, + }, + { + Kind: mcfunction.ParameterKindBoolean, + Name: "checkForBlocks", + Optional: true, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindVector3, + Name: "destination", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "facing", + Literals: []string{"facing"}, + }, + { + Kind: mcfunction.ParameterKindVector3, + Name: "lookAtPosition", + }, + { + Kind: mcfunction.ParameterKindBoolean, + Name: "checkForBlocks", + Optional: true, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindVector3, + Name: "destination", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "facing", + Literals: []string{"facing"}, + }, + { + Kind: mcfunction.ParameterKindSelector, + Name: "lookAtEntity", + }, + { + Kind: mcfunction.ParameterKindBoolean, + Name: "checkForBlocks", + Optional: true, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindSelector, + Name: "victim", + }, + { + Kind: mcfunction.ParameterKindVector3, + Name: "destination", + }, + { + Kind: mcfunction.ParameterKindRelativeNumber, + Name: "yRot", + Optional: true, + }, + { + Kind: mcfunction.ParameterKindRelativeNumber, + Name: "xRot", + Optional: true, + }, + { + Kind: mcfunction.ParameterKindBoolean, + Name: "checkForBlocks", + Optional: true, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindSelector, + Name: "victim", + }, + { + Kind: mcfunction.ParameterKindVector3, + Name: "destination", + }, + { + Kind: mcfunction.ParameterKindBoolean, + Name: "checkForBlocks", + Optional: true, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindSelector, + Name: "victim", + }, + { + Kind: mcfunction.ParameterKindVector3, + Name: "destination", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "facing", + Literals: []string{"facing"}, + }, + { + Kind: mcfunction.ParameterKindVector3, + Name: "lookAtPosition", + }, + { + Kind: mcfunction.ParameterKindBoolean, + Name: "checkForBlocks", + Optional: true, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindSelector, + Name: "victim", + }, + { + Kind: mcfunction.ParameterKindVector3, + Name: "destination", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "facing", + Literals: []string{"facing"}, + }, + { + Kind: mcfunction.ParameterKindSelector, + Name: "lookAtEntity", + }, + { + Kind: mcfunction.ParameterKindBoolean, + Name: "checkForBlocks", + Optional: true, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindSelector, + Name: "destination", + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindSelector, + Name: "victim", + }, + { + Kind: mcfunction.ParameterKindSelector, + Name: "destination", + }, + { + Kind: mcfunction.ParameterKindBoolean, + Name: "checkForBlocks", + Optional: true, + }, + }, + }, + }, +} diff --git a/internal/mcfunction/vanilla/tell.go b/internal/mcfunction/vanilla/tell.go new file mode 100644 index 0000000..159e385 --- /dev/null +++ b/internal/mcfunction/vanilla/tell.go @@ -0,0 +1,23 @@ +package vanilla + +import "github.com/rockide/language-server/internal/mcfunction" + +var Tell = &mcfunction.Spec{ + Name: "tell", + Description: "Sends a private message to one or more players.", + Overloads: []mcfunction.SpecOverload{ + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindSelector, + Name: "target", + }, + { + Kind: mcfunction.ParameterKindString, + Name: "message", + Greedy: true, + }, + }, + }, + }, +} diff --git a/internal/mcfunction/vanilla/tellraw.go b/internal/mcfunction/vanilla/tellraw.go new file mode 100644 index 0000000..a07c5fd --- /dev/null +++ b/internal/mcfunction/vanilla/tellraw.go @@ -0,0 +1,22 @@ +package vanilla + +import "github.com/rockide/language-server/internal/mcfunction" + +var Tellraw = &mcfunction.Spec{ + Name: "tellraw", + Description: "Sends a JSON message to players.", + Overloads: []mcfunction.SpecOverload{ + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindSelector, + Name: "target", + }, + { + Kind: mcfunction.ParameterKindRawMessage, + Name: "raw json message", + }, + }, + }, + }, +} diff --git a/internal/mcfunction/vanilla/testfor.go b/internal/mcfunction/vanilla/testfor.go new file mode 100644 index 0000000..0a70f03 --- /dev/null +++ b/internal/mcfunction/vanilla/testfor.go @@ -0,0 +1,18 @@ +package vanilla + +import "github.com/rockide/language-server/internal/mcfunction" + +var Testfor = &mcfunction.Spec{ + Name: "testfor", + Description: "Counts entities (players, mobs, items, etc.) matching specified conditions.", + Overloads: []mcfunction.SpecOverload{ + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindSelector, + Name: "victim", + }, + }, + }, + }, +} diff --git a/internal/mcfunction/vanilla/testforblock.go b/internal/mcfunction/vanilla/testforblock.go new file mode 100644 index 0000000..9eceb1e --- /dev/null +++ b/internal/mcfunction/vanilla/testforblock.go @@ -0,0 +1,29 @@ +package vanilla + +import "github.com/rockide/language-server/internal/mcfunction" + +var Testforblock = &mcfunction.Spec{ + Name: "testforblock", + Description: "Tests whether a certain block is in a specific location.", + Overloads: []mcfunction.SpecOverload{ + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindVector3, + Name: "position", + }, + { + Kind: mcfunction.ParameterKindString, + Name: "tileName", + Tags: []string{mcfunction.TagBlockId}, + }, + { + Kind: mcfunction.ParameterKindMap, + Name: "blockStates", + Optional: true, + Tags: []string{mcfunction.TagBlockState}, + }, + }, + }, + }, +} diff --git a/internal/mcfunction/vanilla/testforblocks.go b/internal/mcfunction/vanilla/testforblocks.go new file mode 100644 index 0000000..a83a5ee --- /dev/null +++ b/internal/mcfunction/vanilla/testforblocks.go @@ -0,0 +1,32 @@ +package vanilla + +import "github.com/rockide/language-server/internal/mcfunction" + +var Testforblocks = &mcfunction.Spec{ + Name: "testforblocks", + Description: "Tests whether the blocks in two regions match.", + Overloads: []mcfunction.SpecOverload{ + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindVector3, + Name: "begin", + }, + { + Kind: mcfunction.ParameterKindVector3, + Name: "end", + }, + { + Kind: mcfunction.ParameterKindVector3, + Name: "destination", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "mode", + Optional: true, + Literals: []string{"all", "masked"}, + }, + }, + }, + }, +} diff --git a/internal/mcfunction/vanilla/tickingarea.go b/internal/mcfunction/vanilla/tickingarea.go new file mode 100644 index 0000000..70acad1 --- /dev/null +++ b/internal/mcfunction/vanilla/tickingarea.go @@ -0,0 +1,167 @@ +package vanilla + +import ( + "math" + + "github.com/rockide/language-server/internal/mcfunction" +) + +var Tickingarea = &mcfunction.Spec{ + Name: "tickingarea", + Description: "Add, remove, or list ticking areas.", + Overloads: []mcfunction.SpecOverload{ + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "mode", + Literals: []string{"add"}, + }, + { + Kind: mcfunction.ParameterKindVector3, + Name: "from", + }, + { + Kind: mcfunction.ParameterKindVector3, + Name: "to", + }, + { + Kind: mcfunction.ParameterKindString, + Name: "name", + Optional: true, + Tags: []string{mcfunction.TagTickingAreaId}, + }, + { + Kind: mcfunction.ParameterKindBoolean, + Name: "preload", + Optional: true, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "mode", + Literals: []string{"add"}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "circle", + Literals: []string{"circle"}, + }, + { + Kind: mcfunction.ParameterKindVector3, + Name: "center", + }, + { + Kind: mcfunction.ParameterKindInteger, + Name: "radius", + Range: &mcfunction.NumberRange{ + Min: 0, + Max: math.MaxFloat64, + }, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "name", + Optional: true, + Tags: []string{mcfunction.TagTickingAreaId}, + }, + { + Kind: mcfunction.ParameterKindBoolean, + Name: "preload", + Optional: true, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "mode", + Literals: []string{"remove"}, + }, + { + Kind: mcfunction.ParameterKindVector3, + Name: "position", + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "mode", + Literals: []string{"remove"}, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "name", + Tags: []string{mcfunction.TagTickingAreaId}, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "mode", + Literals: []string{"remove_all"}, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "mode", + Literals: []string{"list"}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "all-dimensions", + Optional: true, + Literals: []string{"all-dimensions"}, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "mode", + Literals: []string{"preload"}, + }, + { + Kind: mcfunction.ParameterKindVector3, + Name: "position", + }, + { + Kind: mcfunction.ParameterKindBoolean, + Name: "preload", + Optional: true, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "mode", + Literals: []string{"preload"}, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "name", + Tags: []string{mcfunction.TagTickingAreaId}, + }, + { + Kind: mcfunction.ParameterKindBoolean, + Name: "preload", + Optional: true, + }, + }, + }, + }, +} diff --git a/internal/mcfunction/vanilla/time.go b/internal/mcfunction/vanilla/time.go new file mode 100644 index 0000000..180ce52 --- /dev/null +++ b/internal/mcfunction/vanilla/time.go @@ -0,0 +1,75 @@ +package vanilla + +import "github.com/rockide/language-server/internal/mcfunction" + +var Time = &mcfunction.Spec{ + Name: "time", + Description: "Changes or queries the world's game time.", + Overloads: []mcfunction.SpecOverload{ + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "mode", + Literals: []string{"add"}, + }, + { + Kind: mcfunction.ParameterKindInteger, + Name: "amount", + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "mode", + Literals: []string{"set"}, + }, + { + Kind: mcfunction.ParameterKindInteger, + Name: "amount", + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "mode", + Literals: []string{"set"}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "time", + Literals: []string{ + "day", + "midnight", + "night", + "noon", + "sunrise", + "sunset", + }, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "mode", + Literals: []string{"query"}, + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "time", + Literals: []string{ + "day", + "daytime", + "gametime", + }, + }, + }, + }, + }, +} diff --git a/internal/mcfunction/vanilla/title.go b/internal/mcfunction/vanilla/title.go new file mode 100644 index 0000000..0f0dc91 --- /dev/null +++ b/internal/mcfunction/vanilla/title.go @@ -0,0 +1,95 @@ +package vanilla + +import ( + "math" + + "github.com/rockide/language-server/internal/mcfunction" +) + +var Title = &mcfunction.Spec{ + Name: "title", + Description: "Controls screen titles.", + Overloads: []mcfunction.SpecOverload{ + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindSelector, + Name: "player", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "clear", + Literals: []string{"clear"}, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindSelector, + Name: "player", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "reset", + Literals: []string{"reset"}, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindSelector, + Name: "player", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "titleLocation", + Literals: []string{"title", "subtitle", "actionbar"}, + }, + { + Kind: mcfunction.ParameterKindString, + Name: "titleText", + Greedy: true, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindSelector, + Name: "player", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "times", + Literals: []string{"times"}, + }, + { + Kind: mcfunction.ParameterKindInteger, + Name: "fadeIn", + Range: &mcfunction.NumberRange{ + Min: 0, + Max: math.MaxFloat64, + }, + }, + { + Kind: mcfunction.ParameterKindInteger, + Name: "stay", + Range: &mcfunction.NumberRange{ + Min: 0, + Max: math.MaxFloat64, + }, + }, + { + Kind: mcfunction.ParameterKindInteger, + Name: "fadeOut", + Range: &mcfunction.NumberRange{ + Min: 0, + Max: math.MaxFloat64, + }, + }, + }, + }, + }, +} diff --git a/internal/mcfunction/vanilla/titleraw.go b/internal/mcfunction/vanilla/titleraw.go new file mode 100644 index 0000000..25a3b78 --- /dev/null +++ b/internal/mcfunction/vanilla/titleraw.go @@ -0,0 +1,94 @@ +package vanilla + +import ( + "math" + + "github.com/rockide/language-server/internal/mcfunction" +) + +var Titleraw = &mcfunction.Spec{ + Name: "titleraw", + Description: "Controls screen titles with JSON messages.", + Overloads: []mcfunction.SpecOverload{ + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindSelector, + Name: "player", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "clear", + Literals: []string{"clear"}, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindSelector, + Name: "player", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "reset", + Literals: []string{"reset"}, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindSelector, + Name: "player", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "titleLocation", + Literals: []string{"title", "subtitle", "actionbar"}, + }, + { + Kind: mcfunction.ParameterKindRawMessage, + Name: "raw json titleText", + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindSelector, + Name: "player", + }, + { + Kind: mcfunction.ParameterKindLiteral, + Name: "times", + Literals: []string{"times"}, + }, + { + Kind: mcfunction.ParameterKindInteger, + Name: "fadeIn", + Range: &mcfunction.NumberRange{ + Min: 0, + Max: math.MaxFloat64, + }, + }, + { + Kind: mcfunction.ParameterKindInteger, + Name: "stay", + Range: &mcfunction.NumberRange{ + Min: 0, + Max: math.MaxFloat64, + }, + }, + { + Kind: mcfunction.ParameterKindInteger, + Name: "fadeOut", + Range: &mcfunction.NumberRange{ + Min: 0, + Max: math.MaxFloat64, + }, + }, + }, + }, + }, +} diff --git a/internal/mcfunction/vanilla/toggledownfall.go b/internal/mcfunction/vanilla/toggledownfall.go new file mode 100644 index 0000000..7ca8758 --- /dev/null +++ b/internal/mcfunction/vanilla/toggledownfall.go @@ -0,0 +1,13 @@ +package vanilla + +import "github.com/rockide/language-server/internal/mcfunction" + +var Toggledownfall = &mcfunction.Spec{ + Name: "toggledownfall", + Description: "Toggles the weather.", + Overloads: []mcfunction.SpecOverload{ + { + Parameters: []mcfunction.ParameterSpec{}, + }, + }, +} diff --git a/internal/mcfunction/vanilla/weather.go b/internal/mcfunction/vanilla/weather.go new file mode 100644 index 0000000..aa23796 --- /dev/null +++ b/internal/mcfunction/vanilla/weather.go @@ -0,0 +1,33 @@ +package vanilla + +import "github.com/rockide/language-server/internal/mcfunction" + +var Weather = &mcfunction.Spec{ + Name: "weather", + Description: "Sets the weather.", + Overloads: []mcfunction.SpecOverload{ + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "type", + Literals: []string{"clear", "rain", "thunder"}, + }, + { + Kind: mcfunction.ParameterKindInteger, + Name: "duration", + Optional: true, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindLiteral, + Name: "query", + Literals: []string{"query"}, + }, + }, + }, + }, +} diff --git a/internal/mcfunction/vanilla/xp.go b/internal/mcfunction/vanilla/xp.go new file mode 100644 index 0000000..e764e23 --- /dev/null +++ b/internal/mcfunction/vanilla/xp.go @@ -0,0 +1,37 @@ +package vanilla + +import "github.com/rockide/language-server/internal/mcfunction" + +var Xp = &mcfunction.Spec{ + Name: "xp", + Description: "Adds or removes player experience.", + Overloads: []mcfunction.SpecOverload{ + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindInteger, + Name: "amount", + }, + { + Kind: mcfunction.ParameterKindSelector, + Name: "player", + Optional: true, + }, + }, + }, + { + Parameters: []mcfunction.ParameterSpec{ + { + Kind: mcfunction.ParameterKindSuffixedInteger, + Name: "amount", + Suffix: "L", + }, + { + Kind: mcfunction.ParameterKindSelector, + Name: "player", + Optional: true, + }, + }, + }, + }, +} diff --git a/stores/path.go b/stores/path.go index 16ef0e5..e15a577 100644 --- a/stores/path.go +++ b/stores/path.go @@ -58,6 +58,7 @@ func (s *PathStore) Delete(uri protocol.DocumentURI) { var ( LootTablePath = NewPathStore(vanilla.LootTable) + McFunctionPath = NewPathStore(nil, ".mcfunction") StructurePath = NewPathStore(nil, ".mcstructure") TradeTablePath = NewPathStore(vanilla.TradeTable) SoundPath = NewPathStore(vanilla.SoundPath, ".fsb", ".ogg", ".wav") diff --git a/stores/symbol.go b/stores/symbol.go index d7ff301..e25e2b7 100644 --- a/stores/symbol.go +++ b/stores/symbol.go @@ -104,8 +104,12 @@ var ( ItemCustomComponent = NewSymbolBinding(nil) ItemId = NewSymbolBinding(vanilla.ItemId) // Blocks are contained within the "block" scope ItemTag = NewSymbolBinding(vanilla.ItemTag) + ProvidedFogId = NewSymbolBinding(nil) RecipeId = NewSymbolBinding(vanilla.RecipeId) RecipeTag = NewSymbolBinding(vanilla.RecipeTag) + ScoreboardObjective = NewSymbolBinding(nil) + Tag = NewSymbolBinding(nil) + TickingArea = NewSymbolBinding(nil) WorldgenProcessor = NewSymbolBinding(vanilla.WorldgenProcessorId) WorldgenTemplatePool = NewSymbolBinding(vanilla.WorldgenTemplatePoolId) WorldgenJigsaw = NewSymbolBinding(nil) From e0857e749fe8412f98151966107f9b04690be1b4 Mon Sep 17 00:00:00 2001 From: Beltsazar Date: Mon, 19 Jan 2026 22:55:49 +0700 Subject: [PATCH 05/13] Rename package to builtin --- handlers/mcfunction.go | 4 ++-- internal/mcfunction/{vanilla => builtin}/aimassist.go | 2 +- internal/mcfunction/{vanilla => builtin}/camera.go | 2 +- internal/mcfunction/{vanilla => builtin}/camerashake.go | 2 +- internal/mcfunction/{vanilla => builtin}/clear.go | 2 +- internal/mcfunction/{vanilla => builtin}/clearspawnpoint.go | 2 +- internal/mcfunction/{vanilla => builtin}/clone.go | 2 +- internal/mcfunction/{vanilla => builtin}/commands.go | 2 +- internal/mcfunction/{vanilla => builtin}/controlscheme.go | 2 +- internal/mcfunction/{vanilla => builtin}/damage.go | 2 +- internal/mcfunction/{vanilla => builtin}/daylock.go | 2 +- internal/mcfunction/{vanilla => builtin}/dialogue.go | 2 +- internal/mcfunction/{vanilla => builtin}/difficulty.go | 2 +- internal/mcfunction/{vanilla => builtin}/effect.go | 2 +- internal/mcfunction/{vanilla => builtin}/enchant.go | 2 +- internal/mcfunction/{vanilla => builtin}/event.go | 2 +- internal/mcfunction/{vanilla => builtin}/execute.go | 2 +- internal/mcfunction/{vanilla => builtin}/fill.go | 2 +- internal/mcfunction/{vanilla => builtin}/fog.go | 2 +- internal/mcfunction/{vanilla => builtin}/function.go | 2 +- internal/mcfunction/{vanilla => builtin}/gamemode.go | 2 +- internal/mcfunction/{vanilla => builtin}/gamerule.go | 2 +- internal/mcfunction/{vanilla => builtin}/gametest.go | 2 +- internal/mcfunction/{vanilla => builtin}/give.go | 2 +- internal/mcfunction/{vanilla => builtin}/hud.go | 2 +- internal/mcfunction/{vanilla => builtin}/inputpermission.go | 2 +- internal/mcfunction/{vanilla => builtin}/kill.go | 2 +- internal/mcfunction/{vanilla => builtin}/locate.go | 2 +- internal/mcfunction/{vanilla => builtin}/loot.go | 2 +- internal/mcfunction/{vanilla => builtin}/me.go | 2 +- internal/mcfunction/{vanilla => builtin}/mobevent.go | 2 +- internal/mcfunction/{vanilla => builtin}/music.go | 2 +- internal/mcfunction/{vanilla => builtin}/op.go | 2 +- internal/mcfunction/{vanilla => builtin}/particle.go | 2 +- internal/mcfunction/{vanilla => builtin}/place.go | 2 +- internal/mcfunction/{vanilla => builtin}/playanimation.go | 2 +- internal/mcfunction/{vanilla => builtin}/playsound.go | 2 +- internal/mcfunction/{vanilla => builtin}/recipe.go | 2 +- internal/mcfunction/{vanilla => builtin}/reload.go | 2 +- internal/mcfunction/{vanilla => builtin}/replaceitem.go | 2 +- internal/mcfunction/{vanilla => builtin}/ride.go | 2 +- internal/mcfunction/{vanilla => builtin}/say.go | 2 +- internal/mcfunction/{vanilla => builtin}/schedule.go | 2 +- internal/mcfunction/{vanilla => builtin}/scoreboard.go | 2 +- internal/mcfunction/{vanilla => builtin}/script.go | 2 +- internal/mcfunction/{vanilla => builtin}/scriptevent.go | 2 +- internal/mcfunction/{vanilla => builtin}/setblock.go | 2 +- internal/mcfunction/{vanilla => builtin}/setmaxplayers.go | 2 +- internal/mcfunction/{vanilla => builtin}/setworldspawn.go | 2 +- internal/mcfunction/{vanilla => builtin}/spawnpoint.go | 2 +- internal/mcfunction/{vanilla => builtin}/spreadplayers.go | 2 +- internal/mcfunction/{vanilla => builtin}/stopsound.go | 2 +- internal/mcfunction/{vanilla => builtin}/structure.go | 2 +- internal/mcfunction/{vanilla => builtin}/summon.go | 2 +- internal/mcfunction/{vanilla => builtin}/tag.go | 2 +- internal/mcfunction/{vanilla => builtin}/teleport.go | 2 +- internal/mcfunction/{vanilla => builtin}/tell.go | 2 +- internal/mcfunction/{vanilla => builtin}/tellraw.go | 2 +- internal/mcfunction/{vanilla => builtin}/testfor.go | 2 +- internal/mcfunction/{vanilla => builtin}/testforblock.go | 2 +- internal/mcfunction/{vanilla => builtin}/testforblocks.go | 2 +- internal/mcfunction/{vanilla => builtin}/tickingarea.go | 2 +- internal/mcfunction/{vanilla => builtin}/time.go | 2 +- internal/mcfunction/{vanilla => builtin}/title.go | 2 +- internal/mcfunction/{vanilla => builtin}/titleraw.go | 2 +- internal/mcfunction/{vanilla => builtin}/toggledownfall.go | 2 +- internal/mcfunction/{vanilla => builtin}/weather.go | 2 +- internal/mcfunction/{vanilla => builtin}/xp.go | 2 +- 68 files changed, 69 insertions(+), 69 deletions(-) rename internal/mcfunction/{vanilla => builtin}/aimassist.go (98%) rename internal/mcfunction/{vanilla => builtin}/camera.go (99%) rename internal/mcfunction/{vanilla => builtin}/camerashake.go (98%) rename internal/mcfunction/{vanilla => builtin}/clear.go (97%) rename internal/mcfunction/{vanilla => builtin}/clearspawnpoint.go (96%) rename internal/mcfunction/{vanilla => builtin}/clone.go (99%) rename internal/mcfunction/{vanilla => builtin}/commands.go (98%) rename internal/mcfunction/{vanilla => builtin}/controlscheme.go (98%) rename internal/mcfunction/{vanilla => builtin}/damage.go (99%) rename internal/mcfunction/{vanilla => builtin}/daylock.go (96%) rename internal/mcfunction/{vanilla => builtin}/dialogue.go (98%) rename internal/mcfunction/{vanilla => builtin}/difficulty.go (97%) rename internal/mcfunction/{vanilla => builtin}/effect.go (99%) rename internal/mcfunction/{vanilla => builtin}/enchant.go (98%) rename internal/mcfunction/{vanilla => builtin}/event.go (97%) rename internal/mcfunction/{vanilla => builtin}/execute.go (99%) rename internal/mcfunction/{vanilla => builtin}/fill.go (99%) rename internal/mcfunction/{vanilla => builtin}/fog.go (98%) rename internal/mcfunction/{vanilla => builtin}/function.go (96%) rename internal/mcfunction/{vanilla => builtin}/gamemode.go (98%) rename internal/mcfunction/{vanilla => builtin}/gamerule.go (99%) rename internal/mcfunction/{vanilla => builtin}/gametest.go (99%) rename internal/mcfunction/{vanilla => builtin}/give.go (98%) rename internal/mcfunction/{vanilla => builtin}/hud.go (98%) rename internal/mcfunction/{vanilla => builtin}/inputpermission.go (98%) rename internal/mcfunction/{vanilla => builtin}/kill.go (95%) rename internal/mcfunction/{vanilla => builtin}/locate.go (98%) rename internal/mcfunction/{vanilla => builtin}/loot.go (99%) rename internal/mcfunction/{vanilla => builtin}/me.go (95%) rename internal/mcfunction/{vanilla => builtin}/mobevent.go (97%) rename internal/mcfunction/{vanilla => builtin}/music.go (99%) rename internal/mcfunction/{vanilla => builtin}/op.go (95%) rename internal/mcfunction/{vanilla => builtin}/particle.go (96%) rename internal/mcfunction/{vanilla => builtin}/place.go (99%) rename internal/mcfunction/{vanilla => builtin}/playanimation.go (98%) rename internal/mcfunction/{vanilla => builtin}/playsound.go (98%) rename internal/mcfunction/{vanilla => builtin}/recipe.go (98%) rename internal/mcfunction/{vanilla => builtin}/reload.go (96%) rename internal/mcfunction/{vanilla => builtin}/replaceitem.go (99%) rename internal/mcfunction/{vanilla => builtin}/ride.go (99%) rename internal/mcfunction/{vanilla => builtin}/say.go (95%) rename internal/mcfunction/{vanilla => builtin}/schedule.go (99%) rename internal/mcfunction/{vanilla => builtin}/scoreboard.go (99%) rename internal/mcfunction/{vanilla => builtin}/script.go (99%) rename internal/mcfunction/{vanilla => builtin}/scriptevent.go (96%) rename internal/mcfunction/{vanilla => builtin}/setblock.go (98%) rename internal/mcfunction/{vanilla => builtin}/setmaxplayers.go (96%) rename internal/mcfunction/{vanilla => builtin}/setworldspawn.go (96%) rename internal/mcfunction/{vanilla => builtin}/spawnpoint.go (96%) rename internal/mcfunction/{vanilla => builtin}/spreadplayers.go (98%) rename internal/mcfunction/{vanilla => builtin}/stopsound.go (96%) rename internal/mcfunction/{vanilla => builtin}/structure.go (99%) rename internal/mcfunction/{vanilla => builtin}/summon.go (99%) rename internal/mcfunction/{vanilla => builtin}/tag.go (98%) rename internal/mcfunction/{vanilla => builtin}/teleport.go (99%) rename internal/mcfunction/{vanilla => builtin}/tell.go (96%) rename internal/mcfunction/{vanilla => builtin}/tellraw.go (96%) rename internal/mcfunction/{vanilla => builtin}/testfor.go (96%) rename internal/mcfunction/{vanilla => builtin}/testforblock.go (97%) rename internal/mcfunction/{vanilla => builtin}/testforblocks.go (97%) rename internal/mcfunction/{vanilla => builtin}/tickingarea.go (99%) rename internal/mcfunction/{vanilla => builtin}/time.go (98%) rename internal/mcfunction/{vanilla => builtin}/title.go (99%) rename internal/mcfunction/{vanilla => builtin}/titleraw.go (99%) rename internal/mcfunction/{vanilla => builtin}/toggledownfall.go (94%) rename internal/mcfunction/{vanilla => builtin}/weather.go (97%) rename internal/mcfunction/{vanilla => builtin}/xp.go (97%) diff --git a/handlers/mcfunction.go b/handlers/mcfunction.go index 5a59f42..dd34e64 100644 --- a/handlers/mcfunction.go +++ b/handlers/mcfunction.go @@ -2,13 +2,13 @@ package handlers import ( "github.com/rockide/language-server/internal/mcfunction" - "github.com/rockide/language-server/internal/mcfunction/vanilla" + "github.com/rockide/language-server/internal/mcfunction/builtin" "github.com/rockide/language-server/shared" ) func newCommandParser(options mcfunction.ParserOptions) *mcfunction.Parser { parser := mcfunction.NewParser(options) - parser.RegisterCommands(vanilla.Commands...) + parser.RegisterCommands(builtin.Commands...) return parser } diff --git a/internal/mcfunction/vanilla/aimassist.go b/internal/mcfunction/builtin/aimassist.go similarity index 98% rename from internal/mcfunction/vanilla/aimassist.go rename to internal/mcfunction/builtin/aimassist.go index 9e9384c..b97b880 100644 --- a/internal/mcfunction/vanilla/aimassist.go +++ b/internal/mcfunction/builtin/aimassist.go @@ -1,4 +1,4 @@ -package vanilla +package builtin import "github.com/rockide/language-server/internal/mcfunction" diff --git a/internal/mcfunction/vanilla/camera.go b/internal/mcfunction/builtin/camera.go similarity index 99% rename from internal/mcfunction/vanilla/camera.go rename to internal/mcfunction/builtin/camera.go index b11db18..8c18702 100644 --- a/internal/mcfunction/vanilla/camera.go +++ b/internal/mcfunction/builtin/camera.go @@ -1,4 +1,4 @@ -package vanilla +package builtin import "github.com/rockide/language-server/internal/mcfunction" diff --git a/internal/mcfunction/vanilla/camerashake.go b/internal/mcfunction/builtin/camerashake.go similarity index 98% rename from internal/mcfunction/vanilla/camerashake.go rename to internal/mcfunction/builtin/camerashake.go index 01751bc..5fd40ac 100644 --- a/internal/mcfunction/vanilla/camerashake.go +++ b/internal/mcfunction/builtin/camerashake.go @@ -1,4 +1,4 @@ -package vanilla +package builtin import ( "math" diff --git a/internal/mcfunction/vanilla/clear.go b/internal/mcfunction/builtin/clear.go similarity index 97% rename from internal/mcfunction/vanilla/clear.go rename to internal/mcfunction/builtin/clear.go index 1ccf0d7..000bed7 100644 --- a/internal/mcfunction/vanilla/clear.go +++ b/internal/mcfunction/builtin/clear.go @@ -1,4 +1,4 @@ -package vanilla +package builtin import "github.com/rockide/language-server/internal/mcfunction" diff --git a/internal/mcfunction/vanilla/clearspawnpoint.go b/internal/mcfunction/builtin/clearspawnpoint.go similarity index 96% rename from internal/mcfunction/vanilla/clearspawnpoint.go rename to internal/mcfunction/builtin/clearspawnpoint.go index 44de50b..623bf70 100644 --- a/internal/mcfunction/vanilla/clearspawnpoint.go +++ b/internal/mcfunction/builtin/clearspawnpoint.go @@ -1,4 +1,4 @@ -package vanilla +package builtin import "github.com/rockide/language-server/internal/mcfunction" diff --git a/internal/mcfunction/vanilla/clone.go b/internal/mcfunction/builtin/clone.go similarity index 99% rename from internal/mcfunction/vanilla/clone.go rename to internal/mcfunction/builtin/clone.go index e7f1440..feb85d8 100644 --- a/internal/mcfunction/vanilla/clone.go +++ b/internal/mcfunction/builtin/clone.go @@ -1,4 +1,4 @@ -package vanilla +package builtin import "github.com/rockide/language-server/internal/mcfunction" diff --git a/internal/mcfunction/vanilla/commands.go b/internal/mcfunction/builtin/commands.go similarity index 98% rename from internal/mcfunction/vanilla/commands.go rename to internal/mcfunction/builtin/commands.go index 16d24a5..7a49616 100644 --- a/internal/mcfunction/vanilla/commands.go +++ b/internal/mcfunction/builtin/commands.go @@ -1,4 +1,4 @@ -package vanilla +package builtin import "github.com/rockide/language-server/internal/mcfunction" diff --git a/internal/mcfunction/vanilla/controlscheme.go b/internal/mcfunction/builtin/controlscheme.go similarity index 98% rename from internal/mcfunction/vanilla/controlscheme.go rename to internal/mcfunction/builtin/controlscheme.go index 9c88c1b..2cd23bf 100644 --- a/internal/mcfunction/vanilla/controlscheme.go +++ b/internal/mcfunction/builtin/controlscheme.go @@ -1,4 +1,4 @@ -package vanilla +package builtin import "github.com/rockide/language-server/internal/mcfunction" diff --git a/internal/mcfunction/vanilla/damage.go b/internal/mcfunction/builtin/damage.go similarity index 99% rename from internal/mcfunction/vanilla/damage.go rename to internal/mcfunction/builtin/damage.go index 2a2c9db..aeeecbc 100644 --- a/internal/mcfunction/vanilla/damage.go +++ b/internal/mcfunction/builtin/damage.go @@ -1,4 +1,4 @@ -package vanilla +package builtin import "github.com/rockide/language-server/internal/mcfunction" diff --git a/internal/mcfunction/vanilla/daylock.go b/internal/mcfunction/builtin/daylock.go similarity index 96% rename from internal/mcfunction/vanilla/daylock.go rename to internal/mcfunction/builtin/daylock.go index 5ad4ca9..82b7b49 100644 --- a/internal/mcfunction/vanilla/daylock.go +++ b/internal/mcfunction/builtin/daylock.go @@ -1,4 +1,4 @@ -package vanilla +package builtin import "github.com/rockide/language-server/internal/mcfunction" diff --git a/internal/mcfunction/vanilla/dialogue.go b/internal/mcfunction/builtin/dialogue.go similarity index 98% rename from internal/mcfunction/vanilla/dialogue.go rename to internal/mcfunction/builtin/dialogue.go index 6151ac0..eab8a5a 100644 --- a/internal/mcfunction/vanilla/dialogue.go +++ b/internal/mcfunction/builtin/dialogue.go @@ -1,4 +1,4 @@ -package vanilla +package builtin import "github.com/rockide/language-server/internal/mcfunction" diff --git a/internal/mcfunction/vanilla/difficulty.go b/internal/mcfunction/builtin/difficulty.go similarity index 97% rename from internal/mcfunction/vanilla/difficulty.go rename to internal/mcfunction/builtin/difficulty.go index 700a074..8ca6626 100644 --- a/internal/mcfunction/vanilla/difficulty.go +++ b/internal/mcfunction/builtin/difficulty.go @@ -1,4 +1,4 @@ -package vanilla +package builtin import "github.com/rockide/language-server/internal/mcfunction" diff --git a/internal/mcfunction/vanilla/effect.go b/internal/mcfunction/builtin/effect.go similarity index 99% rename from internal/mcfunction/vanilla/effect.go rename to internal/mcfunction/builtin/effect.go index cdd198c..97cd280 100644 --- a/internal/mcfunction/vanilla/effect.go +++ b/internal/mcfunction/builtin/effect.go @@ -1,4 +1,4 @@ -package vanilla +package builtin import ( "math" diff --git a/internal/mcfunction/vanilla/enchant.go b/internal/mcfunction/builtin/enchant.go similarity index 98% rename from internal/mcfunction/vanilla/enchant.go rename to internal/mcfunction/builtin/enchant.go index 48008f5..16a8bfc 100644 --- a/internal/mcfunction/vanilla/enchant.go +++ b/internal/mcfunction/builtin/enchant.go @@ -1,4 +1,4 @@ -package vanilla +package builtin import "github.com/rockide/language-server/internal/mcfunction" diff --git a/internal/mcfunction/vanilla/event.go b/internal/mcfunction/builtin/event.go similarity index 97% rename from internal/mcfunction/vanilla/event.go rename to internal/mcfunction/builtin/event.go index b6cc993..8490e85 100644 --- a/internal/mcfunction/vanilla/event.go +++ b/internal/mcfunction/builtin/event.go @@ -1,4 +1,4 @@ -package vanilla +package builtin import "github.com/rockide/language-server/internal/mcfunction" diff --git a/internal/mcfunction/vanilla/execute.go b/internal/mcfunction/builtin/execute.go similarity index 99% rename from internal/mcfunction/vanilla/execute.go rename to internal/mcfunction/builtin/execute.go index d68e55f..85104f1 100644 --- a/internal/mcfunction/vanilla/execute.go +++ b/internal/mcfunction/builtin/execute.go @@ -1,4 +1,4 @@ -package vanilla +package builtin import "github.com/rockide/language-server/internal/mcfunction" diff --git a/internal/mcfunction/vanilla/fill.go b/internal/mcfunction/builtin/fill.go similarity index 99% rename from internal/mcfunction/vanilla/fill.go rename to internal/mcfunction/builtin/fill.go index 1ad8c8d..77de894 100644 --- a/internal/mcfunction/vanilla/fill.go +++ b/internal/mcfunction/builtin/fill.go @@ -1,4 +1,4 @@ -package vanilla +package builtin import "github.com/rockide/language-server/internal/mcfunction" diff --git a/internal/mcfunction/vanilla/fog.go b/internal/mcfunction/builtin/fog.go similarity index 98% rename from internal/mcfunction/vanilla/fog.go rename to internal/mcfunction/builtin/fog.go index 4d3d3da..cc15e3b 100644 --- a/internal/mcfunction/vanilla/fog.go +++ b/internal/mcfunction/builtin/fog.go @@ -1,4 +1,4 @@ -package vanilla +package builtin import "github.com/rockide/language-server/internal/mcfunction" diff --git a/internal/mcfunction/vanilla/function.go b/internal/mcfunction/builtin/function.go similarity index 96% rename from internal/mcfunction/vanilla/function.go rename to internal/mcfunction/builtin/function.go index ad4b779..337fd39 100644 --- a/internal/mcfunction/vanilla/function.go +++ b/internal/mcfunction/builtin/function.go @@ -1,4 +1,4 @@ -package vanilla +package builtin import "github.com/rockide/language-server/internal/mcfunction" diff --git a/internal/mcfunction/vanilla/gamemode.go b/internal/mcfunction/builtin/gamemode.go similarity index 98% rename from internal/mcfunction/vanilla/gamemode.go rename to internal/mcfunction/builtin/gamemode.go index e96f203..4aad840 100644 --- a/internal/mcfunction/vanilla/gamemode.go +++ b/internal/mcfunction/builtin/gamemode.go @@ -1,4 +1,4 @@ -package vanilla +package builtin import "github.com/rockide/language-server/internal/mcfunction" diff --git a/internal/mcfunction/vanilla/gamerule.go b/internal/mcfunction/builtin/gamerule.go similarity index 99% rename from internal/mcfunction/vanilla/gamerule.go rename to internal/mcfunction/builtin/gamerule.go index e51ff7a..e375000 100644 --- a/internal/mcfunction/vanilla/gamerule.go +++ b/internal/mcfunction/builtin/gamerule.go @@ -1,4 +1,4 @@ -package vanilla +package builtin import "github.com/rockide/language-server/internal/mcfunction" diff --git a/internal/mcfunction/vanilla/gametest.go b/internal/mcfunction/builtin/gametest.go similarity index 99% rename from internal/mcfunction/vanilla/gametest.go rename to internal/mcfunction/builtin/gametest.go index f9bad5a..f6729be 100644 --- a/internal/mcfunction/vanilla/gametest.go +++ b/internal/mcfunction/builtin/gametest.go @@ -1,4 +1,4 @@ -package vanilla +package builtin import "github.com/rockide/language-server/internal/mcfunction" diff --git a/internal/mcfunction/vanilla/give.go b/internal/mcfunction/builtin/give.go similarity index 98% rename from internal/mcfunction/vanilla/give.go rename to internal/mcfunction/builtin/give.go index 40c12f8..5a0d6e9 100644 --- a/internal/mcfunction/vanilla/give.go +++ b/internal/mcfunction/builtin/give.go @@ -1,4 +1,4 @@ -package vanilla +package builtin import "github.com/rockide/language-server/internal/mcfunction" diff --git a/internal/mcfunction/vanilla/hud.go b/internal/mcfunction/builtin/hud.go similarity index 98% rename from internal/mcfunction/vanilla/hud.go rename to internal/mcfunction/builtin/hud.go index 427530d..dafda1d 100644 --- a/internal/mcfunction/vanilla/hud.go +++ b/internal/mcfunction/builtin/hud.go @@ -1,4 +1,4 @@ -package vanilla +package builtin import "github.com/rockide/language-server/internal/mcfunction" diff --git a/internal/mcfunction/vanilla/inputpermission.go b/internal/mcfunction/builtin/inputpermission.go similarity index 98% rename from internal/mcfunction/vanilla/inputpermission.go rename to internal/mcfunction/builtin/inputpermission.go index 26e3ee5..8ae87cf 100644 --- a/internal/mcfunction/vanilla/inputpermission.go +++ b/internal/mcfunction/builtin/inputpermission.go @@ -1,4 +1,4 @@ -package vanilla +package builtin import "github.com/rockide/language-server/internal/mcfunction" diff --git a/internal/mcfunction/vanilla/kill.go b/internal/mcfunction/builtin/kill.go similarity index 95% rename from internal/mcfunction/vanilla/kill.go rename to internal/mcfunction/builtin/kill.go index b952d77..b99eb95 100644 --- a/internal/mcfunction/vanilla/kill.go +++ b/internal/mcfunction/builtin/kill.go @@ -1,4 +1,4 @@ -package vanilla +package builtin import "github.com/rockide/language-server/internal/mcfunction" diff --git a/internal/mcfunction/vanilla/locate.go b/internal/mcfunction/builtin/locate.go similarity index 98% rename from internal/mcfunction/vanilla/locate.go rename to internal/mcfunction/builtin/locate.go index 80d8b16..80b304c 100644 --- a/internal/mcfunction/vanilla/locate.go +++ b/internal/mcfunction/builtin/locate.go @@ -1,4 +1,4 @@ -package vanilla +package builtin import "github.com/rockide/language-server/internal/mcfunction" diff --git a/internal/mcfunction/vanilla/loot.go b/internal/mcfunction/builtin/loot.go similarity index 99% rename from internal/mcfunction/vanilla/loot.go rename to internal/mcfunction/builtin/loot.go index 4e948ce..469e05f 100644 --- a/internal/mcfunction/vanilla/loot.go +++ b/internal/mcfunction/builtin/loot.go @@ -1,4 +1,4 @@ -package vanilla +package builtin import "github.com/rockide/language-server/internal/mcfunction" diff --git a/internal/mcfunction/vanilla/me.go b/internal/mcfunction/builtin/me.go similarity index 95% rename from internal/mcfunction/vanilla/me.go rename to internal/mcfunction/builtin/me.go index 03deb37..676c9ad 100644 --- a/internal/mcfunction/vanilla/me.go +++ b/internal/mcfunction/builtin/me.go @@ -1,4 +1,4 @@ -package vanilla +package builtin import "github.com/rockide/language-server/internal/mcfunction" diff --git a/internal/mcfunction/vanilla/mobevent.go b/internal/mcfunction/builtin/mobevent.go similarity index 97% rename from internal/mcfunction/vanilla/mobevent.go rename to internal/mcfunction/builtin/mobevent.go index 7ed4669..8a9c22f 100644 --- a/internal/mcfunction/vanilla/mobevent.go +++ b/internal/mcfunction/builtin/mobevent.go @@ -1,4 +1,4 @@ -package vanilla +package builtin import "github.com/rockide/language-server/internal/mcfunction" diff --git a/internal/mcfunction/vanilla/music.go b/internal/mcfunction/builtin/music.go similarity index 99% rename from internal/mcfunction/vanilla/music.go rename to internal/mcfunction/builtin/music.go index 5134483..6f47240 100644 --- a/internal/mcfunction/vanilla/music.go +++ b/internal/mcfunction/builtin/music.go @@ -1,4 +1,4 @@ -package vanilla +package builtin import "github.com/rockide/language-server/internal/mcfunction" diff --git a/internal/mcfunction/vanilla/op.go b/internal/mcfunction/builtin/op.go similarity index 95% rename from internal/mcfunction/vanilla/op.go rename to internal/mcfunction/builtin/op.go index 1830dde..8df3976 100644 --- a/internal/mcfunction/vanilla/op.go +++ b/internal/mcfunction/builtin/op.go @@ -1,4 +1,4 @@ -package vanilla +package builtin import "github.com/rockide/language-server/internal/mcfunction" diff --git a/internal/mcfunction/vanilla/particle.go b/internal/mcfunction/builtin/particle.go similarity index 96% rename from internal/mcfunction/vanilla/particle.go rename to internal/mcfunction/builtin/particle.go index 90883f0..db88fd2 100644 --- a/internal/mcfunction/vanilla/particle.go +++ b/internal/mcfunction/builtin/particle.go @@ -1,4 +1,4 @@ -package vanilla +package builtin import "github.com/rockide/language-server/internal/mcfunction" diff --git a/internal/mcfunction/vanilla/place.go b/internal/mcfunction/builtin/place.go similarity index 99% rename from internal/mcfunction/vanilla/place.go rename to internal/mcfunction/builtin/place.go index 1c04ea8..0290c13 100644 --- a/internal/mcfunction/vanilla/place.go +++ b/internal/mcfunction/builtin/place.go @@ -1,4 +1,4 @@ -package vanilla +package builtin import "github.com/rockide/language-server/internal/mcfunction" diff --git a/internal/mcfunction/vanilla/playanimation.go b/internal/mcfunction/builtin/playanimation.go similarity index 98% rename from internal/mcfunction/vanilla/playanimation.go rename to internal/mcfunction/builtin/playanimation.go index 3438445..6f1df27 100644 --- a/internal/mcfunction/vanilla/playanimation.go +++ b/internal/mcfunction/builtin/playanimation.go @@ -1,4 +1,4 @@ -package vanilla +package builtin import "github.com/rockide/language-server/internal/mcfunction" diff --git a/internal/mcfunction/vanilla/playsound.go b/internal/mcfunction/builtin/playsound.go similarity index 98% rename from internal/mcfunction/vanilla/playsound.go rename to internal/mcfunction/builtin/playsound.go index 9372b42..bdfa319 100644 --- a/internal/mcfunction/vanilla/playsound.go +++ b/internal/mcfunction/builtin/playsound.go @@ -1,4 +1,4 @@ -package vanilla +package builtin import "github.com/rockide/language-server/internal/mcfunction" diff --git a/internal/mcfunction/vanilla/recipe.go b/internal/mcfunction/builtin/recipe.go similarity index 98% rename from internal/mcfunction/vanilla/recipe.go rename to internal/mcfunction/builtin/recipe.go index 1028ac7..1537575 100644 --- a/internal/mcfunction/vanilla/recipe.go +++ b/internal/mcfunction/builtin/recipe.go @@ -1,4 +1,4 @@ -package vanilla +package builtin import "github.com/rockide/language-server/internal/mcfunction" diff --git a/internal/mcfunction/vanilla/reload.go b/internal/mcfunction/builtin/reload.go similarity index 96% rename from internal/mcfunction/vanilla/reload.go rename to internal/mcfunction/builtin/reload.go index 841ad1e..9b88515 100644 --- a/internal/mcfunction/vanilla/reload.go +++ b/internal/mcfunction/builtin/reload.go @@ -1,4 +1,4 @@ -package vanilla +package builtin import "github.com/rockide/language-server/internal/mcfunction" diff --git a/internal/mcfunction/vanilla/replaceitem.go b/internal/mcfunction/builtin/replaceitem.go similarity index 99% rename from internal/mcfunction/vanilla/replaceitem.go rename to internal/mcfunction/builtin/replaceitem.go index 20ea76f..7f48010 100644 --- a/internal/mcfunction/vanilla/replaceitem.go +++ b/internal/mcfunction/builtin/replaceitem.go @@ -1,4 +1,4 @@ -package vanilla +package builtin import "github.com/rockide/language-server/internal/mcfunction" diff --git a/internal/mcfunction/vanilla/ride.go b/internal/mcfunction/builtin/ride.go similarity index 99% rename from internal/mcfunction/vanilla/ride.go rename to internal/mcfunction/builtin/ride.go index 3893228..46fced8 100644 --- a/internal/mcfunction/vanilla/ride.go +++ b/internal/mcfunction/builtin/ride.go @@ -1,4 +1,4 @@ -package vanilla +package builtin import "github.com/rockide/language-server/internal/mcfunction" diff --git a/internal/mcfunction/vanilla/say.go b/internal/mcfunction/builtin/say.go similarity index 95% rename from internal/mcfunction/vanilla/say.go rename to internal/mcfunction/builtin/say.go index 43db5c4..e16f431 100644 --- a/internal/mcfunction/vanilla/say.go +++ b/internal/mcfunction/builtin/say.go @@ -1,4 +1,4 @@ -package vanilla +package builtin import "github.com/rockide/language-server/internal/mcfunction" diff --git a/internal/mcfunction/vanilla/schedule.go b/internal/mcfunction/builtin/schedule.go similarity index 99% rename from internal/mcfunction/vanilla/schedule.go rename to internal/mcfunction/builtin/schedule.go index 4ca61bf..a96fc78 100644 --- a/internal/mcfunction/vanilla/schedule.go +++ b/internal/mcfunction/builtin/schedule.go @@ -1,4 +1,4 @@ -package vanilla +package builtin import "github.com/rockide/language-server/internal/mcfunction" diff --git a/internal/mcfunction/vanilla/scoreboard.go b/internal/mcfunction/builtin/scoreboard.go similarity index 99% rename from internal/mcfunction/vanilla/scoreboard.go rename to internal/mcfunction/builtin/scoreboard.go index db5dd77..ad6adda 100644 --- a/internal/mcfunction/vanilla/scoreboard.go +++ b/internal/mcfunction/builtin/scoreboard.go @@ -1,4 +1,4 @@ -package vanilla +package builtin import "github.com/rockide/language-server/internal/mcfunction" diff --git a/internal/mcfunction/vanilla/script.go b/internal/mcfunction/builtin/script.go similarity index 99% rename from internal/mcfunction/vanilla/script.go rename to internal/mcfunction/builtin/script.go index 9b86996..d318564 100644 --- a/internal/mcfunction/vanilla/script.go +++ b/internal/mcfunction/builtin/script.go @@ -1,4 +1,4 @@ -package vanilla +package builtin import "github.com/rockide/language-server/internal/mcfunction" diff --git a/internal/mcfunction/vanilla/scriptevent.go b/internal/mcfunction/builtin/scriptevent.go similarity index 96% rename from internal/mcfunction/vanilla/scriptevent.go rename to internal/mcfunction/builtin/scriptevent.go index 2b11e43..87ab0ab 100644 --- a/internal/mcfunction/vanilla/scriptevent.go +++ b/internal/mcfunction/builtin/scriptevent.go @@ -1,4 +1,4 @@ -package vanilla +package builtin import "github.com/rockide/language-server/internal/mcfunction" diff --git a/internal/mcfunction/vanilla/setblock.go b/internal/mcfunction/builtin/setblock.go similarity index 98% rename from internal/mcfunction/vanilla/setblock.go rename to internal/mcfunction/builtin/setblock.go index 33446c1..9e16efb 100644 --- a/internal/mcfunction/vanilla/setblock.go +++ b/internal/mcfunction/builtin/setblock.go @@ -1,4 +1,4 @@ -package vanilla +package builtin import "github.com/rockide/language-server/internal/mcfunction" diff --git a/internal/mcfunction/vanilla/setmaxplayers.go b/internal/mcfunction/builtin/setmaxplayers.go similarity index 96% rename from internal/mcfunction/vanilla/setmaxplayers.go rename to internal/mcfunction/builtin/setmaxplayers.go index 35c09aa..183a852 100644 --- a/internal/mcfunction/vanilla/setmaxplayers.go +++ b/internal/mcfunction/builtin/setmaxplayers.go @@ -1,4 +1,4 @@ -package vanilla +package builtin import "github.com/rockide/language-server/internal/mcfunction" diff --git a/internal/mcfunction/vanilla/setworldspawn.go b/internal/mcfunction/builtin/setworldspawn.go similarity index 96% rename from internal/mcfunction/vanilla/setworldspawn.go rename to internal/mcfunction/builtin/setworldspawn.go index bdbb8d5..b3b6ff4 100644 --- a/internal/mcfunction/vanilla/setworldspawn.go +++ b/internal/mcfunction/builtin/setworldspawn.go @@ -1,4 +1,4 @@ -package vanilla +package builtin import "github.com/rockide/language-server/internal/mcfunction" diff --git a/internal/mcfunction/vanilla/spawnpoint.go b/internal/mcfunction/builtin/spawnpoint.go similarity index 96% rename from internal/mcfunction/vanilla/spawnpoint.go rename to internal/mcfunction/builtin/spawnpoint.go index e96568b..9949f9e 100644 --- a/internal/mcfunction/vanilla/spawnpoint.go +++ b/internal/mcfunction/builtin/spawnpoint.go @@ -1,4 +1,4 @@ -package vanilla +package builtin import "github.com/rockide/language-server/internal/mcfunction" diff --git a/internal/mcfunction/vanilla/spreadplayers.go b/internal/mcfunction/builtin/spreadplayers.go similarity index 98% rename from internal/mcfunction/vanilla/spreadplayers.go rename to internal/mcfunction/builtin/spreadplayers.go index 0569fdb..be8906e 100644 --- a/internal/mcfunction/vanilla/spreadplayers.go +++ b/internal/mcfunction/builtin/spreadplayers.go @@ -1,4 +1,4 @@ -package vanilla +package builtin import ( "math" diff --git a/internal/mcfunction/vanilla/stopsound.go b/internal/mcfunction/builtin/stopsound.go similarity index 96% rename from internal/mcfunction/vanilla/stopsound.go rename to internal/mcfunction/builtin/stopsound.go index 77f5baf..16f240f 100644 --- a/internal/mcfunction/vanilla/stopsound.go +++ b/internal/mcfunction/builtin/stopsound.go @@ -1,4 +1,4 @@ -package vanilla +package builtin import "github.com/rockide/language-server/internal/mcfunction" diff --git a/internal/mcfunction/vanilla/structure.go b/internal/mcfunction/builtin/structure.go similarity index 99% rename from internal/mcfunction/vanilla/structure.go rename to internal/mcfunction/builtin/structure.go index 25db6a8..1c95a25 100644 --- a/internal/mcfunction/vanilla/structure.go +++ b/internal/mcfunction/builtin/structure.go @@ -1,4 +1,4 @@ -package vanilla +package builtin import ( "math" diff --git a/internal/mcfunction/vanilla/summon.go b/internal/mcfunction/builtin/summon.go similarity index 99% rename from internal/mcfunction/vanilla/summon.go rename to internal/mcfunction/builtin/summon.go index b1876ac..e39a358 100644 --- a/internal/mcfunction/vanilla/summon.go +++ b/internal/mcfunction/builtin/summon.go @@ -1,4 +1,4 @@ -package vanilla +package builtin import "github.com/rockide/language-server/internal/mcfunction" diff --git a/internal/mcfunction/vanilla/tag.go b/internal/mcfunction/builtin/tag.go similarity index 98% rename from internal/mcfunction/vanilla/tag.go rename to internal/mcfunction/builtin/tag.go index 7475714..da453a3 100644 --- a/internal/mcfunction/vanilla/tag.go +++ b/internal/mcfunction/builtin/tag.go @@ -1,4 +1,4 @@ -package vanilla +package builtin import "github.com/rockide/language-server/internal/mcfunction" diff --git a/internal/mcfunction/vanilla/teleport.go b/internal/mcfunction/builtin/teleport.go similarity index 99% rename from internal/mcfunction/vanilla/teleport.go rename to internal/mcfunction/builtin/teleport.go index c8599b8..d896b2a 100644 --- a/internal/mcfunction/vanilla/teleport.go +++ b/internal/mcfunction/builtin/teleport.go @@ -1,4 +1,4 @@ -package vanilla +package builtin import "github.com/rockide/language-server/internal/mcfunction" diff --git a/internal/mcfunction/vanilla/tell.go b/internal/mcfunction/builtin/tell.go similarity index 96% rename from internal/mcfunction/vanilla/tell.go rename to internal/mcfunction/builtin/tell.go index 159e385..f92f97a 100644 --- a/internal/mcfunction/vanilla/tell.go +++ b/internal/mcfunction/builtin/tell.go @@ -1,4 +1,4 @@ -package vanilla +package builtin import "github.com/rockide/language-server/internal/mcfunction" diff --git a/internal/mcfunction/vanilla/tellraw.go b/internal/mcfunction/builtin/tellraw.go similarity index 96% rename from internal/mcfunction/vanilla/tellraw.go rename to internal/mcfunction/builtin/tellraw.go index a07c5fd..3d1d5fe 100644 --- a/internal/mcfunction/vanilla/tellraw.go +++ b/internal/mcfunction/builtin/tellraw.go @@ -1,4 +1,4 @@ -package vanilla +package builtin import "github.com/rockide/language-server/internal/mcfunction" diff --git a/internal/mcfunction/vanilla/testfor.go b/internal/mcfunction/builtin/testfor.go similarity index 96% rename from internal/mcfunction/vanilla/testfor.go rename to internal/mcfunction/builtin/testfor.go index 0a70f03..91849d2 100644 --- a/internal/mcfunction/vanilla/testfor.go +++ b/internal/mcfunction/builtin/testfor.go @@ -1,4 +1,4 @@ -package vanilla +package builtin import "github.com/rockide/language-server/internal/mcfunction" diff --git a/internal/mcfunction/vanilla/testforblock.go b/internal/mcfunction/builtin/testforblock.go similarity index 97% rename from internal/mcfunction/vanilla/testforblock.go rename to internal/mcfunction/builtin/testforblock.go index 9eceb1e..a37e7ee 100644 --- a/internal/mcfunction/vanilla/testforblock.go +++ b/internal/mcfunction/builtin/testforblock.go @@ -1,4 +1,4 @@ -package vanilla +package builtin import "github.com/rockide/language-server/internal/mcfunction" diff --git a/internal/mcfunction/vanilla/testforblocks.go b/internal/mcfunction/builtin/testforblocks.go similarity index 97% rename from internal/mcfunction/vanilla/testforblocks.go rename to internal/mcfunction/builtin/testforblocks.go index a83a5ee..380c5c9 100644 --- a/internal/mcfunction/vanilla/testforblocks.go +++ b/internal/mcfunction/builtin/testforblocks.go @@ -1,4 +1,4 @@ -package vanilla +package builtin import "github.com/rockide/language-server/internal/mcfunction" diff --git a/internal/mcfunction/vanilla/tickingarea.go b/internal/mcfunction/builtin/tickingarea.go similarity index 99% rename from internal/mcfunction/vanilla/tickingarea.go rename to internal/mcfunction/builtin/tickingarea.go index 70acad1..5956d23 100644 --- a/internal/mcfunction/vanilla/tickingarea.go +++ b/internal/mcfunction/builtin/tickingarea.go @@ -1,4 +1,4 @@ -package vanilla +package builtin import ( "math" diff --git a/internal/mcfunction/vanilla/time.go b/internal/mcfunction/builtin/time.go similarity index 98% rename from internal/mcfunction/vanilla/time.go rename to internal/mcfunction/builtin/time.go index 180ce52..ea4b9ae 100644 --- a/internal/mcfunction/vanilla/time.go +++ b/internal/mcfunction/builtin/time.go @@ -1,4 +1,4 @@ -package vanilla +package builtin import "github.com/rockide/language-server/internal/mcfunction" diff --git a/internal/mcfunction/vanilla/title.go b/internal/mcfunction/builtin/title.go similarity index 99% rename from internal/mcfunction/vanilla/title.go rename to internal/mcfunction/builtin/title.go index 0f0dc91..306c256 100644 --- a/internal/mcfunction/vanilla/title.go +++ b/internal/mcfunction/builtin/title.go @@ -1,4 +1,4 @@ -package vanilla +package builtin import ( "math" diff --git a/internal/mcfunction/vanilla/titleraw.go b/internal/mcfunction/builtin/titleraw.go similarity index 99% rename from internal/mcfunction/vanilla/titleraw.go rename to internal/mcfunction/builtin/titleraw.go index 25a3b78..e1c7ee4 100644 --- a/internal/mcfunction/vanilla/titleraw.go +++ b/internal/mcfunction/builtin/titleraw.go @@ -1,4 +1,4 @@ -package vanilla +package builtin import ( "math" diff --git a/internal/mcfunction/vanilla/toggledownfall.go b/internal/mcfunction/builtin/toggledownfall.go similarity index 94% rename from internal/mcfunction/vanilla/toggledownfall.go rename to internal/mcfunction/builtin/toggledownfall.go index 7ca8758..b837160 100644 --- a/internal/mcfunction/vanilla/toggledownfall.go +++ b/internal/mcfunction/builtin/toggledownfall.go @@ -1,4 +1,4 @@ -package vanilla +package builtin import "github.com/rockide/language-server/internal/mcfunction" diff --git a/internal/mcfunction/vanilla/weather.go b/internal/mcfunction/builtin/weather.go similarity index 97% rename from internal/mcfunction/vanilla/weather.go rename to internal/mcfunction/builtin/weather.go index aa23796..0934a93 100644 --- a/internal/mcfunction/vanilla/weather.go +++ b/internal/mcfunction/builtin/weather.go @@ -1,4 +1,4 @@ -package vanilla +package builtin import "github.com/rockide/language-server/internal/mcfunction" diff --git a/internal/mcfunction/vanilla/xp.go b/internal/mcfunction/builtin/xp.go similarity index 97% rename from internal/mcfunction/vanilla/xp.go rename to internal/mcfunction/builtin/xp.go index e764e23..0df9b2b 100644 --- a/internal/mcfunction/vanilla/xp.go +++ b/internal/mcfunction/builtin/xp.go @@ -1,4 +1,4 @@ -package vanilla +package builtin import "github.com/rockide/language-server/internal/mcfunction" From d236d9c6212e48cfbdf425511b8f2afc7a07659f Mon Sep 17 00:00:00 2001 From: Beltsazar Date: Tue, 20 Jan 2026 14:24:47 +0700 Subject: [PATCH 06/13] Move json document parsing to a separate method --- handlers/handler_json.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/handlers/handler_json.go b/handlers/handler_json.go index 43b6e5d..7a3bafe 100644 --- a/handlers/handler_json.go +++ b/handlers/handler_json.go @@ -59,6 +59,10 @@ func (j *JsonHandler) Parse(uri protocol.DocumentURI) error { if err != nil { return err } + return j.ParseDocument(document) +} + +func (j *JsonHandler) ParseDocument(document *textdocument.TextDocument) error { root, _ := jsonc.ParseTree(document.GetText(), nil) for _, entry := range j.Entries { if entry.Store == nil { @@ -71,7 +75,7 @@ func (j *JsonHandler) Parse(uri protocol.DocumentURI) error { continue } ctx := JsonContext{ - URI: uri, + URI: document.URI, NodeValue: nodeValue, GetPath: func() jsonc.Path { return jsonc.GetNodePath(node) @@ -96,7 +100,7 @@ func (j *JsonHandler) Parse(uri protocol.DocumentURI) error { } entry.Store.Insert(scope, core.Symbol{ Value: nodeValue, - URI: uri, + URI: document.URI, Range: &protocol.Range{ Start: document.PositionAt(node.Offset + 1), End: document.PositionAt(node.Offset + node.Length - 1), From fa5f52023b1c89554b7e59ce833d45a3fd4d1b32 Mon Sep 17 00:00:00 2001 From: Svdex Date: Wed, 31 Dec 2025 07:53:26 +0700 Subject: [PATCH 07/13] Add paramspec suffix to string --- internal/mcfunction/spec.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/internal/mcfunction/spec.go b/internal/mcfunction/spec.go index fe41a66..5a7c25c 100644 --- a/internal/mcfunction/spec.go +++ b/internal/mcfunction/spec.go @@ -96,9 +96,13 @@ func (p ParameterSpec) ToString() string { s = p.Literals[0] } if p.Optional { - return "[" + s + "]" + s = "[" + s + "]" } - return "<" + s + ">" + s = "<" + s + ">" + if p.Kind == ParameterKindSuffixedInteger && p.Suffix != "" { + s += p.Suffix + } + return s } type NumberRange struct { From 4f43945c18594c1c7e669c2f2bd38099f4ebc5e8 Mon Sep 17 00:00:00 2001 From: Svdex Date: Wed, 31 Dec 2025 07:57:47 +0700 Subject: [PATCH 08/13] Fix item nbt snippet cursor --- handlers/handler_command.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/handlers/handler_command.go b/handlers/handler_command.go index 1123f73..2be8b80 100644 --- a/handlers/handler_command.go +++ b/handlers/handler_command.go @@ -272,7 +272,7 @@ func (h *CommandHandler) paramCompletions(node mcfunction.INodeCommand, editRang Label: "Item NBT Snippet...", Kind: protocol.SnippetCompletion, InsertTextFormat: &snippetTextFormat, - InsertText: escape(`{}`), + InsertText: escape(`{$0}`), }) case mcfunction.ParameterKindRelativeNumber: addItem("~") From 26964935258e04acf5172fb1b402e131a8cfe389 Mon Sep 17 00:00:00 2001 From: Svdex Date: Thu, 1 Jan 2026 08:24:37 +0700 Subject: [PATCH 09/13] Change set contains to containsone --- handlers/handler_command.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/handlers/handler_command.go b/handlers/handler_command.go index 2be8b80..6c16a48 100644 --- a/handlers/handler_command.go +++ b/handlers/handler_command.go @@ -155,7 +155,7 @@ func (h *CommandHandler) commandCompletions(editRange protocol.Range) []protocol result := []protocol.CompletionItem{} set := mapset.NewThreadUnsafeSet[string]() for name, spec := range h.Parser.RegisteredCommands() { - if set.Contains(name) { + if set.ContainsOne(name) { continue } set.Add(name) @@ -187,7 +187,7 @@ func (h *CommandHandler) paramCompletions(node mcfunction.INodeCommand, editRang return s } addItem := func(value string, kind ...protocol.CompletionItemKind) { - if set.Contains(value) { + if set.ContainsOne(value) { return } set.Add(value) @@ -290,7 +290,7 @@ func (h *CommandHandler) paramCompletions(node mcfunction.INodeCommand, editRang } addCompletions(param) for _, tag := range param.Tags { - if tagSet.Contains(tag) { + if tagSet.ContainsOne(tag) { continue } tagSet.Add(tag) From f358bb209c6aeeede01f014cc8f41111c90fe5ab Mon Sep 17 00:00:00 2001 From: Svdex Date: Thu, 1 Jan 2026 10:19:32 +0700 Subject: [PATCH 10/13] Add selector arg --- handlers/handler_command.go | 226 +++++++++++++------- internal/mcfunction/builtin/clone.go | 7 +- internal/mcfunction/builtin/common.go | 12 ++ internal/mcfunction/builtin/execute.go | 6 +- internal/mcfunction/builtin/fill.go | 26 +-- internal/mcfunction/builtin/setblock.go | 6 +- internal/mcfunction/builtin/testforblock.go | 7 +- internal/mcfunction/lexer/lexer.go | 2 +- internal/mcfunction/lexer/token.go | 2 +- internal/mcfunction/node.go | 16 -- internal/mcfunction/node_arg.go | 10 +- internal/mcfunction/node_arg_chain.go | 6 +- internal/mcfunction/node_arg_map.go | 24 +++ internal/mcfunction/node_arg_pair.go | 224 ++++++++++++------- internal/mcfunction/node_command.go | 12 +- internal/mcfunction/nodes.go | 50 +++++ internal/mcfunction/overload_state.go | 27 ++- internal/mcfunction/selector_arg.go | 102 ++++++--- internal/mcfunction/spec.go | 56 ++++- 19 files changed, 545 insertions(+), 276 deletions(-) create mode 100644 internal/mcfunction/builtin/common.go create mode 100644 internal/mcfunction/node_arg_map.go create mode 100644 internal/mcfunction/nodes.go diff --git a/handlers/handler_command.go b/handlers/handler_command.go index 6c16a48..5dbca3f 100644 --- a/handlers/handler_command.go +++ b/handlers/handler_command.go @@ -16,6 +16,11 @@ import ( "github.com/rockide/language-server/stores" ) +// TODO: +// JSON Parse +// JSON Defintions +// JSON Rename + type CommandHandler struct { Pattern shared.Pattern Parser *mcfunction.Parser @@ -37,15 +42,15 @@ func (h *CommandHandler) Parse(uri protocol.DocumentURI) error { content := document.GetContent() root, _ := h.Parser.Parse(content) mcfunction.WalkNodeTree(root, func(i mcfunction.INode) bool { - arg, ok := i.(mcfunction.INodeArg) + nodeSpec, ok := i.(mcfunction.NodeParam) if !ok { return true } - param, ok := arg.ArgParamSpec() + paramSpec, ok := nodeSpec.ParamSpec() if !ok { return true } - for _, tag := range param.Tags { + for _, tag := range paramSpec.Tags { entry, ok := commandEntries[tag] if !ok || entry.Store == nil { continue @@ -57,7 +62,7 @@ func (h *CommandHandler) Parse(uri protocol.DocumentURI) error { s, e := i.Range() entry.Store.Insert(scope, core.Symbol{ URI: uri, - Value: arg.Text(content), + Value: i.Text(content), Range: &protocol.Range{ Start: document.PositionAt(s), End: document.PositionAt(e), @@ -82,11 +87,11 @@ func (h *CommandHandler) Delete(uri protocol.DocumentURI) { func (h *CommandHandler) Completions(document *textdocument.TextDocument, position protocol.Position) []protocol.CompletionItem { result := []protocol.CompletionItem{} - context := h.parseLine(document, position) - root := context.Root - rOffset := context.RelativeOffset - startOffset := context.StartOffset - line := context.Content + parsed := h.parseLine(document, position) + root := parsed.Root + rOffset := parsed.RelativeOffset + startOffset := parsed.StartOffset + line := parsed.Content node := mcfunction.NodeAt(root, rOffset) rStart, rEnd := node.Range() @@ -107,20 +112,8 @@ func (h *CommandHandler) Completions(document *textdocument.TextDocument, positi arg, ok := node.(mcfunction.INodeArg) if ok { switch arg.ParamKind() { - case mcfunction.ParameterKindSelectorArg: - for k := range mcfunction.SelectorArg { - result = append(result, protocol.CompletionItem{ - Label: k, - Kind: protocol.FieldCompletion, - TextEdit: &protocol.Or_CompletionItem_textEdit{ - Value: protocol.TextEdit{ - NewText: k, - Range: cursorRange, - }, - }, - }) - } - return result + case mcfunction.ParameterKindMap, mcfunction.ParameterKindMapPair, mcfunction.ParameterKindSelectorArg, mcfunction.ParameterKindMapJSON: + return h.mapCompletions(arg, cursorRange, nodeRange) case mcfunction.ParameterKindRawMessage: doc := document.CreateVirtualDocument(nodeRange) rawMessage.CommandHandler = h @@ -174,11 +167,11 @@ func (h *CommandHandler) commandCompletions(editRange protocol.Range) []protocol return result } -func (h *CommandHandler) paramCompletions(node mcfunction.INodeCommand, editRange protocol.Range) []protocol.CompletionItem { +func (h *CommandHandler) innerCompletions(node mcfunction.INodeCommand, paramSpec *mcfunction.ParameterSpec, editRange protocol.Range) []protocol.CompletionItem { result := []protocol.CompletionItem{} set := mapset.NewThreadUnsafeSet[string]() escape := func(s string) string { - if strings.ContainsAny(s, " /.") { + if strings.ContainsAny(s, " /") { s = `"` + s + `"` } if h.EscapeQuotes { @@ -206,8 +199,8 @@ func (h *CommandHandler) paramCompletions(node mcfunction.INodeCommand, editRang }, }) } - var addCompletions func(param mcfunction.ParameterSpec) - addCompletions = func(param mcfunction.ParameterSpec) { + var paramCompletions func(param *mcfunction.ParameterSpec) + paramCompletions = func(param *mcfunction.ParameterSpec) { if len(param.Literals) > 0 { for _, lit := range param.Literals { addItem(escape(lit), protocol.KeywordCompletion) @@ -232,7 +225,14 @@ func (h *CommandHandler) paramCompletions(node mcfunction.INodeCommand, editRang Label: "[]", Kind: protocol.SnippetCompletion, InsertTextFormat: &snippetTextFormat, - InsertText: escape("[$1=$0]"), + InsertText: "[$1=$0]", + }) + case mcfunction.ParameterKindMapJSON, mcfunction.ParameterKindJSON: + result = append(result, protocol.CompletionItem{ + Label: "{}", + Kind: protocol.SnippetCompletion, + InsertTextFormat: &snippetTextFormat, + InsertText: "{$0}", }) case mcfunction.ParameterKindVector2: addItem("~~") @@ -253,8 +253,10 @@ func (h *CommandHandler) paramCompletions(node mcfunction.INodeCommand, editRang addItem("*") addItem("0") case mcfunction.ParameterKindChainedCommand: - for _, o := range node.OverloadStates() { - addCompletions(o.Parameters()[0]) + if node != nil { + for _, o := range node.OverloadStates() { + paramCompletions(&o.Parameters()[0]) + } } case mcfunction.ParameterKindCommand: for name := range h.Parser.RegisteredCommands() { @@ -280,15 +282,7 @@ func (h *CommandHandler) paramCompletions(node mcfunction.INodeCommand, editRang } } tagSet := mapset.NewThreadUnsafeSet[string]() - for _, o := range node.OverloadStates() { - if !o.Matched() { - continue - } - param, ok := o.Peek() - if !ok { - continue - } - addCompletions(param) + tagCompletions := func(param *mcfunction.ParameterSpec) { for _, tag := range param.Tags { if tagSet.ContainsOne(tag) { continue @@ -315,34 +309,103 @@ func (h *CommandHandler) paramCompletions(node mcfunction.INodeCommand, editRang } } } + if node != nil { + for _, o := range node.OverloadStates() { + if !o.Matched() { + continue + } + param, ok := o.Peek() + if !ok { + continue + } + paramCompletions(¶m) + tagCompletions(¶m) + } + } + if paramSpec != nil { + paramCompletions(paramSpec) + tagCompletions(paramSpec) + } return result } +func (h *CommandHandler) paramCompletions(node mcfunction.INodeCommand, editRange protocol.Range) []protocol.CompletionItem { + return h.innerCompletions(node, nil, editRange) +} + +func (h *CommandHandler) paramSpecCompletions(spec *mcfunction.ParameterSpec, editRange protocol.Range) []protocol.CompletionItem { + return h.innerCompletions(nil, spec, editRange) +} + +func (h *CommandHandler) mapCompletions(node mcfunction.INodeArg, cursorRange protocol.Range, nodeRange protocol.Range) []protocol.CompletionItem { + keyCompletions := func(spec *mcfunction.ParameterSpec, keys []string, editRange protocol.Range) []protocol.CompletionItem { + var result []protocol.CompletionItem + for _, key := range keys { + result = append(result, protocol.CompletionItem{ + Label: key, + Kind: protocol.FieldCompletion, + TextEdit: &protocol.Or_CompletionItem_textEdit{ + Value: protocol.TextEdit{ + NewText: key, + Range: editRange, + }, + }, + }) + } + if spec != nil && spec.Kind != mcfunction.ParameterKindUnknown { + result = slices.Concat(result, h.paramSpecCompletions(spec, editRange)) + } + return result + } + switch n := node.(type) { + case mcfunction.INodeArgMap: + spec, _ := n.MapSpec().KeySpec() + return keyCompletions(spec, n.MapSpec().Keys(), cursorRange) + case mcfunction.INodeArgPairChild: + kind := n.PairKind() + switch kind { + case mcfunction.PairKindKey: + spec, _ := n.KeySpec() + keys := n.Keys() + return keyCompletions(&spec, keys, nodeRange) + case mcfunction.PairKindEqual, mcfunction.PairKindValue: + spec, ok := n.ValueSpec() + if ok { + if kind == mcfunction.PairKindValue { + cursorRange = nodeRange + } + return h.paramSpecCompletions(&spec, cursorRange) + } + } + } + return []protocol.CompletionItem{} +} + func (h *CommandHandler) Definitions(document *textdocument.TextDocument, position protocol.Position) []protocol.LocationLink { result := []protocol.LocationLink{} - context := h.parseLine(document, position) - root := context.Root - rOffset := context.RelativeOffset - startOffset := context.StartOffset - line := context.Content + parsed := h.parseLine(document, position) + root := parsed.Root + rOffset := parsed.RelativeOffset + startOffset := parsed.StartOffset + line := parsed.Content if root == nil { return nil } node := mcfunction.NodeAt(root, rOffset) - arg, ok := node.(mcfunction.INodeArg) + nodeSpec, ok := node.(mcfunction.NodeParam) if !ok { return result } - paramSpec, ok := arg.ArgParamSpec() + paramSpec, ok := nodeSpec.ParamSpec() if !ok { return result } - rStart, rEnd := arg.Range() + rStart, rEnd := node.Range() nodeRange := protocol.Range{ Start: document.PositionAt(startOffset + rStart), End: document.PositionAt(startOffset + rEnd), } - nodeValue := arg.Text(line) + nodeValue := node.Text(line) if h.EscapeQuotes { nodeValue = strings.Trim(nodeValue, `\"`) } else { @@ -376,29 +439,29 @@ func (h *CommandHandler) Definitions(document *textdocument.TextDocument, positi } func (h *CommandHandler) PrepareRename(document *textdocument.TextDocument, position protocol.Position) *protocol.PrepareRenamePlaceholder { - context := h.parseLine(document, position) - root := context.Root - rOffset := context.RelativeOffset - startOffset := context.StartOffset - line := context.Content + parsed := h.parseLine(document, position) + root := parsed.Root + rOffset := parsed.RelativeOffset + startOffset := parsed.StartOffset + line := parsed.Content if root == nil { return nil } node := mcfunction.NodeAt(root, rOffset) - arg, ok := node.(mcfunction.INodeArg) + nodeSpec, ok := node.(mcfunction.NodeParam) if !ok { return nil } - paramSpec, ok := arg.ArgParamSpec() + paramSpec, ok := nodeSpec.ParamSpec() if !ok { return nil } - rStart, rEnd := arg.Range() + rStart, rEnd := node.Range() nodeRange := protocol.Range{ Start: document.PositionAt(startOffset + rStart), End: document.PositionAt(startOffset + rEnd), } - nodeValue := arg.Text(line) + nodeValue := node.Text(line) for _, tag := range paramSpec.Tags { entry, ok := commandEntries[tag] if !ok || entry.DisableRename { @@ -413,23 +476,23 @@ func (h *CommandHandler) PrepareRename(document *textdocument.TextDocument, posi } func (h *CommandHandler) Rename(document *textdocument.TextDocument, position protocol.Position, newName string) *protocol.WorkspaceEdit { - context := h.parseLine(document, position) - root := context.Root - rOffset := context.RelativeOffset - line := context.Content + parsed := h.parseLine(document, position) + root := parsed.Root + rOffset := parsed.RelativeOffset + line := parsed.Content if root == nil { return nil } node := mcfunction.NodeAt(root, rOffset) - arg, ok := node.(mcfunction.INodeArg) + nodeSpec, ok := node.(mcfunction.NodeParam) if !ok { return nil } - paramSpec, ok := arg.ArgParamSpec() + paramSpec, ok := nodeSpec.ParamSpec() if !ok { return nil } - nodeValue := arg.Text(line) + nodeValue := node.Text(line) // TODO: Check cross rename between unescaped and escaped strings changes := make(map[protocol.DocumentURI][]protocol.TextEdit) for _, tag := range paramSpec.Tags { @@ -456,9 +519,9 @@ func (h *CommandHandler) Rename(document *textdocument.TextDocument, position pr } func (h *CommandHandler) Hover(document *textdocument.TextDocument, position protocol.Position) *protocol.Hover { - context := h.parseLine(document, position) - root := context.Root - rOffset := context.RelativeOffset + parsed := h.parseLine(document, position) + root := parsed.Root + rOffset := parsed.RelativeOffset if root == nil { return nil } @@ -485,16 +548,16 @@ func (h *CommandHandler) Hover(document *textdocument.TextDocument, position pro Value: "```\n" + commandNode.CommandName() + "\n```\n" + - commandNode.Spec().Description, + spec.Description, }, } } func (h *CommandHandler) SignatureHelp(document *textdocument.TextDocument, position protocol.Position) *protocol.SignatureHelp { - context := h.parseLine(document, position) - root := context.Root - rOffset := context.RelativeOffset - line := context.Content + parsed := h.parseLine(document, position) + root := parsed.Root + rOffset := parsed.RelativeOffset + line := parsed.Content if root == nil { return nil } @@ -557,7 +620,7 @@ func (h *CommandHandler) ComputeSemanticTokens(document *textdocument.TextDocume tokens := []semtok.Token{} molangRanges := []protocol.Range{} isMolang := func(node mcfunction.INodeArg) bool { - param, ok := node.ArgParamSpec() + param, ok := node.ParamSpec() if ok && slices.Contains(param.Tags, mcfunction.TagMolang) { start, end := node.Range() length := end - start @@ -605,7 +668,7 @@ func (h *CommandHandler) ComputeSemanticTokens(document *textdocument.TextDocume End: pB, }) } else if tokType, ok := commandParamTokenMap[n.ParamKind()]; ok { - spec, ok := n.ArgParamSpec() + spec, ok := n.ParamSpec() if ok && slices.Contains(spec.Tags, mcfunction.TagExecuteChain) { tokType = semtok.TokKeyword } @@ -714,12 +777,15 @@ var commandEntries = map[string]commandEntry{ return stores.ItemId.References.Get("block") }, }, - // mcfunction.TagBlockState: { - // Store: stores.BlockState.References, - // Source: func(node mcfunction.INode) []core.Symbol { - // return stores.BlockState.Source.Get() - // }, - // }, + mcfunction.TagBlockState: { + Store: stores.BlockState.References, + Source: func(node mcfunction.INode) []core.Symbol { + return stores.BlockState.Source.Get() + }, + References: func(node mcfunction.INode) []core.Symbol { + return stores.BlockState.References.Get() + }, + }, mcfunction.TagCameraId: { Store: stores.CameraId.References, Source: func(node mcfunction.INode) []core.Symbol { diff --git a/internal/mcfunction/builtin/clone.go b/internal/mcfunction/builtin/clone.go index feb85d8..3ad23dc 100644 --- a/internal/mcfunction/builtin/clone.go +++ b/internal/mcfunction/builtin/clone.go @@ -63,12 +63,7 @@ var Clone = &mcfunction.Spec{ Name: "tileName", Tags: []string{mcfunction.TagBlockId}, }, - { - Kind: mcfunction.ParameterKindMap, - Name: "blockStates", - Optional: true, - Tags: []string{mcfunction.TagBlockState}, - }, + blockStates, }, }, }, diff --git a/internal/mcfunction/builtin/common.go b/internal/mcfunction/builtin/common.go new file mode 100644 index 0000000..e053a32 --- /dev/null +++ b/internal/mcfunction/builtin/common.go @@ -0,0 +1,12 @@ +package builtin + +import "github.com/rockide/language-server/internal/mcfunction" + +var blockStates = mcfunction.ParameterSpec{ + Name: "blockStates", + Kind: mcfunction.ParameterKindMap, + MapSpec: mcfunction.NewMapValueSpec(&mcfunction.ParameterSpec{ + Kind: mcfunction.ParameterKindString, + Tags: []string{mcfunction.TagBlockState}, + }, nil), +} diff --git a/internal/mcfunction/builtin/execute.go b/internal/mcfunction/builtin/execute.go index 85104f1..4b4d6b2 100644 --- a/internal/mcfunction/builtin/execute.go +++ b/internal/mcfunction/builtin/execute.go @@ -287,11 +287,7 @@ var Execute = &mcfunction.Spec{ Name: "block", Tags: []string{mcfunction.TagBlockId}, }, - { - Kind: mcfunction.ParameterKindMap, - Name: "blockStates", - Tags: []string{mcfunction.TagBlockState}, - }, + blockStates, { Kind: mcfunction.ParameterKindChainedCommand, Name: "chainedCommand", diff --git a/internal/mcfunction/builtin/fill.go b/internal/mcfunction/builtin/fill.go index 77de894..d5a479a 100644 --- a/internal/mcfunction/builtin/fill.go +++ b/internal/mcfunction/builtin/fill.go @@ -29,11 +29,7 @@ var Fill = &mcfunction.Spec{ Name: "tileName", Tags: []string{mcfunction.TagBlockId}, }, - { - Kind: mcfunction.ParameterKindMap, - Name: "blockStates", - Tags: []string{mcfunction.TagBlockState}, - }, + blockStates, { Kind: mcfunction.ParameterKindLiteral, Name: "oldBlockHandling", @@ -80,11 +76,7 @@ var Fill = &mcfunction.Spec{ Name: "tileName", Tags: []string{mcfunction.TagBlockId}, }, - { - Kind: mcfunction.ParameterKindMap, - Name: "blockStates", - Tags: []string{mcfunction.TagBlockState}, - }, + blockStates, { Kind: mcfunction.ParameterKindLiteral, Name: "oldBlockHandling", @@ -96,12 +88,7 @@ var Fill = &mcfunction.Spec{ Optional: true, Tags: []string{mcfunction.TagBlockId}, }, - { - Kind: mcfunction.ParameterKindMap, - Name: "replaceBlockStates", - Optional: true, - Tags: []string{mcfunction.TagBlockState}, - }, + blockStates, }, }, { @@ -130,12 +117,7 @@ var Fill = &mcfunction.Spec{ Optional: true, Tags: []string{mcfunction.TagBlockId}, }, - { - Kind: mcfunction.ParameterKindMap, - Name: "replaceBlockStates", - Optional: true, - Tags: []string{mcfunction.TagBlockState}, - }, + blockStates, }, }, }, diff --git a/internal/mcfunction/builtin/setblock.go b/internal/mcfunction/builtin/setblock.go index 9e16efb..cbe033e 100644 --- a/internal/mcfunction/builtin/setblock.go +++ b/internal/mcfunction/builtin/setblock.go @@ -17,11 +17,7 @@ var Setblock = &mcfunction.Spec{ Name: "tileName", Tags: []string{mcfunction.TagBlockId}, }, - { - Kind: mcfunction.ParameterKindMap, - Name: "blockStates", - Tags: []string{mcfunction.TagBlockState}, - }, + blockStates, { Kind: mcfunction.ParameterKindLiteral, Name: "oldBlockHandling", diff --git a/internal/mcfunction/builtin/testforblock.go b/internal/mcfunction/builtin/testforblock.go index a37e7ee..a641ca6 100644 --- a/internal/mcfunction/builtin/testforblock.go +++ b/internal/mcfunction/builtin/testforblock.go @@ -17,12 +17,7 @@ var Testforblock = &mcfunction.Spec{ Name: "tileName", Tags: []string{mcfunction.TagBlockId}, }, - { - Kind: mcfunction.ParameterKindMap, - Name: "blockStates", - Optional: true, - Tags: []string{mcfunction.TagBlockState}, - }, + blockStates, }, }, }, diff --git a/internal/mcfunction/lexer/lexer.go b/internal/mcfunction/lexer/lexer.go index bcac400..09f85ea 100644 --- a/internal/mcfunction/lexer/lexer.go +++ b/internal/mcfunction/lexer/lexer.go @@ -300,7 +300,7 @@ func isNewline(r rune) bool { } func isTerminateString(r rune) bool { - return isNewline(r) || isWhitespace(r) || isRelativeNumber(r) || r == '@' || r == '"' || r == '[' || r == '{' || r == '=' || r == ',' || r == '.' || r == '!' + return isNewline(r) || isWhitespace(r) || isRelativeNumber(r) || r == '@' || r == '"' || r == '[' || r == '{' || r == '=' || r == ',' || r == '!' } func isRelativeNumber(r rune) bool { diff --git a/internal/mcfunction/lexer/token.go b/internal/mcfunction/lexer/token.go index e5a31a2..859789f 100644 --- a/internal/mcfunction/lexer/token.go +++ b/internal/mcfunction/lexer/token.go @@ -3,7 +3,7 @@ package lexer type TokenKind uint8 const ( - TokenEOF TokenKind = iota + TokenUnknown TokenKind = iota TokenWhitespace TokenNewline TokenComment diff --git a/internal/mcfunction/node.go b/internal/mcfunction/node.go index c9e4290..378bbf1 100644 --- a/internal/mcfunction/node.go +++ b/internal/mcfunction/node.go @@ -20,22 +20,6 @@ const ( NodeKindCommandArg ) -type INode interface { - addChild(child INode) - setParent(parent INode) - setIndex(index int) - - Kind() NodeKind - Range() (start, end uint32) - Text([]rune) string - PrevSibling() INode - NextSibling() INode - Parent() INode - Index() int - Children() []INode - IsInside(pos uint32) bool -} - type Node struct { kind NodeKind parent INode diff --git a/internal/mcfunction/node_arg.go b/internal/mcfunction/node_arg.go index 83654fe..6e81c73 100644 --- a/internal/mcfunction/node_arg.go +++ b/internal/mcfunction/node_arg.go @@ -1,11 +1,5 @@ package mcfunction -type INodeArg interface { - INode - ParamKind() ParameterKind - ArgParamSpec() (ParameterSpec, bool) -} - type NodeArg struct { *Node paramKind ParameterKind @@ -79,11 +73,11 @@ func (n *NodeArg) IsInside(pos uint32) bool { return n.start <= pos && pos < n.end } -func (n *NodeArg) ArgParamSpec() (ParameterSpec, bool) { +func (n *NodeArg) ParamSpec() (ParameterSpec, bool) { commandNode, ok := n.parent.(INodeCommand) if !ok { return ParameterSpec{}, false } argIndex := n.index - return commandNode.ParamSpec(argIndex) + return commandNode.ParamSpecAt(argIndex) } diff --git a/internal/mcfunction/node_arg_chain.go b/internal/mcfunction/node_arg_chain.go index 21c7941..60ce83c 100644 --- a/internal/mcfunction/node_arg_chain.go +++ b/internal/mcfunction/node_arg_chain.go @@ -69,13 +69,13 @@ func (n *NodeArgCommand) ParamKind() ParameterKind { return n.paramKind } -func (n *NodeArgCommand) ArgParamSpec() (ParameterSpec, bool) { +func (n *NodeArgCommand) ParamSpec() (ParameterSpec, bool) { commandNode, ok := n.parent.(INodeCommand) if !ok { return ParameterSpec{}, false } argIndex := n.index - return commandNode.ParamSpec(argIndex) + return commandNode.ParamSpecAt(argIndex) } func (n *NodeArgCommand) IsInside(pos uint32) bool { @@ -98,7 +98,7 @@ func (n *NodeArgCommand) OverloadStates() []*overloadState { return n.overloadStates } -func (n *NodeArgCommand) ParamSpec(index int) (ParameterSpec, bool) { +func (n *NodeArgCommand) ParamSpecAt(index int) (ParameterSpec, bool) { for _, o := range n.overloadStates { if !o.matched { continue diff --git a/internal/mcfunction/node_arg_map.go b/internal/mcfunction/node_arg_map.go new file mode 100644 index 0000000..4961f82 --- /dev/null +++ b/internal/mcfunction/node_arg_map.go @@ -0,0 +1,24 @@ +package mcfunction + +type nodeArgMap struct { + *NodeArg + mapSpec *MapSpec +} + +func (n *nodeArgMap) addChild(child INode) { + child.setParent(n) + child.setIndex(len(n.children)) + n.children = append(n.children, child) +} + +func (n *nodeArgMap) setParent(parent INode) { + n.parent = parent +} + +func (n *nodeArgMap) setIndex(index int) { + n.index = index +} + +func (n *nodeArgMap) MapSpec() *MapSpec { + return n.mapSpec +} diff --git a/internal/mcfunction/node_arg_pair.go b/internal/mcfunction/node_arg_pair.go index 4e3bfaf..72b14da 100644 --- a/internal/mcfunction/node_arg_pair.go +++ b/internal/mcfunction/node_arg_pair.go @@ -13,14 +13,10 @@ const ( PairKindValue ) -type INodeArgPair interface { - INodeArg - PairSpec() (ParameterSpec, bool) -} - type NodeArgPair struct { *NodeArg - spec ParameterSpec + keySpec *ParameterSpec + valueSpec *ParameterSpec } func (n *NodeArgPair) addChild(child INode) { @@ -37,14 +33,12 @@ func (n *NodeArgPair) setIndex(index int) { n.index = index } -func (n *NodeArgPair) PairSpec() (ParameterSpec, bool) { - return n.spec, n.spec.Kind != ParameterKindUnknown +func (n *NodeArgPair) KeySpec() (ParameterSpec, bool) { + return *n.keySpec, n.keySpec != nil } -type INodeArgPairChild interface { - INodeArg - PairKind() PairKind - PairSpec() (ParameterSpec, bool) +func (n *NodeArgPair) ValueSpec() (ParameterSpec, bool) { + return *n.valueSpec, n.valueSpec != nil } type NodeArgPairChild struct { @@ -70,91 +64,157 @@ func (n *NodeArgPairChild) PairKind() PairKind { return n.pairKind } -func (n *NodeArgPairChild) PairSpec() (ParameterSpec, bool) { - if p, ok := n.parent.(*NodeArgPair); ok { - return p.PairSpec() +func (n *NodeArgPairChild) KeySpec() (ParameterSpec, bool) { + parent, ok := n.parent.(*NodeArgPair) + if ok { + if parent.keySpec != nil { + return *parent.keySpec, true + } } return ParameterSpec{}, false } -func createSelectorArg(input []rune, token lexer.Token) *NodeArg { - value := []rune(token.Text(input)) - if len(value) < 2 || value[0] != '[' || value[len(value)-1] != ']' { - return nil +func (n *NodeArgPairChild) ValueSpec() (ParameterSpec, bool) { + parent, ok := n.parent.(*NodeArgPair) + if ok { + if parent.valueSpec != nil { + return *parent.valueSpec, true + } } - result := &NodeArg{ - Node: &Node{ - kind: NodeKindCommandArg, - start: token.Start, - end: token.End, - }, - paramKind: ParameterKindSelectorArg, + return ParameterSpec{}, false +} + +func (n *NodeArgPairChild) ParamSpec() (ParameterSpec, bool) { + switch n.pairKind { + case PairKindKey: + return n.KeySpec() + case PairKindValue: + return n.ValueSpec() } - if len(value) == 2 { - return result + return ParameterSpec{}, false +} + +func (n *NodeArgPairChild) Keys() []string { + p, ok := n.parent.(*NodeArgPair) + if ok { + a, ok := p.parent.(INodeArgMap) + if ok { + return a.MapSpec().Keys() + } } + return nil +} + +func createPairs(input []rune, token lexer.Token, spec *MapSpec) []*NodeArgPair { + value := []rune(token.Text(input)) startOffset := token.Start + 1 value = value[1 : len(value)-1] - lex := lexer.New([]rune(value)) + lex := lexer.New(value) keyTokens := []lexer.Token{} var assignToken lexer.Token valueTokens := []lexer.Token{} - createPair := func() { - tKey := mergeTokens(keyTokens...) - tValue := mergeTokens(valueTokens...) + createPair := func() *NodeArgPair { + start := assignToken.Start + startOffset + end := assignToken.End + startOffset + tKey, kOk := mergeTokens(keyTokens...) + var keyText string + if kOk { + start = tKey.Start + startOffset + if assignToken.Kind == lexer.TokenUnknown { + end = tKey.End + startOffset + } + } + tValue, vOk := mergeTokens(valueTokens...) + if vOk { + end = tValue.End + startOffset + } node := &NodeArgPair{ NodeArg: &NodeArg{ Node: &Node{ kind: NodeKindCommandArg, - start: tKey.Start + startOffset, - end: tValue.End + startOffset, + start: start, + end: end, }, paramKind: ParameterKindMapPair, }, } - key := &NodeArgPairChild{ - NodeArg: &NodeArg{ - Node: &Node{ - kind: NodeKindCommandArg, - start: tKey.Start + startOffset, - end: tKey.End + startOffset, + if kOk { + key := &NodeArgPairChild{ + NodeArg: &NodeArg{ + Node: &Node{ + kind: NodeKindCommandArg, + start: tKey.Start + startOffset, + end: tKey.End + startOffset, + }, + paramKind: ParameterKindMapPair, }, - paramKind: ParameterKindMapPair, - }, - pairKind: PairKindKey, - } - node.addChild(key) - keyValue := key.Text(input) - if spec, ok := SelectorArg[keyValue]; ok { - node.spec = spec + pairKind: PairKindKey, + } + node.addChild(key) + keyText = tKey.Text(value) + if spec != nil { + node.keySpec = spec.keySpec + if paramSpec, ok := spec.ValueSpec(keyText); ok { + node.valueSpec = paramSpec + } + } } - node.addChild(&NodeArgPairChild{ - NodeArg: &NodeArg{ - Node: &Node{ - kind: NodeKindCommandArg, - start: assignToken.Start + startOffset, - end: assignToken.End + startOffset, - }, - paramKind: ParameterKindMapPair, - }, - pairKind: PairKindEqual, - }) - node.addChild(&NodeArgPairChild{ - NodeArg: &NodeArg{ - Node: &Node{ - kind: NodeKindCommandArg, - start: tValue.Start + startOffset, - end: tValue.End + startOffset, + if assignToken.Kind != lexer.TokenUnknown { + node.addChild(&NodeArgPairChild{ + NodeArg: &NodeArg{ + Node: &Node{ + kind: NodeKindCommandArg, + start: assignToken.Start + startOffset, + end: assignToken.End + startOffset, + }, + paramKind: ParameterKindMapPair, }, - paramKind: ParameterKindMapPair, - }, - pairKind: PairKindValue, - }) + pairKind: PairKindEqual, + }) + } + if vOk { + first := valueTokens[0] + first.Start += startOffset + first.End += startOffset + if first.Kind == lexer.TokenMap || first.Kind == lexer.TokenJSON { + if node.valueSpec != nil { + pairs := createPairs(input, first, node.valueSpec.MapSpec) + mapNode := &nodeArgMap{ + NodeArg: &NodeArg{ + Node: &Node{ + kind: NodeKindCommandArg, + start: tValue.Start + startOffset, + end: tValue.End + startOffset, + }, + paramKind: node.valueSpec.Kind, + }, + mapSpec: node.valueSpec.MapSpec, + } + node.addChild(mapNode) + for _, p := range pairs { + mapNode.addChild(p) + } + } + } else { + node.addChild(&NodeArgPairChild{ + NodeArg: &NodeArg{ + Node: &Node{ + kind: NodeKindCommandArg, + start: tValue.Start + startOffset, + end: tValue.End + startOffset, + }, + paramKind: ParameterKindMapPair, + }, + pairKind: PairKindValue, + }) + } + } keyTokens = []lexer.Token{} valueTokens = []lexer.Token{} assignToken = lexer.Token{} - result.addChild(node) + return node } + pairs := []*NodeArgPair{} state := 0 for t := range lex.Next() { if t.Kind == lexer.TokenComment || t.Kind == lexer.TokenWhitespace { @@ -172,22 +232,30 @@ func createSelectorArg(input []rune, token lexer.Token) *NodeArg { keyTokens = append(keyTokens, t) } case 1: - if t.Kind == lexer.TokenComma { + switch t.Kind { + case lexer.TokenComma, lexer.TokenWhitespace: state = 0 - } else { + pairs = append(pairs, createPair()) + case lexer.TokenMap, lexer.TokenJSON: + valueTokens = append(valueTokens, t) + if len(valueTokens) == 1 { + state = 0 + pairs = append(pairs, createPair()) + } + default: valueTokens = append(valueTokens, t) } } } - if len(keyTokens) > 0 { - createPair() + if assignToken.Kind != lexer.TokenUnknown || len(keyTokens) > 0 { + pairs = append(pairs, createPair()) } - return result + return pairs } -func mergeTokens(tokens ...lexer.Token) lexer.Token { +func mergeTokens(tokens ...lexer.Token) (lexer.Token, bool) { if len(tokens) == 0 { - return lexer.Token{} + return lexer.Token{}, false } start := tokens[0].Start end := tokens[0].End @@ -203,5 +271,5 @@ func mergeTokens(tokens ...lexer.Token) lexer.Token { Kind: lexer.TokenString, Start: start, End: end, - } + }, true } diff --git a/internal/mcfunction/node_command.go b/internal/mcfunction/node_command.go index 124c6ad..0db3f57 100644 --- a/internal/mcfunction/node_command.go +++ b/internal/mcfunction/node_command.go @@ -1,15 +1,5 @@ package mcfunction -type INodeCommand interface { - INode - CommandName() string - Args() []INode - Spec() *Spec - OverloadStates() []*overloadState - ParamSpec(index int) (ParameterSpec, bool) - IsValid() bool -} - type NodeCommand struct { *Node name string @@ -54,7 +44,7 @@ func (n *NodeCommand) OverloadStates() []*overloadState { return n.overloadStates } -func (n *NodeCommand) ParamSpec(index int) (ParameterSpec, bool) { +func (n *NodeCommand) ParamSpecAt(index int) (ParameterSpec, bool) { for _, o := range n.overloadStates { if !o.matched { continue diff --git a/internal/mcfunction/nodes.go b/internal/mcfunction/nodes.go new file mode 100644 index 0000000..7bfb9e0 --- /dev/null +++ b/internal/mcfunction/nodes.go @@ -0,0 +1,50 @@ +package mcfunction + +type INode interface { + addChild(child INode) + setParent(parent INode) + setIndex(index int) + + Kind() NodeKind + Range() (start, end uint32) + Text([]rune) string + PrevSibling() INode + NextSibling() INode + Parent() INode + Index() int + Children() []INode + IsInside(pos uint32) bool +} + +type NodeParam interface { + ParamSpec() (ParameterSpec, bool) +} + +type INodeArg interface { + INode + NodeParam + ParamKind() ParameterKind +} + +type INodeArgMap interface { + INodeArg + MapSpec() *MapSpec +} + +type INodeArgPairChild interface { + INodeArg + PairKind() PairKind + Keys() []string + KeySpec() (ParameterSpec, bool) + ValueSpec() (ParameterSpec, bool) +} + +type INodeCommand interface { + INode + CommandName() string + Args() []INode + Spec() *Spec + OverloadStates() []*overloadState + ParamSpecAt(index int) (ParameterSpec, bool) + IsValid() bool +} diff --git a/internal/mcfunction/overload_state.go b/internal/mcfunction/overload_state.go index 0f1ad45..758611b 100644 --- a/internal/mcfunction/overload_state.go +++ b/internal/mcfunction/overload_state.go @@ -143,16 +143,22 @@ func (o *overloadState) matchParameter(input []rune, tokens []lexer.Token, token if tokenIndex+1 < len(tokens) && tokens[tokenIndex+1].Kind == lexer.TokenMap { next := tokens[tokenIndex+1] advance = 2 - selArg := createSelectorArg(input, next) - if selArg == nil { - arg.addChild(&NodeArg{ + selArg := &nodeArgMap{ + NodeArg: &NodeArg{ Node: &Node{ kind: NodeKindCommandArg, start: next.Start, end: next.End, }, paramKind: ParameterKindSelectorArg, - }) + }, + mapSpec: SelectorArg, + } + pairs := createPairs(input, next, SelectorArg) + if len(pairs) > 0 { + for _, p := range pairs { + selArg.addChild(p) + } } arg.addChild(selArg) arg.Node.end = tokens[tokenIndex+1].End @@ -162,8 +168,17 @@ func (o *overloadState) matchParameter(input []rune, tokens []lexer.Token, token } case ParameterKindMap: if token.Kind == lexer.TokenMap { - // TODO: - return arg, 1, nil + mapArg := &nodeArgMap{ + NodeArg: arg, + mapSpec: param.MapSpec, + } + pairs := createPairs(input, token, param.MapSpec) + if len(pairs) > 0 { + for _, p := range pairs { + mapArg.addChild(p) + } + } + return mapArg, 1, nil } case ParameterKindJSON: if token.Kind == lexer.TokenJSON { diff --git a/internal/mcfunction/selector_arg.go b/internal/mcfunction/selector_arg.go index eae2411..6e8b779 100644 --- a/internal/mcfunction/selector_arg.go +++ b/internal/mcfunction/selector_arg.go @@ -1,8 +1,16 @@ package mcfunction -var SelectorArg = map[string]ParameterSpec{ +var permissionValueSpec = &ParameterSpec{ + Kind: ParameterKindLiteral, + Literals: []string{ + "enabled", + "disabled", + }, +} + +var SelectorArg = NewMapSpec(map[string]*ParameterSpec{ "c": { - Kind: ParameterKindNumber, + Kind: ParameterKindInteger, }, "dx": { Kind: ParameterKindRelativeNumber, @@ -17,24 +25,65 @@ var SelectorArg = map[string]ParameterSpec{ Kind: ParameterKindString, Tags: []string{TagTypeFamilyId}, }, - // TODO: This - // "has_property": { - // Kind: ParameterKindJSON, - // }, - // TODO: This - // "hasitem": { - // data: integer - // item: string - // location: slot location - // quantity: integer range - // slot: integer range - // Kind: ParameterKindJSON, - // }, - // TODO: This - // "haspermission": { - // = - // Kind: ParameterKindJSON, - // }, + "has_property": { + Kind: ParameterKindMapJSON, + MapSpec: NewMapValueSpec(nil, &ParameterSpec{ + Kind: ParameterKindBoolean, + }), + }, + "hasitem": { + Kind: ParameterKindMapJSON, + MapSpec: NewMapSpec(map[string]*ParameterSpec{ + "data": { + Kind: ParameterKindInteger, + }, + "item": { + Kind: ParameterKindString, + Tags: []string{TagItemId}, + }, + "location": { + Kind: ParameterKindLiteral, + Literals: []string{ + "slot.armor", + "slot.armor.body", + "slot.armor.chest", + "slot.armor.feet", + "slot.armor.head", + "slot.armor.legs", + "slot.chest", + "slot.enderchest", + "slot.equippable", + "slot.hotbar", + "slot.inventory", + "slot.saddle", + "slot.weapon.mainhand", + "slot.weapon.offhand", + }, + }, + "quantity": { + Kind: ParameterKindRange, + }, + "slot": { + Kind: ParameterKindRange, + }, + }), + }, + "haspermission": { + Kind: ParameterKindMapJSON, + MapSpec: NewMapSpec(map[string]*ParameterSpec{ + "camera": permissionValueSpec, + "dismount": permissionValueSpec, + "jump": permissionValueSpec, + "lateral_movement": permissionValueSpec, + "mount": permissionValueSpec, + "move_backward": permissionValueSpec, + "move_forward": permissionValueSpec, + "move_left": permissionValueSpec, + "move_right": permissionValueSpec, + "movement": permissionValueSpec, + "sneak": permissionValueSpec, + }), + }, "l": { Kind: ParameterKindInteger, }, @@ -85,15 +134,18 @@ var SelectorArg = map[string]ParameterSpec{ "rym": { Kind: ParameterKindRelativeNumber, }, - // TODO: This - // "scores": { - // }, + "scores": { + Kind: ParameterKindMapJSON, + MapSpec: NewMapValueSpec(nil, &ParameterSpec{ + Kind: ParameterKindRange, + }), + }, "tag": { Kind: ParameterKindString, }, "type": { Kind: ParameterKindString, - Tags: []string{TagTypeFamilyId}, + Tags: []string{TagEntityId}, }, "x": { Kind: ParameterKindRelativeNumber, @@ -104,4 +156,4 @@ var SelectorArg = map[string]ParameterSpec{ "z": { Kind: ParameterKindRelativeNumber, }, -} +}) diff --git a/internal/mcfunction/spec.go b/internal/mcfunction/spec.go index 5a7c25c..0303893 100644 --- a/internal/mcfunction/spec.go +++ b/internal/mcfunction/spec.go @@ -23,6 +23,7 @@ const ( ParameterKindSelector // @p, @a, @r, @s, @e, @n, @initiator ParameterKindSelectorArg // selector arguments ParameterKindMap // [key=value,...] + ParameterKindMapJSON // Just a map but with { } wrapping, {key=value,...} ParameterKindJSON // JSON object or array ParameterKindVector2 // x y or rotX rotY ParameterKindVector3 // x y z @@ -83,8 +84,9 @@ type ParameterSpec struct { Literals []string // only for ParameterKindLiteral Range *NumberRange // For number, integer, and range Tags []string - Greedy bool // only for KindString - Suffix string // only for KindSuffixedInteger + Greedy bool // only for KindString + Suffix string // only for KindSuffixedInteger + MapSpec *MapSpec // only for KindMap and KindMapJSON } func (p ParameterSpec) ToString() string { @@ -97,8 +99,9 @@ func (p ParameterSpec) ToString() string { } if p.Optional { s = "[" + s + "]" + } else { + s = "<" + s + ">" } - s = "<" + s + ">" if p.Kind == ParameterKindSuffixedInteger && p.Suffix != "" { s += p.Suffix } @@ -109,3 +112,50 @@ type NumberRange struct { Min float64 Max float64 } + +type MapSpec struct { + mapSpec map[string]*ParameterSpec + keySpec *ParameterSpec + spec *ParameterSpec +} + +func NewMapSpec(spec map[string]*ParameterSpec) *MapSpec { + return &MapSpec{ + mapSpec: spec, + } +} + +func NewMapValueSpec(key *ParameterSpec, value *ParameterSpec) *MapSpec { + return &MapSpec{ + keySpec: key, + spec: value, + } +} + +func (m *MapSpec) KeySpec() (*ParameterSpec, bool) { + if m.keySpec != nil { + return m.keySpec, true + } + return nil, false +} + +func (m *MapSpec) ValueSpec(key string) (*ParameterSpec, bool) { + if m.mapSpec != nil { + s, ok := m.mapSpec[key] + return s, ok + } + return m.spec, m.spec != nil +} + +func (m *MapSpec) Keys() []string { + if m.mapSpec != nil { + keys := make([]string, len(m.mapSpec)) + i := 0 + for k := range m.mapSpec { + keys[i] = k + i++ + } + return keys + } + return []string{} +} From 5dca99c939a3564f1c961901b872eed7be9b48e5 Mon Sep 17 00:00:00 2001 From: Svdex Date: Tue, 20 Jan 2026 08:35:57 +0700 Subject: [PATCH 11/13] Add command node --- handlers/handler_command.go | 21 +++++++++------------ internal/mcfunction/node_arg.go | 8 ++++++++ internal/mcfunction/node_arg_chain.go | 4 ++++ internal/mcfunction/nodes.go | 1 + 4 files changed, 22 insertions(+), 12 deletions(-) diff --git a/handlers/handler_command.go b/handlers/handler_command.go index 5dbca3f..caa8bce 100644 --- a/handlers/handler_command.go +++ b/handlers/handler_command.go @@ -531,7 +531,7 @@ func (h *CommandHandler) Hover(document *textdocument.TextDocument, position pro case mcfunction.INodeCommand: commandNode = n case mcfunction.INodeArg: - if parent, ok := n.Parent().(mcfunction.INodeCommand); ok { + if parent := n.CommandNode(); parent != nil && parent.IsValid() { commandNode = parent } } @@ -563,21 +563,18 @@ func (h *CommandHandler) SignatureHelp(document *textdocument.TextDocument, posi } node := mcfunction.NodeAt(root, rOffset) var commandNode mcfunction.INodeCommand - flag := false -REPARSE: - rStart, _ := node.Range() switch n := node.(type) { case mcfunction.INodeCommand: commandNode = n case mcfunction.INodeArg: - if parent, ok := n.Parent().(mcfunction.INodeCommand); ok { - if parent.IsValid() { - commandNode = parent - } else if !flag { - root, _ := h.Parser.Parse(line[:rStart]) - node = mcfunction.NodeAt(root, rStart) - flag = true - goto REPARSE + if parent := n.CommandNode(); parent != nil && parent.IsValid() { + commandNode = parent + } else { + s, _ := n.Range() + root, _ := h.Parser.Parse(line[:s]) + node = mcfunction.NodeAt(root, s) + if n, ok := node.(mcfunction.INodeCommand); ok { + commandNode = n } } } diff --git a/internal/mcfunction/node_arg.go b/internal/mcfunction/node_arg.go index 6e81c73..e3b26e2 100644 --- a/internal/mcfunction/node_arg.go +++ b/internal/mcfunction/node_arg.go @@ -81,3 +81,11 @@ func (n *NodeArg) ParamSpec() (ParameterSpec, bool) { argIndex := n.index return commandNode.ParamSpecAt(argIndex) } + +func (n *NodeArg) CommandNode() INodeCommand { + commandNode, ok := n.parent.(INodeCommand) + if !ok { + return nil + } + return commandNode +} diff --git a/internal/mcfunction/node_arg_chain.go b/internal/mcfunction/node_arg_chain.go index 60ce83c..633a7e7 100644 --- a/internal/mcfunction/node_arg_chain.go +++ b/internal/mcfunction/node_arg_chain.go @@ -118,3 +118,7 @@ func (n *NodeArgCommand) IsValid() bool { } return false } + +func (n *NodeArgCommand) CommandNode() INodeCommand { + return n +} diff --git a/internal/mcfunction/nodes.go b/internal/mcfunction/nodes.go index 7bfb9e0..12d3dcc 100644 --- a/internal/mcfunction/nodes.go +++ b/internal/mcfunction/nodes.go @@ -24,6 +24,7 @@ type INodeArg interface { INode NodeParam ParamKind() ParameterKind + CommandNode() INodeCommand } type INodeArgMap interface { From c633db3f7ff12054bdf80716d7a8b2de3bee4463 Mon Sep 17 00:00:00 2001 From: Svdex Date: Wed, 21 Jan 2026 00:59:34 +0700 Subject: [PATCH 12/13] Change infinite loop detection --- internal/mcfunction/lexer/lexer.go | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/internal/mcfunction/lexer/lexer.go b/internal/mcfunction/lexer/lexer.go index 09f85ea..a5247f0 100644 --- a/internal/mcfunction/lexer/lexer.go +++ b/internal/mcfunction/lexer/lexer.go @@ -5,15 +5,17 @@ import ( ) type Lexer struct { - src []rune - i int - state state + src []rune + i int + state state + lastPos int } func New(input []rune) *Lexer { return &Lexer{ - src: input, - state: StateStart, + src: input, + state: StateStart, + lastPos: -1, } } @@ -39,6 +41,7 @@ func (l *Lexer) advance() rune { if l.eof() { return 0 } + l.lastPos = l.i r := l.src[l.i] l.i++ return r @@ -83,13 +86,15 @@ func (l *Lexer) matchPairs(open, close rune) bool { return false } +func (l *Lexer) isInfiniteLoop() bool { + return l.i == l.lastPos +} + func (l *Lexer) Next() iter.Seq[Token] { return func(yield func(Token) bool) { - depth := -1 for !l.eof() { - depth++ - if depth > 1000 { - panic("lexer: possible infinite loop detected") + if l.isInfiniteLoop() { + panic("possible infinite loop in lexer") } r := l.peek() start := l.pos() @@ -288,6 +293,7 @@ func (l *Lexer) Next() iter.Seq[Token] { func (l *Lexer) Reset(input []rune) { l.src = input l.i = 0 + l.lastPos = -1 l.state = StateStart } From 1f1b351b57f88f2e1460902500c708314f44d05f Mon Sep 17 00:00:00 2001 From: Svdex Date: Wed, 21 Jan 2026 00:59:53 +0700 Subject: [PATCH 13/13] Fix relative number offset lexer --- internal/mcfunction/lexer/lexer.go | 1 + 1 file changed, 1 insertion(+) diff --git a/internal/mcfunction/lexer/lexer.go b/internal/mcfunction/lexer/lexer.go index a5247f0..fae975c 100644 --- a/internal/mcfunction/lexer/lexer.go +++ b/internal/mcfunction/lexer/lexer.go @@ -242,6 +242,7 @@ func (l *Lexer) Next() iter.Seq[Token] { } if isDigit(r) { l.advanceWhile(isDigit) + r = l.peek() } if r == '.' { l.advance() // consume '.'