From 394914a271be702ba55deed41cdebdc12dc06091 Mon Sep 17 00:00:00 2001 From: Myzel394 <50424412+Myzel394@users.noreply.github.com> Date: Mon, 19 Aug 2024 22:09:38 +0200 Subject: [PATCH] feat(wireguard): Add code action for PersistentKeepalive --- handlers/wireguard/analyzer.go | 6 +- handlers/wireguard/code-actions.go | 41 +++++++ handlers/wireguard/fetch-code-actions.go | 100 ++++++++++++++++++ .../wireguard/text-document-code-action.go | 57 +--------- .../wireguard/workspace-execute-command.go | 6 ++ 5 files changed, 155 insertions(+), 55 deletions(-) create mode 100644 handlers/wireguard/fetch-code-actions.go diff --git a/handlers/wireguard/analyzer.go b/handlers/wireguard/analyzer.go index 235ec3f..9c587e5 100644 --- a/handlers/wireguard/analyzer.go +++ b/handlers/wireguard/analyzer.go @@ -274,7 +274,7 @@ func (p wireguardProperty) analyzeProperty( } func (p wireguardParser) checkForDuplicateProperties() []protocol.Diagnostic { - diagnostics := []protocol.Diagnostic{} + diagnostics := make([]protocol.Diagnostic, 0) for _, section := range p.Sections { diagnostics = append(diagnostics, section.analyzeDuplicateProperties()...) @@ -284,7 +284,7 @@ func (p wireguardParser) checkForDuplicateProperties() []protocol.Diagnostic { } func (p wireguardSection) analyzeDuplicateProperties() []protocol.Diagnostic { - diagnostics := []protocol.Diagnostic{} + diagnostics := make([]protocol.Diagnostic, 0) existingProperties := make(map[string]uint32) @@ -337,7 +337,7 @@ func (p wireguardSection) analyzeDuplicateProperties() []protocol.Diagnostic { } func (p wireguardParser) analyzeAllowedIPIsInRange() []protocol.Diagnostic { - diagnostics := []protocol.Diagnostic{} + diagnostics := make([]protocol.Diagnostic, 0) return diagnostics } diff --git a/handlers/wireguard/code-actions.go b/handlers/wireguard/code-actions.go index 9afdc19..f888ef8 100644 --- a/handlers/wireguard/code-actions.go +++ b/handlers/wireguard/code-actions.go @@ -9,6 +9,7 @@ type codeActionName string const ( codeActionGeneratePrivateKey codeActionName = "generatePrivateKey" codeActionGeneratePresharedKey codeActionName = "generatePresharedKey" + codeActionAddKeepalive codeActionName = "addKeepalive" ) type codeActionGeneratePrivateKeyArgs struct { @@ -35,6 +36,18 @@ func codeActionGeneratePresharedKeyArgsFromArguments(arguments map[string]any) c } } +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 (p wireguardProperty) getInsertRange(line uint32) protocol.Range { var insertPosition uint32 = p.Separator.Location.End var length uint32 = 0 @@ -114,3 +127,31 @@ func (p *wireguardParser) runGeneratePresharedKey(args codeActionGeneratePreshar }, }, nil } + +func (p *wireguardParser) runAddKeepalive(args codeActionAddKeepaliveArgs) (*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, + }, + End: protocol.Position{ + Line: section.EndLine + 1, + Character: 0, + }, + }, + }, + }, + }, + }, + }, nil +} diff --git a/handlers/wireguard/fetch-code-actions.go b/handlers/wireguard/fetch-code-actions.go new file mode 100644 index 0000000..6601ba7 --- /dev/null +++ b/handlers/wireguard/fetch-code-actions.go @@ -0,0 +1,100 @@ +package wireguard + +import protocol "github.com/tliron/glsp/protocol_3_16" + +func getKeepaliveCodeActions( + params *protocol.CodeActionParams, + parser *wireguardParser, +) []protocol.CodeAction { + line := params.Range.Start.Line + + for index, section := range parser.Sections { + if section.StartLine >= line && line <= section.EndLine && section.Name != nil && *section.Name == "Peer" { + if section.fetchFirstProperty("Endpoint") != nil && section.fetchFirstProperty("PersistentKeepalive") == nil { + commandID := "wireguard." + codeActionAddKeepalive + command := protocol.Command{ + Title: "Add PersistentKeepalive", + Command: string(commandID), + Arguments: []any{ + codeActionAddKeepaliveArgs{ + URI: params.TextDocument.URI, + SectionIndex: uint32(index), + }, + }, + } + + return []protocol.CodeAction{ + { + Title: "Add PersistentKeepalive", + Command: &command, + }, + } + } + } + } + + return nil +} + +func getKeyGenerationCodeActions( + params *protocol.CodeActionParams, + parser *wireguardParser, +) []protocol.CodeAction { + line := params.Range.Start.Line + section, property := parser.getPropertyByLine(line) + + if section == nil || property == nil || property.Separator == nil { + return nil + } + + switch property.Key.Name { + case "PrivateKey": + if !areWireguardToolsAvailable() { + return nil + } + + commandID := "wireguard." + codeActionGeneratePrivateKey + command := protocol.Command{ + Title: "Generate Private Key", + Command: string(commandID), + Arguments: []any{ + codeActionGeneratePrivateKeyArgs{ + URI: params.TextDocument.URI, + Line: line, + }, + }, + } + + return []protocol.CodeAction{ + { + Title: "Generate Private Key", + Command: &command, + }, + } + case "PresharedKey": + if !areWireguardToolsAvailable() { + return nil + } + + commandID := "wireguard." + codeActionGeneratePresharedKey + command := protocol.Command{ + Title: "Generate PresharedKey", + Command: string(commandID), + Arguments: []any{ + codeActionGeneratePresharedKeyArgs{ + URI: params.TextDocument.URI, + Line: line, + }, + }, + } + + return []protocol.CodeAction{ + { + Title: "Generate PresharedKey", + Command: &command, + }, + } + } + + return nil +} diff --git a/handlers/wireguard/text-document-code-action.go b/handlers/wireguard/text-document-code-action.go index 40b9a71..6d63d52 100644 --- a/handlers/wireguard/text-document-code-action.go +++ b/handlers/wireguard/text-document-code-action.go @@ -6,62 +6,15 @@ import ( ) func TextDocumentCodeAction(context *glsp.Context, params *protocol.CodeActionParams) ([]protocol.CodeAction, error) { - line := params.Range.Start.Line parser := documentParserMap[params.TextDocument.URI] - section, property := parser.getPropertyByLine(line) + actions := make([]protocol.CodeAction, 0, 2) - if section == nil || property == nil || property.Separator == nil { - return nil, nil - } + actions = append(actions, getKeyGenerationCodeActions(params, parser)...) + actions = append(actions, getKeepaliveCodeActions(params, parser)...) - switch property.Key.Name { - case "PrivateKey": - if !areWireguardToolsAvailable() { - return nil, nil - } - - commandID := "wireguard." + codeActionGeneratePrivateKey - command := protocol.Command{ - Title: "Generate Private Key", - Command: string(commandID), - Arguments: []any{ - codeActionGeneratePrivateKeyArgs{ - URI: params.TextDocument.URI, - Line: line, - }, - }, - } - - return []protocol.CodeAction{ - { - Title: "Generate Private Key", - Command: &command, - }, - }, nil - case "PresharedKey": - if !areWireguardToolsAvailable() { - return nil, nil - } - - commandID := "wireguard." + codeActionGeneratePresharedKey - command := protocol.Command{ - Title: "Generate PresharedKey", - Command: string(commandID), - Arguments: []any{ - codeActionGeneratePresharedKeyArgs{ - URI: params.TextDocument.URI, - Line: line, - }, - }, - } - - return []protocol.CodeAction{ - { - Title: "Generate PresharedKey", - Command: &command, - }, - }, nil + if len(actions) > 0 { + return actions, nil } return nil, nil diff --git a/handlers/wireguard/workspace-execute-command.go b/handlers/wireguard/workspace-execute-command.go index f803733..296e2a5 100644 --- a/handlers/wireguard/workspace-execute-command.go +++ b/handlers/wireguard/workspace-execute-command.go @@ -23,6 +23,12 @@ func WorkspaceExecuteCommand(context *glsp.Context, params *protocol.ExecuteComm parser := documentParserMap[args.URI] return parser.runGeneratePresharedKey(args) + case string(codeActionAddKeepalive): + args := codeActionAddKeepaliveArgsFromArguments(params.Arguments[0].(map[string]any)) + + parser := documentParserMap[args.URI] + + return parser.runAddKeepalive(args) } return nil, nil