diff --git a/handlers/ssh_config/analyzer/analyzer.go b/handlers/ssh_config/analyzer/analyzer.go new file mode 100644 index 0000000..dd789d0 --- /dev/null +++ b/handlers/ssh_config/analyzer/analyzer.go @@ -0,0 +1,12 @@ +package analyzer + +import ( + sshconfig "config-lsp/handlers/ssh_config" + protocol "github.com/tliron/glsp/protocol_3_16" +) + +func Analyze( + d *sshconfig.SSHDocument, +) []protocol.Diagnostic { + return nil +} diff --git a/handlers/ssh_config/lsp/README.md b/handlers/ssh_config/lsp/README.md new file mode 100644 index 0000000..2aa9542 --- /dev/null +++ b/handlers/ssh_config/lsp/README.md @@ -0,0 +1,7 @@ +# /sshd_config/lsp + +This folder is the glue between our language server and the LSP +clients. +This folder only contains LSP commands. +It only handles very little actual logic, and instead calls +the handlers from `../handlers`. \ No newline at end of file diff --git a/handlers/ssh_config/lsp/text-document-completion.go b/handlers/ssh_config/lsp/text-document-completion.go new file mode 100644 index 0000000..5c5b64a --- /dev/null +++ b/handlers/ssh_config/lsp/text-document-completion.go @@ -0,0 +1,10 @@ +package lsp + +import ( + "github.com/tliron/glsp" + protocol "github.com/tliron/glsp/protocol_3_16" +) + +func TextDocumentCompletion(context *glsp.Context, params *protocol.CompletionParams) (any, error) { + return nil, nil +} diff --git a/handlers/ssh_config/lsp/text-document-definition.go b/handlers/ssh_config/lsp/text-document-definition.go new file mode 100644 index 0000000..4e73e2c --- /dev/null +++ b/handlers/ssh_config/lsp/text-document-definition.go @@ -0,0 +1,10 @@ +package lsp + +import ( + "github.com/tliron/glsp" + protocol "github.com/tliron/glsp/protocol_3_16" +) + +func TextDocumentDefinition(context *glsp.Context, params *protocol.DefinitionParams) ([]protocol.Location, error) { + return nil, nil +} diff --git a/handlers/ssh_config/lsp/text-document-did-change.go b/handlers/ssh_config/lsp/text-document-did-change.go new file mode 100644 index 0000000..7650bab --- /dev/null +++ b/handlers/ssh_config/lsp/text-document-did-change.go @@ -0,0 +1,42 @@ +package lsp + +import ( + "config-lsp/common" + sshconfig "config-lsp/handlers/ssh_config" + "config-lsp/handlers/ssh_config/analyzer" + "config-lsp/utils" + + "github.com/tliron/glsp" + protocol "github.com/tliron/glsp/protocol_3_16" +) + +func TextDocumentDidChange( + context *glsp.Context, + params *protocol.DidChangeTextDocumentParams, +) error { + content := params.ContentChanges[0].(protocol.TextDocumentContentChangeEventWhole).Text + common.ClearDiagnostics(context, params.TextDocument.URI) + + document := sshconfig.DocumentParserMap[params.TextDocument.URI] + document.Config.Clear() + + diagnostics := make([]protocol.Diagnostic, 0) + errors := document.Config.Parse(content) + + if len(errors) > 0 { + diagnostics = append(diagnostics, utils.Map( + errors, + func(err common.LSPError) protocol.Diagnostic { + return err.ToDiagnostic() + }, + )...) + } + + diagnostics = append(diagnostics, analyzer.Analyze(document)...) + + if len(diagnostics) > 0 { + common.SendDiagnostics(context, params.TextDocument.URI, diagnostics) + } + + return nil +} diff --git a/handlers/ssh_config/lsp/text-document-did-close.go b/handlers/ssh_config/lsp/text-document-did-close.go new file mode 100644 index 0000000..49d7ba4 --- /dev/null +++ b/handlers/ssh_config/lsp/text-document-did-close.go @@ -0,0 +1,13 @@ +package lsp + +import ( + "config-lsp/handlers/ssh_config" + "github.com/tliron/glsp" + protocol "github.com/tliron/glsp/protocol_3_16" +) + +func TextDocumentDidClose(context *glsp.Context, params *protocol.DidCloseTextDocumentParams) error { + delete(sshconfig.DocumentParserMap, params.TextDocument.URI) + + return nil +} diff --git a/handlers/ssh_config/lsp/text-document-did-open.go b/handlers/ssh_config/lsp/text-document-did-open.go new file mode 100644 index 0000000..d37a78f --- /dev/null +++ b/handlers/ssh_config/lsp/text-document-did-open.go @@ -0,0 +1,51 @@ +package lsp + +import ( + "config-lsp/common" + "config-lsp/handlers/ssh_config" + "config-lsp/handlers/ssh_config/ast" + "config-lsp/handlers/ssh_config/analyzer" + "config-lsp/utils" + + "github.com/tliron/glsp" + protocol "github.com/tliron/glsp/protocol_3_16" +) + +func TextDocumentDidOpen( + context *glsp.Context, + params *protocol.DidOpenTextDocumentParams, +) error { + common.ClearDiagnostics(context, params.TextDocument.URI) + + var document *sshconfig.SSHDocument + + if foundDocument, ok := sshconfig.DocumentParserMap[params.TextDocument.URI]; ok { + document = foundDocument + } else { + config := ast.NewSSHConfig() + document = &sshconfig.SSHDocument{ + Config: config, + } + sshconfig.DocumentParserMap[params.TextDocument.URI] = document + } + + errors := document.Config.Parse(params.TextDocument.Text) + + diagnostics := utils.Map( + errors, + func(err common.LSPError) protocol.Diagnostic { + return err.ToDiagnostic() + }, + ) + + diagnostics = append( + diagnostics, + analyzer.Analyze(document)..., + ) + + if len(diagnostics) > 0 { + common.SendDiagnostics(context, params.TextDocument.URI, diagnostics) + } + + return nil +} diff --git a/handlers/ssh_config/lsp/text-document-hover.go b/handlers/ssh_config/lsp/text-document-hover.go new file mode 100644 index 0000000..61d19cd --- /dev/null +++ b/handlers/ssh_config/lsp/text-document-hover.go @@ -0,0 +1,13 @@ +package lsp + +import ( + "github.com/tliron/glsp" + protocol "github.com/tliron/glsp/protocol_3_16" +) + +func TextDocumentHover( + context *glsp.Context, + params *protocol.HoverParams, +) (*protocol.Hover, error) { + return nil, nil +} diff --git a/handlers/ssh_config/lsp/text-document-range-formatting.go b/handlers/ssh_config/lsp/text-document-range-formatting.go new file mode 100644 index 0000000..8cb8549 --- /dev/null +++ b/handlers/ssh_config/lsp/text-document-range-formatting.go @@ -0,0 +1,13 @@ +package lsp + +import ( + "github.com/tliron/glsp" + protocol "github.com/tliron/glsp/protocol_3_16" +) + +func TextDocumentRangeFormatting( + context *glsp.Context, + params *protocol.DocumentRangeFormattingParams, +) ([]protocol.TextEdit, error) { + return nil, nil +} diff --git a/handlers/ssh_config/lsp/text-document-signature-help.go b/handlers/ssh_config/lsp/text-document-signature-help.go new file mode 100644 index 0000000..eff0052 --- /dev/null +++ b/handlers/ssh_config/lsp/text-document-signature-help.go @@ -0,0 +1,10 @@ +package lsp + +import ( + "github.com/tliron/glsp" + protocol "github.com/tliron/glsp/protocol_3_16" +) + +func TextDocumentSignatureHelp(context *glsp.Context, params *protocol.SignatureHelpParams) (*protocol.SignatureHelp, error) { + return nil, nil +} diff --git a/root-handler/lsp-utils.go b/root-handler/lsp-utils.go index 8a5b7c6..f2e22e5 100644 --- a/root-handler/lsp-utils.go +++ b/root-handler/lsp-utils.go @@ -13,6 +13,7 @@ import ( type SupportedLanguage string const ( + LanguageSSHConfig SupportedLanguage = "ssh_config" LanguageSSHDConfig SupportedLanguage = "sshd_config" LanguageFstab SupportedLanguage = "fstab" LanguageWireguard SupportedLanguage = "languagewireguard" @@ -21,6 +22,7 @@ const ( ) var AllSupportedLanguages = []string{ + string(LanguageSSHConfig), string(LanguageSSHDConfig), string(LanguageFstab), string(LanguageWireguard), @@ -54,8 +56,12 @@ func (e LanguageUndetectableError) Error() string { var valueToLanguageMap = map[string]SupportedLanguage{ "sshd_config": LanguageSSHDConfig, "sshdconfig": LanguageSSHDConfig, - "ssh_config": LanguageSSHDConfig, - "sshconfig": LanguageSSHDConfig, + + "ssh_config": LanguageSSHConfig, + "sshconfig": LanguageSSHConfig, + + ".ssh/config": LanguageSSHConfig, + "~/.ssh/config": LanguageSSHConfig, "fstab": LanguageFstab, "etc/fstab": LanguageFstab, @@ -124,5 +130,9 @@ func DetectLanguage( return LanguageWireguard, nil } + if strings.HasSuffix(uri, ".ssh/config") { + return LanguageSSHConfig, nil + } + return "", undetectableError } diff --git a/root-handler/text-document-code-action.go b/root-handler/text-document-code-action.go index f1da029..ac385ad 100644 --- a/root-handler/text-document-code-action.go +++ b/root-handler/text-document-code-action.go @@ -29,6 +29,8 @@ func TextDocumentCodeAction(context *glsp.Context, params *protocol.CodeActionPa return hosts.TextDocumentCodeAction(context, params) case LanguageSSHDConfig: return nil, nil + case LanguageSSHConfig: + return nil, nil case LanguageWireguard: return wireguard.TextDocumentCodeAction(context, params) case LanguageAliases: diff --git a/root-handler/text-document-completion.go b/root-handler/text-document-completion.go index 6b5a2f2..a82a4eb 100644 --- a/root-handler/text-document-completion.go +++ b/root-handler/text-document-completion.go @@ -4,6 +4,7 @@ import ( aliases "config-lsp/handlers/aliases/lsp" fstab "config-lsp/handlers/fstab/lsp" hosts "config-lsp/handlers/hosts/lsp" + sshconfig "config-lsp/handlers/ssh_config/lsp" sshdconfig "config-lsp/handlers/sshd_config/lsp" wireguard "config-lsp/handlers/wireguard/lsp" @@ -29,6 +30,8 @@ func TextDocumentCompletion(context *glsp.Context, params *protocol.CompletionPa return fstab.TextDocumentCompletion(context, params) case LanguageSSHDConfig: return sshdconfig.TextDocumentCompletion(context, params) + case LanguageSSHConfig: + return sshconfig.TextDocumentCompletion(context, params) case LanguageWireguard: return wireguard.TextDocumentCompletion(context, params) case LanguageHosts: diff --git a/root-handler/text-document-definition.go b/root-handler/text-document-definition.go index 70e7b6a..593cfad 100644 --- a/root-handler/text-document-definition.go +++ b/root-handler/text-document-definition.go @@ -2,6 +2,7 @@ package roothandler import ( aliases "config-lsp/handlers/aliases/lsp" + sshconfig "config-lsp/handlers/ssh_config/lsp" sshdconfig "config-lsp/handlers/sshd_config/lsp" "github.com/tliron/glsp" @@ -26,6 +27,8 @@ func TextDocumentDefinition(context *glsp.Context, params *protocol.DefinitionPa return nil, nil case LanguageSSHDConfig: return sshdconfig.TextDocumentDefinition(context, params) + case LanguageSSHConfig: + return sshconfig.TextDocumentDefinition(context, params) case LanguageFstab: return nil, nil case LanguageWireguard: diff --git a/root-handler/text-document-did-change.go b/root-handler/text-document-did-change.go index 295a091..caaab6d 100644 --- a/root-handler/text-document-did-change.go +++ b/root-handler/text-document-did-change.go @@ -5,6 +5,7 @@ import ( fstab "config-lsp/handlers/fstab/lsp" hosts "config-lsp/handlers/hosts/lsp" sshdconfig "config-lsp/handlers/sshd_config/lsp" + sshconfig "config-lsp/handlers/ssh_config/lsp" wireguard "config-lsp/handlers/wireguard/lsp" "github.com/tliron/glsp" @@ -43,6 +44,8 @@ func TextDocumentDidChange(context *glsp.Context, params *protocol.DidChangeText return fstab.TextDocumentDidOpen(context, params) case LanguageSSHDConfig: return sshdconfig.TextDocumentDidOpen(context, params) + case LanguageSSHConfig: + return sshconfig.TextDocumentDidOpen(context, params) case LanguageWireguard: return wireguard.TextDocumentDidOpen(context, params) case LanguageHosts: @@ -57,6 +60,8 @@ func TextDocumentDidChange(context *glsp.Context, params *protocol.DidChangeText return fstab.TextDocumentDidChange(context, params) case LanguageSSHDConfig: return sshdconfig.TextDocumentDidChange(context, params) + case LanguageSSHConfig: + return sshconfig.TextDocumentDidChange(context, params) case LanguageWireguard: return wireguard.TextDocumentDidChange(context, params) case LanguageHosts: diff --git a/root-handler/text-document-did-close.go b/root-handler/text-document-did-close.go index 0d56091..724d9a6 100644 --- a/root-handler/text-document-did-close.go +++ b/root-handler/text-document-did-close.go @@ -4,6 +4,8 @@ import ( aliases "config-lsp/handlers/aliases/lsp" fstab "config-lsp/handlers/fstab/lsp" hosts "config-lsp/handlers/hosts/lsp" + sshconfig "config-lsp/handlers/ssh_config/lsp" + sshdconfig "config-lsp/handlers/sshd_config/lsp" wireguard "config-lsp/handlers/wireguard/lsp" "github.com/tliron/glsp" @@ -28,6 +30,9 @@ func TextDocumentDidClose(context *glsp.Context, params *protocol.DidCloseTextDo switch *language { case LanguageSSHDConfig: + return sshdconfig.TextDocumentDidClose(context, params) + case LanguageSSHConfig: + return sshconfig.TextDocumentDidClose(context, params) case LanguageFstab: return fstab.TextDocumentDidClose(context, params) case LanguageWireguard: diff --git a/root-handler/text-document-did-open.go b/root-handler/text-document-did-open.go index 3d18585..68365f6 100644 --- a/root-handler/text-document-did-open.go +++ b/root-handler/text-document-did-open.go @@ -7,6 +7,7 @@ import ( aliases "config-lsp/handlers/aliases/lsp" fstab "config-lsp/handlers/fstab/lsp" hosts "config-lsp/handlers/hosts/lsp" + sshconfig "config-lsp/handlers/ssh_config/lsp" sshdconfig "config-lsp/handlers/sshd_config/lsp" wireguard "config-lsp/handlers/wireguard/lsp" @@ -35,6 +36,8 @@ func TextDocumentDidOpen(context *glsp.Context, params *protocol.DidOpenTextDocu return fstab.TextDocumentDidOpen(context, params) case LanguageSSHDConfig: return sshdconfig.TextDocumentDidOpen(context, params) + case LanguageSSHConfig: + return sshconfig.TextDocumentDidOpen(context, params) case LanguageWireguard: return wireguard.TextDocumentDidOpen(context, params) case LanguageHosts: diff --git a/root-handler/text-document-hover.go b/root-handler/text-document-hover.go index da9a971..72f6c65 100644 --- a/root-handler/text-document-hover.go +++ b/root-handler/text-document-hover.go @@ -4,6 +4,7 @@ import ( aliases "config-lsp/handlers/aliases/lsp" fstab "config-lsp/handlers/fstab/lsp" hosts "config-lsp/handlers/hosts/lsp" + sshconfig "config-lsp/handlers/ssh_config/lsp" sshdconfig "config-lsp/handlers/sshd_config/lsp" wireguard "config-lsp/handlers/wireguard/lsp" @@ -29,6 +30,8 @@ func TextDocumentHover(context *glsp.Context, params *protocol.HoverParams) (*pr return hosts.TextDocumentHover(context, params) case LanguageSSHDConfig: return sshdconfig.TextDocumentHover(context, params) + case LanguageSSHConfig: + return sshconfig.TextDocumentHover(context, params) case LanguageFstab: return fstab.TextDocumentHover(context, params) case LanguageWireguard: diff --git a/root-handler/text-document-prepare-rename.go b/root-handler/text-document-prepare-rename.go index 6dbc75a..710fc9b 100644 --- a/root-handler/text-document-prepare-rename.go +++ b/root-handler/text-document-prepare-rename.go @@ -25,6 +25,8 @@ func TextDocumentPrepareRename(context *glsp.Context, params *protocol.PrepareRe return nil, nil case LanguageSSHDConfig: return nil, nil + case LanguageSSHConfig: + return nil, nil case LanguageFstab: return nil, nil case LanguageWireguard: diff --git a/root-handler/text-document-range-formatting.go b/root-handler/text-document-range-formatting.go index 6b4cff6..5f917f2 100644 --- a/root-handler/text-document-range-formatting.go +++ b/root-handler/text-document-range-formatting.go @@ -1,7 +1,9 @@ package roothandler import ( + sshconfig "config-lsp/handlers/ssh_config/lsp" sshdconfig "config-lsp/handlers/sshd_config/lsp" + "github.com/tliron/glsp" protocol "github.com/tliron/glsp/protocol_3_16" ) @@ -27,6 +29,8 @@ func TextDocumentRangeFormattingFunc( return nil, nil case LanguageSSHDConfig: return sshdconfig.TextDocumentRangeFormatting(context, params) + case LanguageSSHConfig: + return sshconfig.TextDocumentRangeFormatting(context, params) case LanguageFstab: return nil, nil case LanguageWireguard: diff --git a/root-handler/text-document-rename.go b/root-handler/text-document-rename.go index 5a41135..9bdfafd 100644 --- a/root-handler/text-document-rename.go +++ b/root-handler/text-document-rename.go @@ -24,6 +24,8 @@ func TextDocumentRename(context *glsp.Context, params *protocol.RenameParams) (* return nil, nil case LanguageSSHDConfig: return nil, nil + case LanguageSSHConfig: + return nil, nil case LanguageFstab: return nil, nil case LanguageWireguard: diff --git a/root-handler/text-document-signature-help.go b/root-handler/text-document-signature-help.go index 3fb742e..0e6ca33 100644 --- a/root-handler/text-document-signature-help.go +++ b/root-handler/text-document-signature-help.go @@ -26,6 +26,8 @@ func TextDocumentSignatureHelp(context *glsp.Context, params *protocol.Signature return nil, nil case LanguageSSHDConfig: return sshdconfig.TextDocumentSignatureHelp(context, params) + case LanguageSSHConfig: + return nil, nil case LanguageFstab: return nil, nil case LanguageWireguard: