Skip to content

Commit

Permalink
fix: cleanup for templateContext completio
Browse files Browse the repository at this point in the history
  • Loading branch information
qvalentin committed May 8, 2024
1 parent f31671d commit bdc4b6c
Show file tree
Hide file tree
Showing 5 changed files with 107 additions and 18 deletions.
2 changes: 2 additions & 0 deletions internal/handler/completion.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ func (h *langHandler) Completion(ctx context.Context, params *lsp.CompletionPara
}
}

// If no usecase matched, we assume we are at {{ }}
// and provide the basic BuiltInObjects and functions
items := []helmdocs.HelmDocumentation{}
for _, v := range helmdocs.BuiltInObjects {
v.Name = "." + v.Name
Expand Down
76 changes: 76 additions & 0 deletions internal/handler/completion_main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ package handler

import (
"context"
"errors"
"os"
"strings"
"testing"

"github.com/mrjosh/helm-ls/internal/adapter/yamlls"
Expand All @@ -11,6 +13,7 @@ import (
lsplocal "github.com/mrjosh/helm-ls/internal/lsp"
"github.com/mrjosh/helm-ls/internal/util"
"github.com/stretchr/testify/assert"
"go.lsp.dev/protocol"
lsp "go.lsp.dev/protocol"
"go.lsp.dev/uri"
)
Expand Down Expand Up @@ -178,3 +181,76 @@ func TestCompletionMain(t *testing.T) {
})
}
}

func TestCompletionMainSingleLines(t *testing.T) {
testCases := []struct {
templateWithMark string
expectedInsertTexts []string
notExpectedInsertTexts []string
err error
}{
{"Test completion on {{ .Bad.^ }}", []string{}, []string{}, errors.New("[Bad ] is no valid template context for helm")},
{"Test completion on {{ n^ }}", []string{"not"}, []string{}, nil},
{"Test completion on {{ .Values.^ }}", []string{"replicaCount"}, []string{}, nil},
{"Test completion on {{ .Release.N^ }}", []string{"Name"}, []string{}, nil},
{"Test completion on {{ .Capabilities.KubeVersion.^ }}", []string{"Minor"}, []string{}, nil},
{"Test completion on {{ .Capabilities.KubeVersion.Mi^ }}", []string{"nor"}, []string{}, nil},
{`Test completion on {{ define "test" }} T1 {{ end }} {{ include "te^"}}`, []string{"test"}, []string{}, nil},
}

for _, tt := range testCases {
t.Run(tt.templateWithMark, func(t *testing.T) {
// seen chars up to ^
col := strings.Index(tt.templateWithMark, "^")
buf := strings.Replace(tt.templateWithMark, "^", "", 1)
pos := protocol.Position{Line: 0, Character: uint32(col)}

documents := lsplocal.NewDocumentStore()

// to get the correct values file
path := "../../testdata/example/templates/completion-test.yaml"
fileURI := uri.File(path)

d := lsp.DidOpenTextDocumentParams{
TextDocument: lsp.TextDocumentItem{
URI: fileURI,
LanguageID: "",
Version: 0,
Text: buf,
},
}
documents.DidOpen(&d, util.DefaultConfig)
h := &langHandler{
chartStore: charts.NewChartStore(uri.File("."), charts.NewChart),
documents: documents,
yamllsConnector: &yamlls.Connector{},
}
result, err := h.Completion(context.Background(), &lsp.CompletionParams{
TextDocumentPositionParams: lsp.TextDocumentPositionParams{
TextDocument: lsp.TextDocumentIdentifier{
URI: fileURI,
},
Position: pos,
},
})
assert.NotNil(t, result)
assert.Equal(t, tt.err, err)

if result == nil {
return
}

insertTexts := []string{}
for _, item := range result.Items {
insertTexts = append(insertTexts, item.InsertText)
}
for _, expectedInsertText := range tt.expectedInsertTexts {
assert.Contains(t, insertTexts, expectedInsertText)
}

for _, notExpectedInsertText := range tt.notExpectedInsertTexts {
assert.NotContains(t, insertTexts, notExpectedInsertText)
}
})
}
}
2 changes: 1 addition & 1 deletion internal/handler/references.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
lsp "go.lsp.dev/protocol"
)

func (h *langHandler) References(ctx context.Context, params *lsp.ReferenceParams) (result []lsp.Location, err error) {
func (h *langHandler) References(_ context.Context, params *lsp.ReferenceParams) (result []lsp.Location, err error) {
genericDocumentUseCase, err := h.NewGenericDocumentUseCase(params.TextDocumentPositionParams, lsplocal.NodeAtPosition)
if err != nil {
return nil, err
Expand Down
35 changes: 24 additions & 11 deletions internal/language_features/template_context_completion.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
package languagefeatures

import (
"fmt"
"strings"

helmdocs "github.com/mrjosh/helm-ls/internal/documentation/helm"
lsplocal "github.com/mrjosh/helm-ls/internal/lsp"
"github.com/mrjosh/helm-ls/internal/protocol"
"github.com/mrjosh/helm-ls/internal/util"
lsp "go.lsp.dev/protocol"
)

func (f *TemplateContextFeature) Completion() (result *lsp.CompletionList, err error) {
func (f *TemplateContextFeature) Completion() (*lsp.CompletionList, error) {
templateContext, err := f.getTemplateContext()
if err != nil {
return nil, err
Expand All @@ -25,21 +28,31 @@ func (f *TemplateContextFeature) Completion() (result *lsp.CompletionList, err e
}
return protocol.CompletionResults{}.WithDocs(result, lsp.CompletionItemKindValue).ToList(), nil
}

switch templateContext[0] {
case "Values":
if templateContext[0] == "Values" {
return f.valuesCompletion(templateContext)
case "Chart", "Release", "Files", "Capabilities", "Template":
// TODO: make this more fine, by checking the length
result, ok := helmdocs.BuiltInOjectVals[templateContext[0]]
if !ok {
return protocol.CompletionResults{}.WithDocs(helmdocs.BuiltInObjects, lsp.CompletionItemKindConstant).ToList(), nil
}
nestedDocs, ok := helmdocs.BuiltInOjectVals[templateContext[0]]
if ok {
if len(templateContext) < 3 {
return protocol.CompletionResults{}.WithDocs(nestedDocs, lsp.CompletionItemKindValue).ToList(), nil
}
return protocol.CompletionResults{}.WithDocs(result, lsp.CompletionItemKindValue).ToList(), nil

adjustedDocs := trimPrefixForNestedDocs(nestedDocs, templateContext)
return protocol.CompletionResults{}.WithDocs(adjustedDocs, lsp.CompletionItemKindValue).ToList(), nil
}
return protocol.CompletionResults{}.ToList(), fmt.Errorf("%s is no valid template context for helm", templateContext)
}

return nil, nil
// handels the completion for .Capabilities.KubeVersion.^ where the result should not contain KubeVersion again
func trimPrefixForNestedDocs(nestedDocs []helmdocs.HelmDocumentation, templateContext lsplocal.TemplateContext) []helmdocs.HelmDocumentation {
adjustedDocs := []helmdocs.HelmDocumentation{}
for _, v := range nestedDocs {
if strings.HasPrefix(v.Name, templateContext.Tail().Format()) {
v.Name = strings.TrimPrefix(v.Name, templateContext.Tail().Format())
adjustedDocs = append(adjustedDocs, v)
}
}
return adjustedDocs
}

func (f *TemplateContextFeature) valuesCompletion(templateContext lsplocal.TemplateContext) (*lsp.CompletionList, error) {
Expand Down
10 changes: 4 additions & 6 deletions internal/util/values.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ func GetValueCompletion(values chartutil.Values, splittedVar []string) []lsp.Com
)

if len(splittedVar) > 0 {

localValues, err = values.Table(tableName)
if err != nil {
if len(splittedVar) > 1 {
Expand All @@ -47,17 +46,16 @@ func GetValueCompletion(values chartutil.Values, splittedVar []string) []lsp.Com
} else {
values = localValues
}

}

for variable, value := range values {
items = setItem(items, value, variable)
items = append(items, builCompletionItem(value, variable))
}

return items
}

func setItem(items []lsp.CompletionItem, value interface{}, variable string) []lsp.CompletionItem {
func builCompletionItem(value interface{}, variable string) lsp.CompletionItem {
var (
itemKind = lsp.CompletionItemKindVariable
valueOf = reflect.ValueOf(value)
Expand All @@ -80,13 +78,13 @@ func setItem(items []lsp.CompletionItem, value interface{}, variable string) []l
itemKind = lsp.CompletionItemKindField
}

return append(items, lsp.CompletionItem{
return lsp.CompletionItem{
Label: variable,
InsertText: variable,
Documentation: documentation,
Detail: valueOf.Kind().String(),
Kind: itemKind,
})
}
}

func FormatToYAML(field reflect.Value, fieldName string) string {
Expand Down

0 comments on commit bdc4b6c

Please sign in to comment.