mirror of
https://github.com/Myzel394/config-lsp.git
synced 2025-06-18 15:05:28 +02:00
refactor(server): Refactor Wireguard config; Improve completions; Improve code actions
Signed-off-by: Myzel394 <github.7a2op@simplelogin.co>
This commit is contained in:
parent
a0dca94b9d
commit
ff9b5db18a
@ -55,7 +55,7 @@ func analyzeStructureIsValid(ctx *analyzerContext) {
|
||||
if property.Value == nil || property.Value.Value == "" {
|
||||
ctx.diagnostics = append(ctx.diagnostics, protocol.Diagnostic{
|
||||
Message: "This property is missing a value",
|
||||
Range: property.Value.ToLSPRange(),
|
||||
Range: property.ToLSPRange(),
|
||||
Severity: &common.SeverityError,
|
||||
})
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package ast
|
||||
|
||||
import (
|
||||
"config-lsp/utils"
|
||||
"slices"
|
||||
)
|
||||
|
||||
@ -47,3 +48,23 @@ func (s *WGSection) FindFirstPropertyByName(name string) *WGProperty {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *WGSection) FindPropertyByName(name string) *WGProperty {
|
||||
for _, property := range s.Properties {
|
||||
if property.Key.Name == name {
|
||||
return property
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *WGSection) GetLastProperty() *WGProperty {
|
||||
if len(s.Properties) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
lastLine := utils.FindBiggestKey(s.Properties)
|
||||
|
||||
return s.Properties[lastLine]
|
||||
}
|
||||
|
@ -1,9 +1,10 @@
|
||||
package handlers
|
||||
|
||||
/*
|
||||
import (
|
||||
"config-lsp/handlers/wireguard"
|
||||
"config-lsp/handlers/wireguard/ast"
|
||||
wgcommands "config-lsp/handlers/wireguard/commands"
|
||||
|
||||
protocol "github.com/tliron/glsp/protocol_3_16"
|
||||
)
|
||||
|
||||
@ -12,7 +13,6 @@ type CodeActionName string
|
||||
const (
|
||||
CodeActionGeneratePrivateKey CodeActionName = "generatePrivateKey"
|
||||
CodeActionGeneratePresharedKey CodeActionName = "generatePresharedKey"
|
||||
CodeActionAddKeepalive CodeActionName = "addKeepalive"
|
||||
)
|
||||
|
||||
type CodeAction interface {
|
||||
@ -33,14 +33,15 @@ func CodeActionGeneratePrivateKeyArgsFromArguments(arguments map[string]any) Cod
|
||||
}
|
||||
}
|
||||
|
||||
func (args CodeActionGeneratePrivateKeyArgs) RunCommand(p *ast.WGConfig) (*protocol.ApplyWorkspaceEditParams, error) {
|
||||
func (args CodeActionGeneratePrivateKeyArgs) RunCommand(d *wireguard.WGDocument) (*protocol.ApplyWorkspaceEditParams, error) {
|
||||
privateKey, err := wgcommands.CreateNewPrivateKey()
|
||||
|
||||
if err != nil {
|
||||
return &protocol.ApplyWorkspaceEditParams{}, err
|
||||
}
|
||||
|
||||
section, property := p.GetPropertyByLine(args.Line)
|
||||
section := d.Config.FindSectionByLine(args.Line)
|
||||
property := d.Config.FindPropertyByLine(args.Line)
|
||||
|
||||
if section == nil || property == nil {
|
||||
return nil, nil
|
||||
@ -54,7 +55,16 @@ func (args CodeActionGeneratePrivateKeyArgs) RunCommand(p *ast.WGConfig) (*proto
|
||||
args.URI: {
|
||||
{
|
||||
NewText: " " + privateKey,
|
||||
Range: property.GetInsertRange(args.Line),
|
||||
Range: protocol.Range{
|
||||
Start: protocol.Position{
|
||||
Line: property.End.Line,
|
||||
Character: property.End.Character,
|
||||
},
|
||||
End: protocol.Position{
|
||||
Line: property.End.Line,
|
||||
Character: property.End.Character,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -74,14 +84,15 @@ func CodeActionGeneratePresharedKeyArgsFromArguments(arguments map[string]any) C
|
||||
}
|
||||
}
|
||||
|
||||
func (args CodeActionGeneratePresharedKeyArgs) RunCommand(p *ast.WGConfig) (*protocol.ApplyWorkspaceEditParams, error) {
|
||||
func (args CodeActionGeneratePresharedKeyArgs) RunCommand(d *wireguard.WGDocument) (*protocol.ApplyWorkspaceEditParams, error) {
|
||||
presharedKey, err := wgcommands.CreatePresharedKey()
|
||||
|
||||
if err != nil {
|
||||
return &protocol.ApplyWorkspaceEditParams{}, err
|
||||
}
|
||||
|
||||
section, property := p.GetPropertyByLine(args.Line)
|
||||
section := d.Config.FindSectionByLine(args.Line)
|
||||
property := d.Config.FindPropertyByLine(args.Line)
|
||||
|
||||
if section == nil || property == nil {
|
||||
return nil, nil
|
||||
@ -95,45 +106,14 @@ func (args CodeActionGeneratePresharedKeyArgs) RunCommand(p *ast.WGConfig) (*pro
|
||||
args.URI: {
|
||||
{
|
||||
NewText: " " + presharedKey,
|
||||
Range: property.GetInsertRange(args.Line),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
type CodeActionAddKeepaliveArgs struct {
|
||||
URI protocol.DocumentUri
|
||||
SectionIndex uint32
|
||||
}
|
||||
|
||||
func CodeActionAddKeepaliveArgsFromArguments(arguments map[string]any) CodeActionAddKeepaliveArgs {
|
||||
return CodeActionAddKeepaliveArgs{
|
||||
URI: arguments["URI"].(protocol.DocumentUri),
|
||||
SectionIndex: uint32(arguments["SectionIndex"].(float64)),
|
||||
}
|
||||
}
|
||||
|
||||
func (args CodeActionAddKeepaliveArgs) RunCommand(p *ast.WGConfig) (*protocol.ApplyWorkspaceEditParams, error) {
|
||||
section := p.Sections[args.SectionIndex]
|
||||
|
||||
label := "Add PersistentKeepalive"
|
||||
return &protocol.ApplyWorkspaceEditParams{
|
||||
Label: &label,
|
||||
Edit: protocol.WorkspaceEdit{
|
||||
Changes: map[protocol.DocumentUri][]protocol.TextEdit{
|
||||
args.URI: {
|
||||
{
|
||||
NewText: "PersistentKeepalive = 25\n",
|
||||
Range: protocol.Range{
|
||||
Start: protocol.Position{
|
||||
Line: section.EndLine + 1,
|
||||
Character: 0,
|
||||
Line: property.End.Line,
|
||||
Character: property.End.Character,
|
||||
},
|
||||
End: protocol.Position{
|
||||
Line: section.EndLine + 1,
|
||||
Character: 0,
|
||||
Line: property.End.Line,
|
||||
Character: property.End.Character,
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -142,4 +122,4 @@ func (args CodeActionAddKeepaliveArgs) RunCommand(p *ast.WGConfig) (*protocol.Ap
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
*/
|
||||
|
||||
|
@ -86,13 +86,20 @@ func getPropertyCompletions(
|
||||
Address = 10.|
|
||||
*/
|
||||
|
||||
if property == nil || property.Separator == nil {
|
||||
currentLine := params.Position.Line
|
||||
position := common.LSPCharacterAsCursorPosition(params.Position.Character)
|
||||
|
||||
// Special case, key defined but separator missing
|
||||
if property != nil && property.Separator == nil && !property.Key.ContainsPosition(position) {
|
||||
return getKeyCompletions(section, true, currentLine), nil
|
||||
}
|
||||
|
||||
if property == nil || property.Separator == nil || property.Key.ContainsPosition(position) {
|
||||
// First scenario
|
||||
return getKeyCompletions(section), nil
|
||||
return getKeyCompletions(section, false, currentLine), nil
|
||||
}
|
||||
|
||||
// Check if the cursor it outside the value
|
||||
position := common.LSPCharacterAsCursorPosition(params.Position.Character)
|
||||
if property.Value != nil && property.Value.IsPositionAfterEnd(position) {
|
||||
// Then we don't show anything
|
||||
return nil, nil
|
||||
@ -104,45 +111,55 @@ func getPropertyCompletions(
|
||||
|
||||
func getKeyCompletions(
|
||||
section ast.WGSection,
|
||||
onlySeparator bool,
|
||||
currentLine uint32,
|
||||
) []protocol.CompletionItem {
|
||||
options := make(map[string]docvalues.DocumentationValue)
|
||||
allowedDuplicatedFields := make(map[string]struct{})
|
||||
|
||||
switch section.Header.Name {
|
||||
case "Interface":
|
||||
maps.Copy(options, fields.InterfaceOptions)
|
||||
|
||||
// Remove existing, non-duplicate options
|
||||
for _, property := range section.Properties {
|
||||
if _, found := fields.InterfaceAllowedDuplicateFields[property.Key.Name]; found {
|
||||
continue
|
||||
}
|
||||
|
||||
delete(options, property.Key.Name)
|
||||
}
|
||||
allowedDuplicatedFields = fields.InterfaceAllowedDuplicateFields
|
||||
case "Peer":
|
||||
maps.Copy(options, fields.PeerOptions)
|
||||
allowedDuplicatedFields = fields.PeerAllowedDuplicateFields
|
||||
}
|
||||
|
||||
// Remove existing, non-duplicate options
|
||||
for _, property := range section.Properties {
|
||||
if _, found := fields.PeerAllowedDuplicateFields[property.Key.Name]; found {
|
||||
if _, found := allowedDuplicatedFields[property.Key.Name]; found {
|
||||
continue
|
||||
}
|
||||
|
||||
if property.Key.Start.Line == currentLine {
|
||||
// The user is currently typing the key, thus we should suggest it
|
||||
continue
|
||||
}
|
||||
|
||||
delete(options, property.Key.Name)
|
||||
}
|
||||
}
|
||||
|
||||
kind := protocol.CompletionItemKindField
|
||||
|
||||
return utils.MapMapToSlice(
|
||||
options,
|
||||
func(optionName string, value docvalues.DocumentationValue) protocol.CompletionItem {
|
||||
insertText := optionName + " = "
|
||||
func(rawOptionName string, value docvalues.DocumentationValue) protocol.CompletionItem {
|
||||
var label string
|
||||
var insertText string
|
||||
|
||||
if onlySeparator {
|
||||
label = rawOptionName + " = "
|
||||
insertText = "= "
|
||||
} else {
|
||||
label = rawOptionName
|
||||
insertText = rawOptionName + " = "
|
||||
}
|
||||
|
||||
return protocol.CompletionItem{
|
||||
Kind: &kind,
|
||||
Documentation: value.Documentation,
|
||||
Label: optionName,
|
||||
Label: label,
|
||||
InsertText: &insertText,
|
||||
}
|
||||
},
|
||||
|
@ -1,37 +1,52 @@
|
||||
package handlers
|
||||
|
||||
/*
|
||||
import (
|
||||
"config-lsp/handlers/wireguard/ast"
|
||||
"config-lsp/handlers/wireguard"
|
||||
"config-lsp/handlers/wireguard/commands"
|
||||
|
||||
protocol "github.com/tliron/glsp/protocol_3_16"
|
||||
)
|
||||
|
||||
func GetKeepaliveCodeActions(
|
||||
p *ast.WGConfig,
|
||||
d *wireguard.WGDocument,
|
||||
params *protocol.CodeActionParams,
|
||||
) []protocol.CodeAction {
|
||||
line := params.Range.Start.Line
|
||||
|
||||
for index, section := range p.Sections {
|
||||
if section.StartLine >= line && line <= section.EndLine && section.Header != nil && *section.Header == "Peer" {
|
||||
if section.ExistsProperty("Endpoint") && !section.ExistsProperty("PersistentKeepalive") {
|
||||
commandID := "wireguard." + CodeActionAddKeepalive
|
||||
command := protocol.Command{
|
||||
Title: "Add PersistentKeepalive",
|
||||
Command: string(commandID),
|
||||
Arguments: []any{
|
||||
CodeActionAddKeepaliveArgs{
|
||||
URI: params.TextDocument.URI,
|
||||
SectionIndex: uint32(index),
|
||||
},
|
||||
},
|
||||
for _, section := range d.Indexes.SectionsByName["Peer"] {
|
||||
if section.Start.Line >= line && line <= section.End.Line {
|
||||
if section.FindPropertyByName("Endpoint") != nil && section.FindFirstPropertyByName("PersistentKeepalive") == nil {
|
||||
var insertionLine uint32
|
||||
lastProperty := section.GetLastProperty()
|
||||
|
||||
if lastProperty == nil {
|
||||
insertionLine = section.End.Line
|
||||
} else {
|
||||
insertionLine = lastProperty.End.Line + 1
|
||||
}
|
||||
|
||||
return []protocol.CodeAction{
|
||||
{
|
||||
Title: "Add PersistentKeepalive",
|
||||
Command: &command,
|
||||
Edit: &protocol.WorkspaceEdit{
|
||||
Changes: map[protocol.DocumentUri][]protocol.TextEdit{
|
||||
params.TextDocument.URI: {
|
||||
{
|
||||
Range: protocol.Range{
|
||||
Start: protocol.Position{
|
||||
Line: insertionLine,
|
||||
Character: 0,
|
||||
},
|
||||
End: protocol.Position{
|
||||
Line: insertionLine,
|
||||
Character: 0,
|
||||
},
|
||||
},
|
||||
NewText: "PersistentKeepalive = 25\n",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
@ -42,11 +57,17 @@ func GetKeepaliveCodeActions(
|
||||
}
|
||||
|
||||
func GetKeyGenerationCodeActions(
|
||||
p *ast.WGConfig,
|
||||
d *wireguard.WGDocument,
|
||||
params *protocol.CodeActionParams,
|
||||
) []protocol.CodeAction {
|
||||
if !wgcommands.AreWireguardToolsAvailable() {
|
||||
return nil
|
||||
}
|
||||
|
||||
line := params.Range.Start.Line
|
||||
section, property := p.GetPropertyByLine(line)
|
||||
|
||||
section := d.Config.FindSectionByLine(line)
|
||||
property := d.Config.FindPropertyByLine(line)
|
||||
|
||||
if section == nil || property == nil || property.Separator == nil {
|
||||
return nil
|
||||
@ -54,10 +75,6 @@ func GetKeyGenerationCodeActions(
|
||||
|
||||
switch property.Key.Name {
|
||||
case "PrivateKey":
|
||||
if !wgcommands.AreWireguardToolsAvailable() {
|
||||
return nil
|
||||
}
|
||||
|
||||
commandID := "wireguard." + CodeActionGeneratePrivateKey
|
||||
command := protocol.Command{
|
||||
Title: "Generate Private Key",
|
||||
@ -103,4 +120,3 @@ func GetKeyGenerationCodeActions(
|
||||
|
||||
return nil
|
||||
}
|
||||
*/
|
||||
|
@ -1,18 +1,20 @@
|
||||
package lsp
|
||||
|
||||
import (
|
||||
"config-lsp/handlers/wireguard"
|
||||
"config-lsp/handlers/wireguard/handlers"
|
||||
|
||||
"github.com/tliron/glsp"
|
||||
protocol "github.com/tliron/glsp/protocol_3_16"
|
||||
)
|
||||
|
||||
func TextDocumentCodeAction(context *glsp.Context, params *protocol.CodeActionParams) ([]protocol.CodeAction, error) {
|
||||
p := documentParserMap[params.TextDocument.URI]
|
||||
d := wireguard.DocumentParserMap[params.TextDocument.URI]
|
||||
|
||||
actions := make([]protocol.CodeAction, 0, 2)
|
||||
|
||||
actions = append(actions, handlers.GetKeyGenerationCodeActions(p, params)...)
|
||||
actions = append(actions, handlers.GetKeepaliveCodeActions(p, params)...)
|
||||
actions = append(actions, handlers.GetKeyGenerationCodeActions(d, params)...)
|
||||
actions = append(actions, handlers.GetKeepaliveCodeActions(d, params)...)
|
||||
|
||||
if len(actions) > 0 {
|
||||
return actions, nil
|
||||
|
@ -1,10 +1,6 @@
|
||||
package lsp
|
||||
|
||||
import (
|
||||
"config-lsp/handlers/wireguard/handlers"
|
||||
"config-lsp/handlers/wireguard/parser"
|
||||
"strings"
|
||||
|
||||
"github.com/tliron/glsp"
|
||||
protocol "github.com/tliron/glsp/protocol_3_16"
|
||||
)
|
||||
@ -13,6 +9,7 @@ func TextDocumentHover(
|
||||
context *glsp.Context,
|
||||
params *protocol.HoverParams,
|
||||
) (*protocol.Hover, error) {
|
||||
/*
|
||||
p := documentParserMap[params.TextDocument.URI]
|
||||
|
||||
switch p.GetTypeByLine(params.Position.Line) {
|
||||
@ -37,6 +34,7 @@ func TextDocumentHover(
|
||||
}
|
||||
return &hover, nil
|
||||
}
|
||||
*/
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package lsp
|
||||
|
||||
import (
|
||||
"config-lsp/handlers/wireguard"
|
||||
"config-lsp/handlers/wireguard/handlers"
|
||||
"strings"
|
||||
|
||||
@ -15,21 +16,15 @@ func WorkspaceExecuteCommand(context *glsp.Context, params *protocol.ExecuteComm
|
||||
case string(handlers.CodeActionGeneratePrivateKey):
|
||||
args := handlers.CodeActionGeneratePrivateKeyArgsFromArguments(params.Arguments[0].(map[string]any))
|
||||
|
||||
p := documentParserMap[args.URI]
|
||||
d := wireguard.DocumentParserMap[args.URI]
|
||||
|
||||
return args.RunCommand(p)
|
||||
return args.RunCommand(d)
|
||||
case string(handlers.CodeActionGeneratePresharedKey):
|
||||
args := handlers.CodeActionGeneratePresharedKeyArgsFromArguments(params.Arguments[0].(map[string]any))
|
||||
|
||||
parser := documentParserMap[args.URI]
|
||||
d := wireguard.DocumentParserMap[args.URI]
|
||||
|
||||
return args.RunCommand(parser)
|
||||
case string(handlers.CodeActionAddKeepalive):
|
||||
args := handlers.CodeActionAddKeepaliveArgsFromArguments(params.Arguments[0].(map[string]any))
|
||||
|
||||
p := documentParserMap[args.URI]
|
||||
|
||||
return args.RunCommand(p)
|
||||
return args.RunCommand(d)
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
|
Loading…
x
Reference in New Issue
Block a user