From 3e0c438c79442fe3368c9e0b0b65ec9ab24f8a72 Mon Sep 17 00:00:00 2001 From: Daniel Banck Date: Wed, 27 Jul 2022 17:17:17 +0200 Subject: [PATCH] Improve quoting and empty/multiline expressions --- decoder/expression_candidates.go | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/decoder/expression_candidates.go b/decoder/expression_candidates.go index 8237ede1..3d92112b 100644 --- a/decoder/expression_candidates.go +++ b/decoder/expression_candidates.go @@ -199,6 +199,15 @@ func isEmptyExpr(expr hclsyntax.Expression) bool { return true } +func isMultilineTemplateExpr(expr hclsyntax.Expression) bool { + t, ok := expr.(*hclsyntax.TemplateExpr) + if !ok { + return false + } + // TODO fix/test + return isMultilineStringLiteral(t) +} + func (d *PathDecoder) candidatesFromHooks(ctx context.Context, attr *hclsyntax.Attribute, schema *schema.AttributeSchema, outerBodyRng hcl.Range, pos hcl.Pos) []lang.Candidate { candidates := make([]lang.Candidate, 0) expr := ExprConstraints(schema.Expr) @@ -209,7 +218,11 @@ func (d *PathDecoder) candidatesFromHooks(ctx context.Context, attr *hclsyntax.A } editRng := attr.Expr.Range() - if isEmptyExpr(attr.Expr) { // TODO improve quoting and range + if isEmptyExpr(attr.Expr) || isMultilineTemplateExpr(attr.Expr) { + // An empty expression or a string without a closing quote will lead to + // an attribute expression spanning multiple lines. + // Since text edits only support a single line, we're resetting the End + // position here. editRng.End = pos } prefixRng := attr.Expr.Range() @@ -227,14 +240,19 @@ func (d *PathDecoder) candidatesFromHooks(ctx context.Context, attr *hclsyntax.A res, _ := completionFunc(ctx, cty.StringVal(prefix)) for _, c := range res { + // We're adding quotes to the string here, as we're always + // replacing the whole edit range + text := fmt.Sprintf("%q", c.RawInsertText) + candidates = append(candidates, lang.Candidate{ - Label: c.Label, - Detail: c.Detail, - Description: c.Description, - Kind: c.Kind, + Label: text, + Detail: c.Detail, + Description: c.Description, + Kind: c.Kind, + IsDeprecated: c.IsDeprecated, TextEdit: lang.TextEdit{ - NewText: fmt.Sprintf("%q", c.RawInsertText), - Snippet: fmt.Sprintf("%q", c.RawInsertText), + NewText: text, + Snippet: text, Range: editRng, }, ResolveHook: c.ResolveHook,