1
0
mirror of https://github.com/golang/go synced 2024-10-01 01:38:33 -06:00

internal/lsp: improve handling of code completion snippets

A few minor fixes: check that the insert text has the expected prefix
before removing it, use a bytes.Buffer to build up snippets, and check
that functions have parentheses in their insert text before trimming
them.

Change-Id: Iaeaf6fda25d6b0a375460b975188486685be1061
Reviewed-on: https://go-review.googlesource.com/c/152978
Reviewed-by: Ingo Oeser <nightlyone@googlemail.com>
Reviewed-by: Ian Cottrell <iancottrell@google.com>
This commit is contained in:
Rebecca Stambler 2018-12-06 15:52:34 -05:00
parent 8bc39b9880
commit 8634b1ecd3

View File

@ -5,6 +5,7 @@
package lsp package lsp
import ( import (
"bytes"
"fmt" "fmt"
"sort" "sort"
"strings" "strings"
@ -28,7 +29,7 @@ func toProtocolCompletionItems(items []source.CompletionItem, prefix string, pos
continue continue
} }
insertText, triggerSignatureHelp := labelToProtocolSnippets(item.Label, item.Kind, insertTextFormat, signatureHelpEnabled) insertText, triggerSignatureHelp := labelToProtocolSnippets(item.Label, item.Kind, insertTextFormat, signatureHelpEnabled)
if prefix != "" { if strings.HasPrefix(insertText, prefix) {
insertText = insertText[len(prefix):] insertText = insertText[len(prefix):]
} }
i := protocol.CompletionItem{ i := protocol.CompletionItem{
@ -90,14 +91,17 @@ func labelToProtocolSnippets(label string, kind source.CompletionItemKind, inser
switch kind { switch kind {
case source.ConstantCompletionItem: case source.ConstantCompletionItem:
// The label for constants is of the format "<identifier> = <value>". // The label for constants is of the format "<identifier> = <value>".
// We should now insert the " = <value>" part of the label. // We should not insert the " = <value>" part of the label.
if i := strings.Index(label, " ="); i >= 0 { if i := strings.Index(label, " ="); i >= 0 {
return label[:i], false return label[:i], false
} }
case source.FunctionCompletionItem, source.MethodCompletionItem: case source.FunctionCompletionItem, source.MethodCompletionItem:
trimmed := label[:strings.Index(label, "(")] var trimmed, params string
params := strings.Trim(label[strings.Index(label, "("):], "()") if i := strings.Index(label, "("); i >= 0 {
if params == "" { trimmed = label[:i]
params = strings.Trim(label[i:], "()")
}
if params == "" || trimmed == "" {
return label, true return label, true
} }
// Don't add parameters or parens for the plaintext insert format. // Don't add parameters or parens for the plaintext insert format.
@ -118,14 +122,16 @@ func labelToProtocolSnippets(label string, kind source.CompletionItemKind, inser
`}`, `\}`, `}`, `\}`,
`$`, `\$`, `$`, `\$`,
) )
trimmed += "(" b := bytes.NewBufferString(trimmed)
b.WriteByte('(')
for i, p := range strings.Split(params, ",") { for i, p := range strings.Split(params, ",") {
if i != 0 { if i != 0 {
trimmed += ", " b.WriteString(", ")
} }
trimmed += fmt.Sprintf("${%v:%v}", i+1, r.Replace(strings.Trim(p, " "))) fmt.Fprintf(b, "${%v:%v}", i+1, r.Replace(strings.Trim(p, " ")))
} }
return trimmed + ")", false b.WriteByte(')')
return b.String(), false
} }
return label, false return label, false