1
0
mirror of https://github.com/golang/go synced 2024-09-30 18:28:32 -06:00
go/internal/lsp/completion.go
TheSecEng b2d8b03366 internal/lsp: remove VS Code-specific completion hack
This hack was previously being used to correct the rankings for VS Code
Go users. This logic has since been moved into the VS Code Go plugin.

Change-Id: Ia6bff53eb2c6dbe479faa1fd0667d763837eea78
GitHub-Last-Rev: e7fed76b3f85b0db3b705cbb6945cecd855d2c7b
GitHub-Pull-Request: golang/tools#225
Reviewed-on: https://go-review.googlesource.com/c/tools/+/231098
Reviewed-by: Rebecca Stambler <rstambler@golang.org>
2020-06-30 15:48:51 +00:00

112 lines
3.3 KiB
Go

// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package lsp
import (
"context"
"fmt"
"strings"
"golang.org/x/tools/internal/event"
"golang.org/x/tools/internal/lsp/debug/tag"
"golang.org/x/tools/internal/lsp/protocol"
"golang.org/x/tools/internal/lsp/source"
)
func (s *Server) completion(ctx context.Context, params *protocol.CompletionParams) (*protocol.CompletionList, error) {
snapshot, fh, ok, err := s.beginFileRequest(ctx, params.TextDocument.URI, source.UnknownKind)
if !ok {
return nil, err
}
var candidates []source.CompletionItem
var surrounding *source.Selection
switch fh.Kind() {
case source.Go:
candidates, surrounding, err = source.Completion(ctx, snapshot, fh, params.Position)
case source.Mod:
candidates, surrounding = nil, nil
}
if err != nil {
event.Error(ctx, "no completions found", err, tag.Position.Of(params.Position))
}
if candidates == nil {
return &protocol.CompletionList{
Items: []protocol.CompletionItem{},
}, nil
}
// We might need to adjust the position to account for the prefix.
rng, err := surrounding.Range()
if err != nil {
return nil, err
}
// When using deep completions/fuzzy matching, report results as incomplete so
// client fetches updated completions after every key stroke.
options := snapshot.View().Options()
incompleteResults := options.DeepCompletion || options.Matcher == source.Fuzzy
items := toProtocolCompletionItems(candidates, rng, options)
return &protocol.CompletionList{
IsIncomplete: incompleteResults,
Items: items,
}, nil
}
func toProtocolCompletionItems(candidates []source.CompletionItem, rng protocol.Range, options source.Options) []protocol.CompletionItem {
var (
items = make([]protocol.CompletionItem, 0, len(candidates))
numDeepCompletionsSeen int
)
for i, candidate := range candidates {
// Limit the number of deep completions to not overwhelm the user in cases
// with dozens of deep completion matches.
if candidate.Depth > 0 {
if !options.DeepCompletion {
continue
}
if numDeepCompletionsSeen >= source.MaxDeepCompletions {
continue
}
numDeepCompletionsSeen++
}
insertText := candidate.InsertText
if options.InsertTextFormat == protocol.SnippetTextFormat {
insertText = candidate.Snippet()
}
// This can happen if the client has snippets disabled but the
// candidate only supports snippet insertion.
if insertText == "" {
continue
}
item := protocol.CompletionItem{
Label: candidate.Label,
Detail: candidate.Detail,
Kind: candidate.Kind,
TextEdit: &protocol.TextEdit{
NewText: insertText,
Range: rng,
},
InsertTextFormat: options.InsertTextFormat,
AdditionalTextEdits: candidate.AdditionalTextEdits,
// This is a hack so that the client sorts completion results in the order
// according to their score. This can be removed upon the resolution of
// https://github.com/Microsoft/language-server-protocol/issues/348.
SortText: fmt.Sprintf("%05d", i),
// Trim operators (VSCode doesn't like weird characters in
// filterText).
FilterText: strings.TrimLeft(candidate.InsertText, "&*"),
Preselect: i == 0,
Documentation: candidate.Documentation,
}
items = append(items, item)
}
return items
}