added suggestion for variables

This commit is contained in:
Martino Ferrari
2026-02-02 14:37:03 +01:00
parent ff19fef779
commit 55ca313b73
2 changed files with 136 additions and 11 deletions

View File

@@ -265,7 +265,7 @@ func HandleMessage(msg *JsonRpcMessage) {
"documentFormattingProvider": true, "documentFormattingProvider": true,
"renameProvider": true, "renameProvider": true,
"completionProvider": map[string]any{ "completionProvider": map[string]any{
"triggerCharacters": []string{"=", " "}, "triggerCharacters": []string{"=", " ", "@"},
}, },
}, },
}) })
@@ -675,6 +675,20 @@ func HandleCompletion(params CompletionParams) *CompletionList {
prefix := lineStr[:col] prefix := lineStr[:col]
// Case 3: Variable completion
varRegex := regexp.MustCompile(`([@$])([a-zA-Z0-9_]*)$`)
if matches := varRegex.FindStringSubmatch(prefix); matches != nil {
container := Tree.GetNodeContaining(path, parser.Position{Line: params.Position.Line + 1, Column: col + 1})
if container == nil {
if iso, ok := Tree.IsolatedFiles[path]; ok {
container = iso
} else {
container = Tree.Root
}
}
return suggestVariables(container)
}
// Case 1: Assigning a value (Ends with "=" or "= ") // Case 1: Assigning a value (Ends with "=" or "= ")
if strings.Contains(prefix, "=") { if strings.Contains(prefix, "=") {
lastIdx := strings.LastIndex(prefix, "=") lastIdx := strings.LastIndex(prefix, "=")
@@ -907,20 +921,41 @@ func suggestFieldValues(container *index.ProjectNode, field string, path string)
root = Tree.Root root = Tree.Root
} }
var items []CompletionItem
if field == "DataSource" { if field == "DataSource" {
return suggestObjects(root, "DataSource") if list := suggestObjects(root, "DataSource"); list != nil {
items = append(items, list.Items...)
} }
if field == "Functions" { } else if field == "Functions" {
return suggestObjects(root, "GAM") if list := suggestObjects(root, "GAM"); list != nil {
items = append(items, list.Items...)
} }
if field == "Type" { } else if field == "Type" {
return suggestSignalTypes() if list := suggestSignalTypes(); list != nil {
items = append(items, list.Items...)
} }
} else {
if list := suggestCUEEnums(container, field); list != nil { if list := suggestCUEEnums(container, field); list != nil {
return list items = append(items, list.Items...)
}
} }
// Add variables
vars := suggestVariables(container)
if vars != nil {
for _, item := range vars.Items {
// Create copy to modify label
newItem := item
newItem.Label = "@" + newItem.Label
newItem.InsertText = "@" + item.Label
items = append(items, newItem)
}
}
if len(items) > 0 {
return &CompletionList{Items: items}
}
return nil return nil
} }
@@ -1518,3 +1553,31 @@ func send(msg any) {
body, _ := json.Marshal(msg) body, _ := json.Marshal(msg)
fmt.Fprintf(Output, "Content-Length: %d\r\n\r\n%s", len(body), body) fmt.Fprintf(Output, "Content-Length: %d\r\n\r\n%s", len(body), body)
} }
func suggestVariables(container *index.ProjectNode) *CompletionList {
items := []CompletionItem{}
seen := make(map[string]bool)
curr := container
for curr != nil {
for name, info := range curr.Variables {
if !seen[name] {
seen[name] = true
doc := ""
if info.Def.DefaultValue != nil {
doc = fmt.Sprintf("Default: %s", valueToString(info.Def.DefaultValue))
}
items = append(items, CompletionItem{
Label: name,
Kind: 6, // Variable
Detail: fmt.Sprintf("Variable (%s)", info.Def.TypeExpr),
Documentation: doc,
})
}
}
curr = curr.Parent
}
return &CompletionList{Items: items}
}

View File

@@ -317,4 +317,66 @@ package schema
} }
} }
}) })
t.Run("Suggest Variables", func(t *testing.T) {
setup()
content := `
#var MyVar: uint = 10
+App = {
Field =
}
`
lsp.Documents[uri] = content
p := parser.NewParser(content)
cfg, _ := p.Parse()
lsp.Tree.AddFile(path, cfg)
// 1. Triggered by =
params := lsp.CompletionParams{
TextDocument: lsp.TextDocumentIdentifier{URI: uri},
Position: lsp.Position{Line: 3, Character: 12}, // After "Field = "
}
list := lsp.HandleCompletion(params)
if list == nil {
t.Fatal("Expected suggestions")
}
found := false
for _, item := range list.Items {
if item.Label == "@MyVar" {
found = true
break
}
}
if !found {
t.Error("Expected @MyVar in suggestions for =")
}
// 2. Triggered by $
// "Field = $"
lsp.Documents[uri] = `
#var MyVar: uint = 10
+App = {
Field = $
}
`
params2 := lsp.CompletionParams{
TextDocument: lsp.TextDocumentIdentifier{URI: uri},
Position: lsp.Position{Line: 3, Character: 13}, // After "Field = $"
}
list2 := lsp.HandleCompletion(params2)
if list2 == nil {
t.Fatal("Expected suggestions for $")
}
found = false
for _, item := range list2.Items {
if item.Label == "MyVar" { // suggestVariables returns "MyVar"
found = true
break
}
}
if !found {
t.Error("Expected MyVar in suggestions for $")
}
})
} }