mirror of
https://github.com/Myzel394/config-lsp.git
synced 2025-06-18 23:15:26 +02:00
feat(wireguard): Add code actions; Add generate private key code action
This commit is contained in:
parent
72a8851a58
commit
dc1ccb7e43
BIN
config-lsp
Executable file
BIN
config-lsp
Executable file
Binary file not shown.
73
handlers/wireguard/code-actions.go
Normal file
73
handlers/wireguard/code-actions.go
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
package wireguard
|
||||||
|
|
||||||
|
import (
|
||||||
|
protocol "github.com/tliron/glsp/protocol_3_16"
|
||||||
|
)
|
||||||
|
|
||||||
|
type codeActionName string
|
||||||
|
|
||||||
|
const (
|
||||||
|
codeActionGeneratePrivateKey codeActionName = "generatePrivateKey"
|
||||||
|
)
|
||||||
|
|
||||||
|
type codeActionGeneratePrivateKeyArgs struct {
|
||||||
|
URI protocol.DocumentUri
|
||||||
|
Line uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
func codeActionGeneratePrivateKeyArgsFromArguments(arguments map[string]any) codeActionGeneratePrivateKeyArgs {
|
||||||
|
return codeActionGeneratePrivateKeyArgs{
|
||||||
|
URI: arguments["URI"].(protocol.DocumentUri),
|
||||||
|
Line: uint32(arguments["Line"].(float64)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p wireguardProperty) getInsertRange(line uint32) protocol.Range {
|
||||||
|
insertPosition := p.Separator.Location.End
|
||||||
|
var length uint32 = 0
|
||||||
|
|
||||||
|
if p.Value != nil {
|
||||||
|
// Length of the value
|
||||||
|
length = p.Value.Location.End - p.Value.Location.Start
|
||||||
|
}
|
||||||
|
|
||||||
|
return protocol.Range{
|
||||||
|
Start: protocol.Position{
|
||||||
|
Line: line,
|
||||||
|
Character: insertPosition,
|
||||||
|
},
|
||||||
|
End: protocol.Position{
|
||||||
|
Line: line,
|
||||||
|
Character: insertPosition + length,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *wireguardParser) runGeneratePrivateKey(args codeActionGeneratePrivateKeyArgs) (*protocol.ApplyWorkspaceEditParams, error) {
|
||||||
|
privateKey, err := createNewPrivateKey()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return &protocol.ApplyWorkspaceEditParams{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
section, property := p.getPropertyByLine(args.Line)
|
||||||
|
|
||||||
|
if section == nil || property == nil {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
label := "Generate Private Key"
|
||||||
|
return &protocol.ApplyWorkspaceEditParams{
|
||||||
|
Label: &label,
|
||||||
|
Edit: protocol.WorkspaceEdit{
|
||||||
|
Changes: map[protocol.DocumentUri][]protocol.TextEdit{
|
||||||
|
args.URI: {
|
||||||
|
{
|
||||||
|
NewText: " " + privateKey,
|
||||||
|
Range: property.getInsertRange(args.Line),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}, nil
|
||||||
|
}
|
45
handlers/wireguard/text-document-code-action.go
Normal file
45
handlers/wireguard/text-document-code-action.go
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
package wireguard
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/tliron/glsp"
|
||||||
|
protocol "github.com/tliron/glsp/protocol_3_16"
|
||||||
|
)
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
if section == nil || property == nil || property.Separator == nil {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, nil
|
||||||
|
}
|
@ -11,8 +11,6 @@ func TextDocumentHover(
|
|||||||
context *glsp.Context,
|
context *glsp.Context,
|
||||||
params *protocol.HoverParams,
|
params *protocol.HoverParams,
|
||||||
) (*protocol.Hover, error) {
|
) (*protocol.Hover, error) {
|
||||||
// cursor := params.Position.Character
|
|
||||||
|
|
||||||
parser := documentParserMap[params.TextDocument.URI]
|
parser := documentParserMap[params.TextDocument.URI]
|
||||||
|
|
||||||
switch parser.getTypeByLine(params.Position.Line) {
|
switch parser.getTypeByLine(params.Position.Line) {
|
||||||
|
37
handlers/wireguard/wg-commands.go
Normal file
37
handlers/wireguard/wg-commands.go
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
package wireguard
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os/exec"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
func areWireguardToolsAvailable() bool {
|
||||||
|
_, err := exec.LookPath("wg")
|
||||||
|
|
||||||
|
return err == nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func createNewPrivateKey() (string, error) {
|
||||||
|
cmd := exec.Command("wg", "genkey")
|
||||||
|
|
||||||
|
bytes, err := cmd.Output()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
return string(bytes), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func createPublicKey(privateKey string) (string, error) {
|
||||||
|
cmd := exec.Command("wg", "pubkey")
|
||||||
|
cmd.Stdin = strings.NewReader(privateKey)
|
||||||
|
|
||||||
|
bytes, err := cmd.Output()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
return strings.ReplaceAll(string(bytes), "\n", ""), nil
|
||||||
|
}
|
@ -327,3 +327,19 @@ func (p *wireguardParser) getBelongingSectionByLine(line uint32) *wireguardSecti
|
|||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *wireguardParser) getPropertyByLine(line uint32) (*wireguardSection, *wireguardProperty) {
|
||||||
|
section := p.getSectionByLine(line)
|
||||||
|
|
||||||
|
if section.Name == nil {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
property, _ := section.findProperty(line)
|
||||||
|
|
||||||
|
if property == nil {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return section, property
|
||||||
|
}
|
||||||
|
40
handlers/wireguard/wg_commands_test.go
Normal file
40
handlers/wireguard/wg_commands_test.go
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
package wireguard
|
||||||
|
|
||||||
|
import "testing"
|
||||||
|
|
||||||
|
func TestWireguardAvailable(
|
||||||
|
t *testing.T,
|
||||||
|
) {
|
||||||
|
if !areWireguardToolsAvailable() {
|
||||||
|
t.Skip("Wireguard tools not available")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWireguardPrivateKey(
|
||||||
|
t *testing.T,
|
||||||
|
) {
|
||||||
|
privateKey, err := createNewPrivateKey()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Log(privateKey)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWireguardPublicKey(
|
||||||
|
t *testing.T,
|
||||||
|
) {
|
||||||
|
privateKey := "UPBKR0kLF2C/+Ei5fwN5KHsAcon9xfBX+RWhebYFGWg="
|
||||||
|
publicKey, err := createPublicKey(privateKey)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if publicKey != "3IPUqUKXUkkU7tNp/G/KgcBqUh3N0WWJpfQf79lGdl0=" {
|
||||||
|
t.Fatalf("Public key does not match, it's: %v", publicKey)
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Log(publicKey)
|
||||||
|
}
|
23
handlers/wireguard/workspace-execute-command.go
Normal file
23
handlers/wireguard/workspace-execute-command.go
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
package wireguard
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/tliron/glsp"
|
||||||
|
protocol "github.com/tliron/glsp/protocol_3_16"
|
||||||
|
)
|
||||||
|
|
||||||
|
func WorkspaceExecuteCommand(context *glsp.Context, params *protocol.ExecuteCommandParams) (*protocol.ApplyWorkspaceEditParams, error) {
|
||||||
|
_, command, _ := strings.Cut(params.Command, ".")
|
||||||
|
|
||||||
|
switch command {
|
||||||
|
case string(codeActionGeneratePrivateKey):
|
||||||
|
args := codeActionGeneratePrivateKeyArgsFromArguments(params.Arguments[0].(map[string]any))
|
||||||
|
|
||||||
|
parser := documentParserMap[args.URI]
|
||||||
|
|
||||||
|
return parser.runGeneratePrivateKey(args)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, nil
|
||||||
|
}
|
@ -17,15 +17,17 @@ var lspHandler protocol.Handler
|
|||||||
func SetUpRootHandler() {
|
func SetUpRootHandler() {
|
||||||
rootHandler = NewRootHandler()
|
rootHandler = NewRootHandler()
|
||||||
lspHandler = protocol.Handler{
|
lspHandler = protocol.Handler{
|
||||||
Initialize: initialize,
|
Initialize: initialize,
|
||||||
Initialized: initialized,
|
Initialized: initialized,
|
||||||
Shutdown: shutdown,
|
Shutdown: shutdown,
|
||||||
SetTrace: setTrace,
|
SetTrace: setTrace,
|
||||||
TextDocumentDidOpen: TextDocumentDidOpen,
|
TextDocumentDidOpen: TextDocumentDidOpen,
|
||||||
TextDocumentDidChange: TextDocumentDidChange,
|
TextDocumentDidChange: TextDocumentDidChange,
|
||||||
TextDocumentCompletion: TextDocumentCompletion,
|
TextDocumentCompletion: TextDocumentCompletion,
|
||||||
TextDocumentHover: TextDocumentHover,
|
TextDocumentHover: TextDocumentHover,
|
||||||
TextDocumentDidClose: TextDocumentDidClose,
|
TextDocumentDidClose: TextDocumentDidClose,
|
||||||
|
TextDocumentCodeAction: TextDocumentCodeAction,
|
||||||
|
WorkspaceExecuteCommand: WorkspaceExecuteCommand,
|
||||||
}
|
}
|
||||||
|
|
||||||
server := server.NewServer(&lspHandler, lsName, false)
|
server := server.NewServer(&lspHandler, lsName, false)
|
||||||
|
23
root-handler/text-document-code-action.go
Normal file
23
root-handler/text-document-code-action.go
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
package roothandler
|
||||||
|
|
||||||
|
import (
|
||||||
|
"config-lsp/handlers/wireguard"
|
||||||
|
|
||||||
|
"github.com/tliron/glsp"
|
||||||
|
protocol "github.com/tliron/glsp/protocol_3_16"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TextDocumentCodeAction(context *glsp.Context, params *protocol.CodeActionParams) (any, error) {
|
||||||
|
language := rootHandler.GetLanguageForDocument(params.TextDocument.URI)
|
||||||
|
|
||||||
|
switch language {
|
||||||
|
case LanguageFstab:
|
||||||
|
return nil, nil
|
||||||
|
case LanguageSSHDConfig:
|
||||||
|
return nil, nil
|
||||||
|
case LanguageWireguard:
|
||||||
|
return wireguard.TextDocumentCodeAction(context, params)
|
||||||
|
}
|
||||||
|
|
||||||
|
panic("root-handler/TextDocumentCompletion: unexpected language" + language)
|
||||||
|
}
|
32
root-handler/workspace-execute-command.go
Normal file
32
root-handler/workspace-execute-command.go
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
package roothandler
|
||||||
|
|
||||||
|
import (
|
||||||
|
"config-lsp/handlers/wireguard"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/tliron/glsp"
|
||||||
|
protocol "github.com/tliron/glsp/protocol_3_16"
|
||||||
|
)
|
||||||
|
|
||||||
|
func WorkspaceExecuteCommand(context *glsp.Context, params *protocol.ExecuteCommandParams) (any, error) {
|
||||||
|
commandSection, _, _ := strings.Cut(params.Command, ".")
|
||||||
|
|
||||||
|
var edit *protocol.ApplyWorkspaceEditParams
|
||||||
|
var err error
|
||||||
|
|
||||||
|
switch commandSection {
|
||||||
|
case "wireguard":
|
||||||
|
edit, err = wireguard.WorkspaceExecuteCommand(context, params)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
context.Notify(
|
||||||
|
"workspace/applyEdit",
|
||||||
|
edit,
|
||||||
|
)
|
||||||
|
|
||||||
|
return nil, nil
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user