mirror of
https://github.com/Myzel394/config-lsp.git
synced 2025-06-19 07:25:27 +02:00
feat(aliases): Add support for renaming
This commit is contained in:
parent
654675524c
commit
d56eef43bf
@ -23,7 +23,7 @@ func GetDefinitionLocationForValue(
|
||||
return []protocol.Location{
|
||||
{
|
||||
URI: params.TextDocument.URI,
|
||||
Range: entry.Location.ToLSPRange(),
|
||||
Range: entry.Key.Location.ToLSPRange(),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
33
handlers/aliases/handlers/rename.go
Normal file
33
handlers/aliases/handlers/rename.go
Normal file
@ -0,0 +1,33 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"config-lsp/handlers/aliases/ast"
|
||||
"config-lsp/handlers/aliases/indexes"
|
||||
|
||||
protocol "github.com/tliron/glsp/protocol_3_16"
|
||||
)
|
||||
|
||||
func RenameAlias(
|
||||
i indexes.AliasesIndexes,
|
||||
oldEntry *ast.AliasEntry,
|
||||
newName string,
|
||||
) []protocol.TextEdit {
|
||||
occurrences := i.UserOccurrences[indexes.NormalizeKey(oldEntry.Key.Value)]
|
||||
changes := make([]protocol.TextEdit, 0, len(occurrences))
|
||||
|
||||
// Own rename
|
||||
changes = append(changes, protocol.TextEdit{
|
||||
Range: oldEntry.Key.Location.ToLSPRange(),
|
||||
NewText: newName,
|
||||
})
|
||||
|
||||
// Other AliasValueUser occurrences
|
||||
for _, value := range occurrences {
|
||||
changes = append(changes, protocol.TextEdit{
|
||||
Range: value.Location.ToLSPRange(),
|
||||
NewText: newName,
|
||||
})
|
||||
}
|
||||
|
||||
return changes
|
||||
}
|
48
handlers/aliases/handlers/rename_test.go
Normal file
48
handlers/aliases/handlers/rename_test.go
Normal file
@ -0,0 +1,48 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"config-lsp/handlers/aliases/ast"
|
||||
"config-lsp/handlers/aliases/indexes"
|
||||
"config-lsp/utils"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestComplexExample(
|
||||
t *testing.T,
|
||||
) {
|
||||
input := utils.Dedent(`
|
||||
alice: alice
|
||||
bob: root
|
||||
support: alice, bob
|
||||
`)
|
||||
parser := ast.NewAliasesParser()
|
||||
errors := parser.Parse(input)
|
||||
|
||||
if len(errors) > 0 {
|
||||
t.Fatalf("Unexpected errors: %v", errors)
|
||||
}
|
||||
|
||||
i, errors := indexes.CreateIndexes(parser)
|
||||
|
||||
if len(errors) > 0 {
|
||||
t.Fatalf("Expected no errors, but got: %v", errors)
|
||||
}
|
||||
|
||||
edits := RenameAlias(i, i.Keys["alice"], "amelie")
|
||||
|
||||
if !(len(edits) == 3) {
|
||||
t.Errorf("Expected 2 edits, but got %v", len(edits))
|
||||
}
|
||||
|
||||
if !(edits[0].Range.Start.Line == 0 && edits[0].Range.Start.Character == 0 && edits[0].Range.End.Line == 0 && edits[0].Range.End.Character == 5) {
|
||||
t.Errorf("Unexpected edit: %v", edits[0])
|
||||
}
|
||||
|
||||
if !(edits[1].Range.Start.Line == 0 && edits[1].Range.Start.Character == 7 && edits[1].Range.End.Line == 0 && edits[1].Range.End.Character == 12) {
|
||||
t.Errorf("Unexpected edit: %v", edits[1])
|
||||
}
|
||||
|
||||
if !(edits[2].Range.Start.Line == 2 && edits[2].Range.Start.Character == 9 && edits[2].Range.End.Line == 2 && edits[2].Range.End.Character == 14) {
|
||||
t.Errorf("Unexpected edit: %v", edits[2])
|
||||
}
|
||||
}
|
@ -8,7 +8,8 @@ import (
|
||||
)
|
||||
|
||||
type AliasesIndexes struct {
|
||||
Keys map[string]*ast.AliasKey
|
||||
Keys map[string]*ast.AliasEntry
|
||||
UserOccurrences map[string][]*ast.AliasValueUser
|
||||
}
|
||||
|
||||
func NormalizeKey(key string) string {
|
||||
@ -18,7 +19,8 @@ func NormalizeKey(key string) string {
|
||||
func CreateIndexes(parser ast.AliasesParser) (AliasesIndexes, []common.LSPError) {
|
||||
errors := make([]common.LSPError, 0)
|
||||
indexes := &AliasesIndexes{
|
||||
Keys: make(map[string]*ast.AliasKey),
|
||||
Keys: make(map[string]*ast.AliasEntry),
|
||||
UserOccurrences: make(map[string][]*ast.AliasValueUser),
|
||||
}
|
||||
|
||||
it := parser.Aliases.Iterator()
|
||||
@ -26,6 +28,20 @@ func CreateIndexes(parser ast.AliasesParser) (AliasesIndexes, []common.LSPError)
|
||||
for it.Next() {
|
||||
entry := it.Value().(*ast.AliasEntry)
|
||||
|
||||
if entry.Values != nil {
|
||||
for _, value := range entry.Values.Values {
|
||||
switch value.(type) {
|
||||
case ast.AliasValueUser:
|
||||
userValue := value.(ast.AliasValueUser)
|
||||
|
||||
indexes.UserOccurrences[userValue.Value] = append(
|
||||
indexes.UserOccurrences[userValue.Value],
|
||||
&userValue,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if entry.Key == nil || entry.Key.Value == "" {
|
||||
continue
|
||||
}
|
||||
@ -44,7 +60,7 @@ func CreateIndexes(parser ast.AliasesParser) (AliasesIndexes, []common.LSPError)
|
||||
continue
|
||||
}
|
||||
|
||||
indexes.Keys[normalizedAlias] = entry.Key
|
||||
indexes.Keys[normalizedAlias] = entry
|
||||
}
|
||||
|
||||
return *indexes, errors
|
||||
|
49
handlers/aliases/indexes/indexes_test.go
Normal file
49
handlers/aliases/indexes/indexes_test.go
Normal file
@ -0,0 +1,49 @@
|
||||
package indexes
|
||||
|
||||
import (
|
||||
"config-lsp/handlers/aliases/ast"
|
||||
"config-lsp/utils"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestComplexExample(
|
||||
t *testing.T,
|
||||
) {
|
||||
input := utils.Dedent(`
|
||||
postmaster: alice, bob
|
||||
alice: root
|
||||
bob: root
|
||||
`)
|
||||
parser := ast.NewAliasesParser()
|
||||
errors := parser.Parse(input)
|
||||
|
||||
if len(errors) > 0 {
|
||||
t.Fatalf("Unexpected errors: %v", errors)
|
||||
}
|
||||
|
||||
indexes, errors := CreateIndexes(parser)
|
||||
|
||||
if len(errors) > 0 {
|
||||
t.Fatalf("Expected no errors, but got: %v", errors)
|
||||
}
|
||||
|
||||
if !(len(indexes.Keys) == 3) {
|
||||
t.Errorf("Expected 3 keys, but got %v", len(indexes.Keys))
|
||||
}
|
||||
|
||||
if !(len(indexes.UserOccurrences) == 3) {
|
||||
t.Errorf("Expected 3 user occurrences, but got %v", len(indexes.UserOccurrences))
|
||||
}
|
||||
|
||||
if !(len(indexes.UserOccurrences["root"]) == 2) {
|
||||
t.Errorf("Expected 2 occurrences of root, but got %v", len(indexes.UserOccurrences["root"]))
|
||||
}
|
||||
|
||||
if !(len(indexes.UserOccurrences["alice"]) == 1) {
|
||||
t.Errorf("Expected 1 occurrence of alice, but got %v", len(indexes.UserOccurrences["alice"]))
|
||||
}
|
||||
|
||||
if !(len(indexes.UserOccurrences["bob"]) == 1) {
|
||||
t.Errorf("Expected 1 occurrence of bob, but got %v", len(indexes.UserOccurrences["bob"]))
|
||||
}
|
||||
}
|
60
handlers/aliases/lsp/text-document-rename.go
Normal file
60
handlers/aliases/lsp/text-document-rename.go
Normal file
@ -0,0 +1,60 @@
|
||||
package lsp
|
||||
|
||||
import (
|
||||
"config-lsp/handlers/aliases"
|
||||
"config-lsp/handlers/aliases/ast"
|
||||
"config-lsp/handlers/aliases/handlers"
|
||||
"config-lsp/handlers/aliases/indexes"
|
||||
|
||||
"github.com/tliron/glsp"
|
||||
protocol "github.com/tliron/glsp/protocol_3_16"
|
||||
)
|
||||
|
||||
func TextDocumentRename(context *glsp.Context, params *protocol.RenameParams) (*protocol.WorkspaceEdit, 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 character >= entry.Key.Location.Start.Character && character <= entry.Key.Location.End.Character {
|
||||
changes := handlers.RenameAlias(*d.Indexes, entry, params.NewName)
|
||||
|
||||
return &protocol.WorkspaceEdit{
|
||||
Changes: map[protocol.DocumentUri][]protocol.TextEdit{
|
||||
params.TextDocument.URI: changes,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
switch (*rawValue).(type) {
|
||||
case ast.AliasValueUser:
|
||||
userValue := (*rawValue).(ast.AliasValueUser)
|
||||
|
||||
definitionEntry := d.Indexes.Keys[indexes.NormalizeKey(userValue.Value)]
|
||||
|
||||
changes := handlers.RenameAlias(*d.Indexes, definitionEntry, params.NewName)
|
||||
|
||||
return &protocol.WorkspaceEdit{
|
||||
Changes: map[protocol.DocumentUri][]protocol.TextEdit{
|
||||
params.TextDocument.URI: changes,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
@ -29,6 +29,7 @@ func SetUpRootHandler() {
|
||||
TextDocumentCodeAction: TextDocumentCodeAction,
|
||||
TextDocumentDefinition: TextDocumentDefinition,
|
||||
WorkspaceExecuteCommand: WorkspaceExecuteCommand,
|
||||
TextDocumentRename: TextDocumentRename,
|
||||
}
|
||||
|
||||
server := server.NewServer(&lspHandler, lsName, false)
|
||||
|
36
root-handler/text-document-rename.go
Normal file
36
root-handler/text-document-rename.go
Normal file
@ -0,0 +1,36 @@
|
||||
package roothandler
|
||||
|
||||
import (
|
||||
aliases "config-lsp/handlers/aliases/lsp"
|
||||
"github.com/tliron/glsp"
|
||||
protocol "github.com/tliron/glsp/protocol_3_16"
|
||||
)
|
||||
|
||||
func TextDocumentRename(context *glsp.Context, params *protocol.RenameParams) (*protocol.WorkspaceEdit, 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.TextDocumentRename(context, params)
|
||||
}
|
||||
|
||||
panic("root-handler/TextDocumentRename: unexpected language" + *language)
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user