internal/lsp: match completions case-insensitively

Change-Id: I31f2ea338ae3e2ec2837a444705f990e140ebc77
Reviewed-on: https://go-review.googlesource.com/c/tools/+/184159
Run-TryBot: Rebecca Stambler <rstambler@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Cottrell <iancottrell@google.com>
This commit is contained in:
Rebecca Stambler 2019-06-27 16:28:22 -04:00
parent 85b1a4bcd4
commit 212fb13d59
4 changed files with 18 additions and 8 deletions

View File

@ -67,16 +67,21 @@ func (s *Server) completion(ctx context.Context, params *protocol.CompletionPara
const maxDeepCompletions = 3 const maxDeepCompletions = 3
func toProtocolCompletionItems(candidates []source.CompletionItem, prefix string, rng protocol.Range, insertTextFormat protocol.InsertTextFormat, usePlaceholders bool, useDeepCompletions bool) []protocol.CompletionItem { func toProtocolCompletionItems(candidates []source.CompletionItem, prefix string, rng protocol.Range, insertTextFormat protocol.InsertTextFormat, usePlaceholders bool, useDeepCompletions bool) []protocol.CompletionItem {
// Sort the candidates by score, since that is not supported by LSP yet.
sort.SliceStable(candidates, func(i, j int) bool { sort.SliceStable(candidates, func(i, j int) bool {
return candidates[i].Score > candidates[j].Score return candidates[i].Score > candidates[j].Score
}) })
// Matching against the prefix should be case insensitive.
prefix = strings.ToLower(prefix)
var ( var (
items = make([]protocol.CompletionItem, 0, len(candidates)) items = make([]protocol.CompletionItem, 0, len(candidates))
numDeepCompletionsSeen int numDeepCompletionsSeen int
) )
for i, candidate := range candidates { for i, candidate := range candidates {
// Match against the label. // Match against the label (case-insensitive).
if !strings.HasPrefix(candidate.Label, prefix) { if !strings.HasPrefix(strings.ToLower(candidate.Label), prefix) {
continue continue
} }

View File

@ -152,19 +152,19 @@ func (r *runner) Completion(t *testing.T, data tests.Completions, snippets tests
if err != nil { if err != nil {
t.Fatalf("failed for %v: %v", src, err) t.Fatalf("failed for %v: %v", src, err)
} }
var prefix string
if surrounding != nil {
prefix = strings.ToLower(surrounding.Prefix())
}
wantBuiltins := strings.Contains(string(src.URI()), "builtins") wantBuiltins := strings.Contains(string(src.URI()), "builtins")
var got []source.CompletionItem var got []source.CompletionItem
for _, item := range list { for _, item := range list {
if !wantBuiltins && isBuiltin(item) { if !wantBuiltins && isBuiltin(item) {
continue continue
} }
var prefix string
if surrounding != nil {
prefix = surrounding.Prefix()
}
// We let the client do fuzzy matching, so we return all possible candidates. // We let the client do fuzzy matching, so we return all possible candidates.
// To simplify testing, filter results with prefixes that don't match exactly. // To simplify testing, filter results with prefixes that don't match exactly.
if !strings.HasPrefix(item.Label, prefix) { if !strings.HasPrefix(strings.ToLower(item.Label), prefix) {
continue continue
} }
got = append(got, item) got = append(got, item)

View File

@ -1,5 +1,10 @@
package errors package errors
import (
"golang.org/x/tools/internal/lsp/types"
)
func _() { func _() {
bob.Bob() //@complete(".") bob.Bob() //@complete(".")
types.b //@complete(" //", Bob_interface)
} }

View File

@ -25,7 +25,7 @@ import (
// We hardcode the expected number of test cases to ensure that all tests // We hardcode the expected number of test cases to ensure that all tests
// are being executed. If a test is added, this number must be changed. // are being executed. If a test is added, this number must be changed.
const ( const (
ExpectedCompletionsCount = 136 ExpectedCompletionsCount = 137
ExpectedCompletionSnippetCount = 15 ExpectedCompletionSnippetCount = 15
ExpectedDiagnosticsCount = 17 ExpectedDiagnosticsCount = 17
ExpectedFormatCount = 5 ExpectedFormatCount = 5