From 90fe288650fa5667b6f7dca610c323ee851dedf9 Mon Sep 17 00:00:00 2001 From: qvalentin Date: Mon, 14 Oct 2024 18:20:06 +0200 Subject: [PATCH] feat: start with yaml document --- internal/handler/handler.go | 19 ++--- internal/handler/text_document.go | 6 ++ .../handler/yaml_handler/text_document.go | 28 ++++++++ internal/handler/yaml_handler/yaml_handler.go | 69 +++++++++++++++++++ internal/lsp/document.go | 20 ++++++ internal/lsp/document_store.go | 30 +++++--- internal/lsp/template_document.go | 22 +----- internal/lsp/yaml_document.go | 29 ++++++++ 8 files changed, 182 insertions(+), 41 deletions(-) create mode 100644 internal/handler/yaml_handler/text_document.go create mode 100644 internal/handler/yaml_handler/yaml_handler.go create mode 100644 internal/lsp/yaml_document.go diff --git a/internal/handler/handler.go b/internal/handler/handler.go index b4d7070..6c41103 100644 --- a/internal/handler/handler.go +++ b/internal/handler/handler.go @@ -4,9 +4,9 @@ import ( "context" "io" - "github.com/mrjosh/helm-ls/internal/adapter/yamlls" "github.com/mrjosh/helm-ls/internal/charts" templatehandler "github.com/mrjosh/helm-ls/internal/handler/template_handler" + yamlhandler "github.com/mrjosh/helm-ls/internal/handler/yaml_handler" lsplocal "github.com/mrjosh/helm-ls/internal/lsp" "github.com/mrjosh/helm-ls/internal/util" "go.lsp.dev/jsonrpc2" @@ -20,14 +20,13 @@ import ( var logger = log.GetLogger() type ServerHandler struct { - client protocol.Client - connPool jsonrpc2.Conn - linterName string - documents *lsplocal.DocumentStore - chartStore *charts.ChartStore - yamllsConnector *yamlls.Connector - helmlsConfig util.HelmlsConfiguration - langHandlers map[lsplocal.DocumentType]LangHandler + client protocol.Client + connPool jsonrpc2.Conn + linterName string + documents *lsplocal.DocumentStore + chartStore *charts.ChartStore + helmlsConfig util.HelmlsConfiguration + langHandlers map[lsplocal.DocumentType]LangHandler } func StartHandler(stream io.ReadWriteCloser) { @@ -47,6 +46,7 @@ func StartHandler(stream io.ReadWriteCloser) { func newHandler(connPool jsonrpc2.Conn, client protocol.Client) *ServerHandler { documents := lsplocal.NewDocumentStore() + var x LangHandler = yamlhandler.NewYamlHandler(client, documents, nil) handler := &ServerHandler{ client: client, linterName: "helm-lint", @@ -55,6 +55,7 @@ func newHandler(connPool jsonrpc2.Conn, client protocol.Client) *ServerHandler { helmlsConfig: util.DefaultConfig, langHandlers: map[lsplocal.DocumentType]LangHandler{ lsplocal.TemplateDocumentType: templatehandler.NewTemplateHandler(client, documents, nil), + lsplocal.YamlDocumentType: x, }, } logger.Printf("helm-lint-langserver: connections opened") diff --git a/internal/handler/text_document.go b/internal/handler/text_document.go index fb7ff0e..f691fa9 100644 --- a/internal/handler/text_document.go +++ b/internal/handler/text_document.go @@ -12,6 +12,12 @@ import ( func (h *ServerHandler) DidOpen(ctx context.Context, params *lsp.DidOpenTextDocumentParams) (err error) { handler := h.langHandlers[lsplocal.TemplateDocumentTypeForLangID(params.TextDocument.LanguageID)] + if handler == nil { + message := "Language not supported: " + string(params.TextDocument.LanguageID) + logger.Error(message) + return errors.New(message) + } + handler.DidOpen(ctx, params, h.helmlsConfig) defer h.publishDiagnostics(ctx, handler.GetDiagnostics(params.TextDocument.URI)) diff --git a/internal/handler/yaml_handler/text_document.go b/internal/handler/yaml_handler/text_document.go new file mode 100644 index 0000000..5b70fda --- /dev/null +++ b/internal/handler/yaml_handler/text_document.go @@ -0,0 +1,28 @@ +package yamlhandler + +import ( + "context" + + "github.com/mrjosh/helm-ls/internal/util" + "go.lsp.dev/protocol" +) + +// DidChange implements handler.LangHandler. +func (h *YamlHandler) DidChange(ctx context.Context, params *protocol.DidChangeTextDocumentParams) (err error) { + panic("unimplemented") +} + +// DidOpen implements handler.LangHandler. +func (h *YamlHandler) DidOpen(ctx context.Context, params *protocol.DidOpenTextDocumentParams, helmlsConfig util.HelmlsConfiguration) (err error) { + _, err = h.documents.DidOpenTemplateDocument(params, helmlsConfig) + if err != nil { + logger.Error(err) + return err + } + return nil +} + +// DidSave implements handler.LangHandler. +func (h *YamlHandler) DidSave(ctx context.Context, params *protocol.DidSaveTextDocumentParams) (err error) { + return nil +} diff --git a/internal/handler/yaml_handler/yaml_handler.go b/internal/handler/yaml_handler/yaml_handler.go new file mode 100644 index 0000000..7e1d0e5 --- /dev/null +++ b/internal/handler/yaml_handler/yaml_handler.go @@ -0,0 +1,69 @@ +package yamlhandler + +import ( + "context" + + "github.com/mrjosh/helm-ls/internal/adapter/yamlls" + "github.com/mrjosh/helm-ls/internal/charts" + "github.com/mrjosh/helm-ls/internal/log" + lsplocal "github.com/mrjosh/helm-ls/internal/lsp" + "github.com/mrjosh/helm-ls/internal/util" + "go.lsp.dev/protocol" + "go.lsp.dev/uri" +) + +var logger = log.GetLogger() + +type YamlHandler struct { + documents *lsplocal.DocumentStore + chartStore *charts.ChartStore + yamllsConnector *yamlls.Connector +} + +// Completion implements handler.LangHandler. +func (h *YamlHandler) Completion(ctx context.Context, params *protocol.CompletionParams) (result *protocol.CompletionList, err error) { + panic("unimplemented") +} + +// Configure implements handler.LangHandler. +func (h *YamlHandler) Configure(ctx context.Context, helmlsConfig util.HelmlsConfiguration) {} + +// Definition implements handler.LangHandler. +func (h *YamlHandler) Definition(ctx context.Context, params *protocol.DefinitionParams) (result []protocol.Location, err error) { + panic("unimplemented") +} + +// DocumentSymbol implements handler.LangHandler. +func (h *YamlHandler) DocumentSymbol(ctx context.Context, params *protocol.DocumentSymbolParams) (result []interface{}, err error) { + panic("unimplemented") +} + +// GetDiagnostics implements handler.LangHandler. +func (h *YamlHandler) GetDiagnostics(uri uri.URI) []protocol.PublishDiagnosticsParams { + panic("unimplemented") +} + +// Hover implements handler.LangHandler. +func (h *YamlHandler) Hover(ctx context.Context, params *protocol.HoverParams) (result *protocol.Hover, err error) { + panic("unimplemented") +} + +// References implements handler.LangHandler. +func (h *YamlHandler) References(ctx context.Context, params *protocol.ReferenceParams) (result []protocol.Location, err error) { + panic("unimplemented") +} + +// SetClient implements handler.LangHandler. +func (h *YamlHandler) SetClient(client protocol.Client) {} + +func NewYamlHandler(client protocol.Client, documents *lsplocal.DocumentStore, chartStore *charts.ChartStore) *YamlHandler { + return &YamlHandler{ + documents: documents, + chartStore: chartStore, + yamllsConnector: &yamlls.Connector{}, + } +} + +func (h *YamlHandler) SetChartStore(chartStore *charts.ChartStore) { + h.chartStore = chartStore +} diff --git a/internal/lsp/document.go b/internal/lsp/document.go index 8ab4469..fdbb80e 100644 --- a/internal/lsp/document.go +++ b/internal/lsp/document.go @@ -93,3 +93,23 @@ func (d *Document) GetPath() string { type TextDocument interface { ApplyChanges([]lsp.TextDocumentContentChangeEvent) } + +// WordAt returns the word found at the given location. +func (d *Document) WordAt(pos lsp.Position) string { + logger.Debug(pos) + + line, ok := d.getLine(int(pos.Line)) + if !ok { + return "" + } + return util.WordAt(line, int(pos.Character)) +} + +// getLine returns the line at the given index. +func (d *Document) getLine(index int) (string, bool) { + lines := d.getLines() + if index < 0 || index > len(lines) { + return "", false + } + return lines[index], true +} diff --git a/internal/lsp/document_store.go b/internal/lsp/document_store.go index c06aa0a..23491d0 100644 --- a/internal/lsp/document_store.go +++ b/internal/lsp/document_store.go @@ -33,19 +33,15 @@ func (s *DocumentStore) DidOpenTemplateDocument( return doc, nil } -// unused -func (s *DocumentStore) DidOpen(params *lsp.DidOpenTextDocumentParams, helmlsConfig util.HelmlsConfiguration) (*Document, error) { - logger.Debug(fmt.Sprintf("Opening document %s with langID %s", params.TextDocument.URI, params.TextDocument.LanguageID)) - +func (s *DocumentStore) DidOpenYamlDocument( + params *lsp.DidOpenTextDocumentParams, helmlsConfig util.HelmlsConfiguration, +) (*YamlDocument, error) { uri := params.TextDocument.URI path := uri.Filename() - if IsTemplateDocumentLangID(params.TextDocument.LanguageID) { - doc := NewTemplateDocument(uri, []byte(params.TextDocument.Text), true, helmlsConfig) - logger.Debug("Storing doc ", path) - s.documents.Store(path, doc) - // return doc, nil - } - return nil, fmt.Errorf("unsupported document type: %s", params.TextDocument.LanguageID) + doc := NewYamlDocument(uri, []byte(params.TextDocument.Text), true, helmlsConfig) + logger.Debug("Storing doc ", path) + s.documents.Store(path, doc) + return doc, nil } func (s *DocumentStore) StoreTemplateDocument(path string, content []byte, helmlsConfig util.HelmlsConfiguration) { @@ -69,6 +65,18 @@ func (s *DocumentStore) GetTemplateDoc(docuri uri.URI) (*TemplateDocument, bool) return doc, ok } +func (s *DocumentStore) GetYamlDoc(docuri uri.URI) (*YamlDocument, bool) { + path := docuri.Filename() + d, ok := s.documents.Load(path) + + if !ok { + return nil, false + } + + doc, ok := d.(*YamlDocument) + return doc, ok +} + func (s *DocumentStore) GetAllTemplateDocs() []*TemplateDocument { var docs []*TemplateDocument s.documents.Range(func(_, v interface{}) bool { diff --git a/internal/lsp/template_document.go b/internal/lsp/template_document.go index 59a5deb..5bfe850 100644 --- a/internal/lsp/template_document.go +++ b/internal/lsp/template_document.go @@ -7,7 +7,7 @@ import ( "go.lsp.dev/uri" ) -// TemplateDocument represents an opened file. +// TemplateDocument represents an helm template file. type TemplateDocument struct { Document NeedsRefreshDiagnostics bool @@ -43,26 +43,6 @@ func (d *TemplateDocument) ApplyChanges(changes []lsp.TextDocumentContentChangeE d.lines = nil } -// WordAt returns the word found at the given location. -func (d *Document) WordAt(pos lsp.Position) string { - logger.Debug(pos) - - line, ok := d.getLine(int(pos.Line)) - if !ok { - return "" - } - return util.WordAt(line, int(pos.Character)) -} - -// getLine returns the line at the given index. -func (d *Document) getLine(index int) (string, bool) { - lines := d.getLines() - if index < 0 || index > len(lines) { - return "", false - } - return lines[index], true -} - func IsYamllsEnabled(uri lsp.URI, yamllsConfiguration util.YamllsConfiguration) bool { return yamllsConfiguration.EnabledForFilesGlobObject.Match(uri.Filename()) } diff --git a/internal/lsp/yaml_document.go b/internal/lsp/yaml_document.go new file mode 100644 index 0000000..893055c --- /dev/null +++ b/internal/lsp/yaml_document.go @@ -0,0 +1,29 @@ +package lsp + +import ( + "github.com/mrjosh/helm-ls/internal/util" + lsp "go.lsp.dev/protocol" + "go.lsp.dev/uri" +) + +// TemplateDocument represents an helm template file. +type YamlDocument struct { + Document +} + +func (d *YamlDocument) GetDocumentType() DocumentType { + return YamlDocumentType +} + +func NewYamlDocument(fileURI uri.URI, content []byte, isOpen bool, helmlsConfig util.HelmlsConfiguration) *YamlDocument { + return &YamlDocument{ + Document: *NewDocument(fileURI, content, isOpen), + } +} + +// ApplyChanges updates the content of the document from LSP textDocument/didChange events. +func (d *YamlDocument) ApplyChanges(changes []lsp.TextDocumentContentChangeEvent) { + d.Document.ApplyChanges(changes) + + d.lines = nil +}