feat(aliases): Add support for textDocument/definition

This commit is contained in:
Myzel394 2024-09-07 15:45:52 +02:00
parent c5d9634ab3
commit 654675524c
No known key found for this signature in database
GPG Key ID: DEC4AAB876F73185
6 changed files with 176 additions and 3 deletions

View File

@ -10,6 +10,7 @@ type PasswdInfo struct {
UID string
GID string
HomePath string
Line uint32
}
var _cachedPasswdInfo []PasswdInfo
@ -28,7 +29,7 @@ func FetchPasswdInfo() ([]PasswdInfo, error) {
lines := strings.Split(string(readBytes), "\n")
infos := make([]PasswdInfo, 0)
for _, line := range lines {
for lineNumber, line := range lines {
splitted := strings.Split(line, ":")
if len(splitted) < 6 {
@ -40,6 +41,7 @@ func FetchPasswdInfo() ([]PasswdInfo, error) {
UID: splitted[2],
GID: splitted[3],
HomePath: splitted[5],
Line: uint32(lineNumber),
}
infos = append(infos, info)

View File

@ -164,7 +164,7 @@ func getUsersFromEntry(
switch (value).(type) {
case ast.AliasValueUser:
userValue := value.(ast.AliasValueUser)
users[indexes.NormalizeKey(userValue.Value)] = struct{}{}
}
}
@ -172,4 +172,3 @@ func getUsersFromEntry(
return users
}

View File

@ -0,0 +1,94 @@
package handlers
import (
"config-lsp/common"
"config-lsp/handlers/aliases/ast"
"config-lsp/handlers/aliases/indexes"
"config-lsp/utils"
protocol "github.com/tliron/glsp/protocol_3_16"
)
func GetDefinitionLocationForValue(
i indexes.AliasesIndexes,
value ast.AliasValueInterface,
params *protocol.DefinitionParams,
) []protocol.Location {
switch value.(type) {
case ast.AliasValueUser:
userValue := value.(ast.AliasValueUser)
// Own defined alias
if entry, found := i.Keys[indexes.NormalizeKey(userValue.Value)]; found {
return []protocol.Location{
{
URI: params.TextDocument.URI,
Range: entry.Location.ToLSPRange(),
},
}
}
// System user
systemUsers, _ := getSystemUserMap()
if user, found := systemUsers[userValue.Value]; found {
return []protocol.Location{
{
URI: "file:///etc/passwd",
Range: protocol.Range{
Start: protocol.Position{
Line: user.Line,
Character: 0,
},
End: protocol.Position{
Line: user.Line,
Character: uint32(len(user.Name)),
},
},
},
}
}
case ast.AliasValueFile:
fileValue := value.(ast.AliasValueFile)
path := string(fileValue.Path)
if utils.DoesPathExist(path) {
return []protocol.Location{
{
URI: "file://" + path,
},
}
}
case ast.AliasValueInclude:
includeValue := value.(ast.AliasValueInclude)
if includeValue.Path != nil {
path := string(includeValue.Path.Path)
if utils.DoesPathExist(path) {
return []protocol.Location{
{
URI: "file://" + path,
},
}
}
}
}
return nil
}
func getSystemUserMap() (map[string]common.PasswdInfo, error) {
users, err := common.FetchPasswdInfo()
if err != nil {
return nil, err
}
userMap := make(map[string]common.PasswdInfo)
for _, user := range users {
userMap[user.Name] = user
}
return userMap, nil
}

View File

@ -0,0 +1,40 @@
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 TextDocumentDefinition(context *glsp.Context, params *protocol.DefinitionParams) ([]protocol.Location, error) {
d := aliases.DocumentParserMap[params.TextDocument.URI]
character := params.Position.Character
line := params.Position.Line
rawEntry, found := d.Parser.Aliases.Get(line)
if !found {
return nil, nil
}
entry := rawEntry.(*ast.AliasEntry)
if entry.Values != nil && character >= entry.Values.Location.Start.Character && character <= entry.Values.Location.End.Character {
rawValue := handlers.GetValueAtCursor(character, entry)
if rawValue == nil {
return nil, nil
}
return handlers.GetDefinitionLocationForValue(
*d.Indexes,
*rawValue,
params,
), nil
}
return nil, nil
}

View File

@ -27,6 +27,7 @@ func SetUpRootHandler() {
TextDocumentHover: TextDocumentHover,
TextDocumentDidClose: TextDocumentDidClose,
TextDocumentCodeAction: TextDocumentCodeAction,
TextDocumentDefinition: TextDocumentDefinition,
WorkspaceExecuteCommand: WorkspaceExecuteCommand,
}

View File

@ -0,0 +1,37 @@
package roothandler
import (
aliases "config-lsp/handlers/aliases/lsp"
"github.com/tliron/glsp"
protocol "github.com/tliron/glsp/protocol_3_16"
)
func TextDocumentDefinition(context *glsp.Context, params *protocol.DefinitionParams) (any, error) {
language := rootHandler.GetLanguageForDocument(params.TextDocument.URI)
if language == nil {
showParseError(
context,
params.TextDocument.URI,
undetectableError,
)
return nil, undetectableError.Err
}
switch *language {
case LanguageHosts:
return nil, nil
case LanguageSSHDConfig:
return nil, nil
case LanguageFstab:
return nil, nil
case LanguageWireguard:
return nil, nil
case LanguageAliases:
return aliases.TextDocumentDefinition(context, params)
}
panic("root-handler/TextDocumentDefinition: unexpected language" + *language)
}