diff --git a/handlers/aliases/analyzer/required_keys.go b/handlers/aliases/analyzer/required_keys.go index ea320a4..b7c0d32 100644 --- a/handlers/aliases/analyzer/required_keys.go +++ b/handlers/aliases/analyzer/required_keys.go @@ -9,7 +9,7 @@ import ( ers "errors" ) -var requiredFields = []string{ +var RequiredAliases = []string{ indexes.NormalizeKey("mailer-daemon"), indexes.NormalizeKey("hostmaster"), indexes.NormalizeKey("postmaster"), @@ -20,7 +20,7 @@ func analyzeContainsRequiredKeys( ) []common.LSPError { errors := make([]common.LSPError, 0) - for _, requiredField := range requiredFields { + for _, requiredField := range RequiredAliases { if _, found := d.Indexes.Keys[requiredField]; !found { errors = append(errors, common.LSPError{ Range: common.GlobalLocationRange, diff --git a/handlers/aliases/ast/aliases.go b/handlers/aliases/ast/aliases.go index 5f40b4d..7464edd 100644 --- a/handlers/aliases/ast/aliases.go +++ b/handlers/aliases/ast/aliases.go @@ -35,6 +35,7 @@ type AliasEntry struct { } type AliasesParser struct { + // uint32 -> *AliasEntry Aliases *treemap.Map CommentLines map[uint32]struct{} } diff --git a/handlers/aliases/ast/values.go b/handlers/aliases/ast/values.go index ed6ab59..6d4ab64 100644 --- a/handlers/aliases/ast/values.go +++ b/handlers/aliases/ast/values.go @@ -8,10 +8,15 @@ import ( ) type AliasValueInterface interface { + GetAliasValue() AliasValue FetchCompletions(line string, cursor uint32) []protocol.CompletionItem CheckIsValid() []*docvalues.InvalidValue } +func (a AliasValue) GetAliasValue() AliasValue { + return a +} + func (a AliasValue) FetchCompletions(line string, cursor uint32) []protocol.CompletionItem { return nil } diff --git a/handlers/aliases/handlers/completions.go b/handlers/aliases/handlers/completions.go new file mode 100644 index 0000000..f05bff1 --- /dev/null +++ b/handlers/aliases/handlers/completions.go @@ -0,0 +1,56 @@ +package handlers + +import ( + "config-lsp/handlers/aliases/analyzer" + "config-lsp/handlers/aliases/ast" + "config-lsp/handlers/aliases/indexes" + "fmt" + + protocol "github.com/tliron/glsp/protocol_3_16" +) + +func GetAliasesCompletions( + i *indexes.AliasesIndexes, +) []protocol.CompletionItem { + completions := make([]protocol.CompletionItem, 0) + aliases := analyzer.RequiredAliases + + kind := protocol.CompletionItemKindValue + + for _, alias := range aliases { + if i != nil { + if _, found := i.Keys[alias]; found { + continue + } + } + + text := fmt.Sprintf("%s: ", alias) + completions = append(completions, protocol.CompletionItem{ + Label: alias, + Kind: &kind, + InsertText: &text, + Documentation: "This alias is required by the aliases file", + }) + } + + return completions +} + +func GetCompletionsForEntry( + cursor uint32, + entry *ast.AliasEntry, + i *indexes.AliasesIndexes, +) ([]protocol.CompletionItem, error) { + completions := make([]protocol.CompletionItem, 0) + + if entry.Key == nil { + return completions, nil + } + + value := getValueAtCursor(cursor, entry) + + println(fmt.Sprintf("Value: %v", value)) + + return completions, nil +} + diff --git a/handlers/aliases/handlers/get-value.go b/handlers/aliases/handlers/get-value.go new file mode 100644 index 0000000..3c7c206 --- /dev/null +++ b/handlers/aliases/handlers/get-value.go @@ -0,0 +1,43 @@ +package handlers + +import ( + "config-lsp/handlers/aliases/ast" + "fmt" + "slices" +) + +func getValueAtCursor( + cursor uint32, + entry *ast.AliasEntry, +) *ast.AliasValueInterface { + if entry.Values == nil || len(entry.Values.Values) == 0 { + return nil + } + + println(fmt.Sprintf("Values: %v", entry.Values.Values)) + index, found := slices.BinarySearchFunc( + entry.Values.Values, + cursor, + func(entry ast.AliasValueInterface, pos uint32) int { + println(fmt.Sprintf("Entry: %v", entry)) + value := entry.(ast.AliasValue) + + if value.Location.End.Character > pos { + return 1 + } + + if value.Location.Start.Character < pos { + return -1 + } + + return 0 + }, + ) + + if !found { + return nil + } + + return &entry.Values.Values[index] +} + diff --git a/handlers/aliases/lsp/text-document-completion.go b/handlers/aliases/lsp/text-document-completion.go index 8c0754b..af328c9 100644 --- a/handlers/aliases/lsp/text-document-completion.go +++ b/handlers/aliases/lsp/text-document-completion.go @@ -1,12 +1,34 @@ package lsp import ( + "config-lsp/handlers/aliases" + "config-lsp/handlers/aliases/ast" + "config-lsp/handlers/aliases/handlers" + "github.com/tliron/glsp" protocol "github.com/tliron/glsp/protocol_3_16" ) func TextDocumentCompletion(context *glsp.Context, params *protocol.CompletionParams) (any, error) { - // p := documentParserMap[params.TextDocument.URI] + d := aliases.DocumentParserMap[params.TextDocument.URI] + cursor := params.Position.Character + line := params.Position.Line - return nil, nil + if _, found := d.Parser.CommentLines[line]; found { + return nil, nil + } + + rawEntry, found := d.Parser.Aliases.Get(line) + entry := rawEntry.(*ast.AliasEntry) + + if !found { + // For the key there are no completions available + return handlers.GetAliasesCompletions(d.Indexes), nil + } + + return handlers.GetCompletionsForEntry( + cursor, + entry, + d.Indexes, + ) } diff --git a/handlers/aliases/shared.go b/handlers/aliases/shared.go index b47d360..ec1e83d 100644 --- a/handlers/aliases/shared.go +++ b/handlers/aliases/shared.go @@ -13,3 +13,4 @@ type AliasesDocument struct { } var DocumentParserMap = map[protocol.DocumentUri]*AliasesDocument{} +