added suggestion for variables
This commit is contained in:
@@ -265,7 +265,7 @@ func HandleMessage(msg *JsonRpcMessage) {
|
||||
"documentFormattingProvider": true,
|
||||
"renameProvider": true,
|
||||
"completionProvider": map[string]any{
|
||||
"triggerCharacters": []string{"=", " "},
|
||||
"triggerCharacters": []string{"=", " ", "@"},
|
||||
},
|
||||
},
|
||||
})
|
||||
@@ -675,6 +675,20 @@ func HandleCompletion(params CompletionParams) *CompletionList {
|
||||
|
||||
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 "= ")
|
||||
if strings.Contains(prefix, "=") {
|
||||
lastIdx := strings.LastIndex(prefix, "=")
|
||||
@@ -907,20 +921,41 @@ func suggestFieldValues(container *index.ProjectNode, field string, path string)
|
||||
root = Tree.Root
|
||||
}
|
||||
|
||||
var items []CompletionItem
|
||||
|
||||
if field == "DataSource" {
|
||||
return suggestObjects(root, "DataSource")
|
||||
if list := suggestObjects(root, "DataSource"); list != nil {
|
||||
items = append(items, list.Items...)
|
||||
}
|
||||
if field == "Functions" {
|
||||
return suggestObjects(root, "GAM")
|
||||
} else if field == "Functions" {
|
||||
if list := suggestObjects(root, "GAM"); list != nil {
|
||||
items = append(items, list.Items...)
|
||||
}
|
||||
if field == "Type" {
|
||||
return suggestSignalTypes()
|
||||
} else if field == "Type" {
|
||||
if list := suggestSignalTypes(); list != nil {
|
||||
items = append(items, list.Items...)
|
||||
}
|
||||
|
||||
} else {
|
||||
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
|
||||
}
|
||||
|
||||
@@ -1518,3 +1553,31 @@ func send(msg any) {
|
||||
body, _ := json.Marshal(msg)
|
||||
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}
|
||||
}
|
||||
|
||||
@@ -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 $")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user