From 14cba1b530e3f5e9726e0bbd005ac78011b5b7ea Mon Sep 17 00:00:00 2001 From: Martino Ferrari Date: Fri, 23 Jan 2026 14:01:26 +0100 Subject: [PATCH] Working --- internal/lsp/server.go | 45 +++++++++++++++++++++++++++++++-------- internal/parser/parser.go | 1 + internal/schema/marte.cue | 4 ++-- 3 files changed, 39 insertions(+), 11 deletions(-) diff --git a/internal/lsp/server.go b/internal/lsp/server.go index 51ccf01..c548d52 100644 --- a/internal/lsp/server.go +++ b/internal/lsp/server.go @@ -7,6 +7,7 @@ import ( "fmt" "io" "os" + "regexp" "strings" "github.com/marte-community/marte-dev-tools/internal/formatter" @@ -575,8 +576,16 @@ func handleCompletion(params CompletionParams) *CompletionList { // Case 1: Assigning a value (Ends with "=" or "= ") if strings.Contains(prefix, "=") { - parts := strings.Split(prefix, "=") - key := strings.TrimSpace(parts[len(parts)-2]) + lastIdx := strings.LastIndex(prefix, "=") + beforeEqual := prefix[:lastIdx] + + // Find the last identifier before '=' + key := "" + re := regexp.MustCompile(`[a-zA-Z][a-zA-Z0-9_\-]*`) + matches := re.FindAllString(beforeEqual, -1) + if len(matches) > 0 { + key = matches[len(matches)-1] + } if key == "Class" { return suggestClasses() @@ -584,7 +593,7 @@ func handleCompletion(params CompletionParams) *CompletionList { container := tree.GetNodeContaining(path, parser.Position{Line: params.Position.Line + 1, Column: col + 1}) if container != nil { - return suggestFieldValues(container, key) + return suggestFieldValues(container, key, path) } return nil } @@ -700,19 +709,31 @@ func suggestFields(container *index.ProjectNode) *CompletionList { return &CompletionList{Items: items} } -func suggestFieldValues(container *index.ProjectNode, field string) *CompletionList { +func suggestFieldValues(container *index.ProjectNode, field string, path string) *CompletionList { + var root *index.ProjectNode + if iso, ok := tree.IsolatedFiles[path]; ok { + root = iso + } else { + root = tree.Root + } + if field == "DataSource" { - return suggestObjects("DataSource") + return suggestObjects(root, "DataSource") } if field == "Functions" { - return suggestObjects("GAM") + return suggestObjects(root, "GAM") } return nil } -func suggestObjects(filter string) *CompletionList { +func suggestObjects(root *index.ProjectNode, filter string) *CompletionList { + if root == nil { + return nil + } var items []CompletionItem - tree.Walk(func(node *index.ProjectNode) { + + var walk func(*index.ProjectNode) + walk = func(node *index.ProjectNode) { match := false if filter == "GAM" { if isGAM(node) { @@ -731,7 +752,13 @@ func suggestObjects(filter string) *CompletionList { Detail: node.Metadata["Class"], }) } - }) + + for _, child := range node.Children { + walk(child) + } + } + + walk(root) return &CompletionList{Items: items} } diff --git a/internal/parser/parser.go b/internal/parser/parser.go index f464dd7..6b296f2 100644 --- a/internal/parser/parser.go +++ b/internal/parser/parser.go @@ -207,6 +207,7 @@ func (p *Parser) parseSubnode() (Subnode, bool) { } if t.Type == TokenEOF { p.addError(t.Position, "unexpected EOF, expected }") + sub.EndPosition = t.Position return sub, false } def, ok := p.parseDefinition() diff --git a/internal/schema/marte.cue b/internal/schema/marte.cue index ec0a598..8220268 100644 --- a/internal/schema/marte.cue +++ b/internal/schema/marte.cue @@ -277,12 +277,12 @@ package schema } } -// Definition for any Object. +// Definition for any Object. // It must have a Class field. // Based on Class, it validates against #Classes. #Object: { Class: string - // Allow any other field by default (extensibility), + // Allow any other field by default (extensibility), // unless #Classes definition is closed. // We allow open structs now. ...