1
0
mirror of https://github.com/golang/go synced 2024-11-18 14:54:40 -07:00

internal/lsp: merge completion options into source.Options

This change flattens the completion options type into UserOptions and
DebuggingOptions, which will enable us to generate documentation for
these options more effectively. This results in some modifications in
the tests.

Additionally, the fuzzyMatching and caseSensitive boolean flags are
merged into one setting, matcher, which can be used to specify the type
of matcher that is used for completion. Other requests (notably
workspaceSymbols) may need to use a matcher in the future.

Change-Id: I185875e50351be4090c7a2b3340d40286dc9f4a0
Reviewed-on: https://go-review.googlesource.com/c/tools/+/212635
Run-TryBot: Rebecca Stambler <rstambler@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Heschi Kreinick <heschi@google.com>
This commit is contained in:
Rebecca Stambler 2019-12-29 02:22:12 -05:00
parent 6316571e2c
commit 8f45075ebc
10 changed files with 176 additions and 117 deletions

View File

@ -24,7 +24,6 @@ func (s *Server) completion(ctx context.Context, params *protocol.CompletionPara
return nil, err
}
snapshot := view.Snapshot()
options := view.Options()
fh, err := snapshot.GetFile(uri)
if err != nil {
return nil, err
@ -33,8 +32,7 @@ func (s *Server) completion(ctx context.Context, params *protocol.CompletionPara
var surrounding *source.Selection
switch fh.Identity().Kind {
case source.Go:
options.Completion.FullDocumentation = options.HoverKind == source.FullDocumentation
candidates, surrounding, err = source.Completion(ctx, snapshot, fh, params.Position, options.Completion)
candidates, surrounding, err = source.Completion(ctx, snapshot, fh, params.Position)
case source.Mod:
candidates, surrounding = nil, nil
}
@ -62,7 +60,8 @@ func (s *Server) completion(ctx context.Context, params *protocol.CompletionPara
// When using deep completions/fuzzy matching, report results as incomplete so
// client fetches updated completions after every key stroke.
incompleteResults := options.Completion.Deep || options.Completion.FuzzyMatching
options := view.Options()
incompleteResults := options.DeepCompletion || options.Matcher == source.Fuzzy
items := toProtocolCompletionItems(candidates, rng, options)
@ -94,7 +93,7 @@ func toProtocolCompletionItems(candidates []source.CompletionItem, rng protocol.
// 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.Completion.Deep {
if !options.DeepCompletion {
continue
}
if numDeepCompletionsSeen >= source.MaxDeepCompletions {

View File

@ -11,11 +11,10 @@ import (
)
func (r *runner) Completion(t *testing.T, src span.Span, test tests.Completion, items tests.CompletionItems) {
got := r.callCompletion(t, src, source.CompletionOptions{
Deep: false,
FuzzyMatching: false,
Documentation: true,
Literal: strings.Contains(string(src.URI()), "literal"),
got := r.callCompletion(t, src, func(opts *source.Options) {
opts.DeepCompletion = false
opts.Matcher = source.CaseInsensitive
opts.Literal = strings.Contains(string(src.URI()), "literal")
})
if !strings.Contains(string(src.URI()), "builtins") {
got = tests.FilterBuiltins(got)
@ -27,11 +26,11 @@ func (r *runner) Completion(t *testing.T, src span.Span, test tests.Completion,
}
func (r *runner) CompletionSnippet(t *testing.T, src span.Span, expected tests.CompletionSnippet, placeholders bool, items tests.CompletionItems) {
list := r.callCompletion(t, src, source.CompletionOptions{
Placeholders: placeholders,
Deep: true,
FuzzyMatching: true,
Literal: true,
list := r.callCompletion(t, src, func(opts *source.Options) {
opts.Placeholders = placeholders
opts.DeepCompletion = true
opts.Matcher = source.Fuzzy
opts.Literal = true
})
got := tests.FindItem(list, *items[expected.CompletionItem])
want := expected.PlainSnippet
@ -44,8 +43,8 @@ func (r *runner) CompletionSnippet(t *testing.T, src span.Span, expected tests.C
}
func (r *runner) UnimportedCompletion(t *testing.T, src span.Span, test tests.Completion, items tests.CompletionItems) {
got := r.callCompletion(t, src, source.CompletionOptions{
Unimported: true,
got := r.callCompletion(t, src, func(opts *source.Options) {
opts.UnimportedCompletion = true
})
if !strings.Contains(string(src.URI()), "builtins") {
got = tests.FilterBuiltins(got)
@ -57,9 +56,9 @@ func (r *runner) UnimportedCompletion(t *testing.T, src span.Span, test tests.Co
}
func (r *runner) DeepCompletion(t *testing.T, src span.Span, test tests.Completion, items tests.CompletionItems) {
got := r.callCompletion(t, src, source.CompletionOptions{
Deep: true,
Documentation: true,
got := r.callCompletion(t, src, func(opts *source.Options) {
opts.DeepCompletion = true
opts.Matcher = source.CaseInsensitive
})
if !strings.Contains(string(src.URI()), "builtins") {
got = tests.FilterBuiltins(got)
@ -71,9 +70,9 @@ func (r *runner) DeepCompletion(t *testing.T, src span.Span, test tests.Completi
}
func (r *runner) FuzzyCompletion(t *testing.T, src span.Span, test tests.Completion, items tests.CompletionItems) {
got := r.callCompletion(t, src, source.CompletionOptions{
FuzzyMatching: true,
Deep: true,
got := r.callCompletion(t, src, func(opts *source.Options) {
opts.DeepCompletion = true
opts.Matcher = source.Fuzzy
})
if !strings.Contains(string(src.URI()), "builtins") {
got = tests.FilterBuiltins(got)
@ -85,8 +84,8 @@ func (r *runner) FuzzyCompletion(t *testing.T, src span.Span, test tests.Complet
}
func (r *runner) CaseSensitiveCompletion(t *testing.T, src span.Span, test tests.Completion, items tests.CompletionItems) {
got := r.callCompletion(t, src, source.CompletionOptions{
CaseSensitive: true,
got := r.callCompletion(t, src, func(opts *source.Options) {
opts.Matcher = source.CaseSensitive
})
if !strings.Contains(string(src.URI()), "builtins") {
got = tests.FilterBuiltins(got)
@ -98,10 +97,10 @@ func (r *runner) CaseSensitiveCompletion(t *testing.T, src span.Span, test tests
}
func (r *runner) RankCompletion(t *testing.T, src span.Span, test tests.Completion, items tests.CompletionItems) {
got := r.callCompletion(t, src, source.CompletionOptions{
FuzzyMatching: true,
Deep: true,
Literal: true,
got := r.callCompletion(t, src, func(opts *source.Options) {
opts.DeepCompletion = true
opts.Matcher = source.Fuzzy
opts.Literal = true
})
want := expected(t, test, items)
if msg := tests.CheckCompletionOrder(want, got, true); msg != "" {
@ -120,7 +119,7 @@ func expected(t *testing.T, test tests.Completion, items tests.CompletionItems)
return want
}
func (r *runner) callCompletion(t *testing.T, src span.Span, options source.CompletionOptions) []protocol.CompletionItem {
func (r *runner) callCompletion(t *testing.T, src span.Span, options func(*source.Options)) []protocol.CompletionItem {
t.Helper()
view, err := r.server.session.ViewOf(src.URI())
@ -129,8 +128,7 @@ func (r *runner) callCompletion(t *testing.T, src span.Span, options source.Comp
}
original := view.Options()
modified := original
modified.InsertTextFormat = protocol.SnippetTextFormat
modified.Completion = options
options(&modified)
view, err = view.SetOptions(r.ctx, modified)
if err != nil {
t.Error(err)

View File

@ -131,9 +131,8 @@ func (ipm insensitivePrefixMatcher) Score(candidateLabel string) float32 {
type completer struct {
snapshot Snapshot
pkg Package
qf types.Qualifier
opts CompletionOptions
qf types.Qualifier
opts *completionOptions
// ctx is the context associated with this completion request.
ctx context.Context
@ -247,10 +246,10 @@ func (p Selection) Suffix() string {
}
func (c *completer) deepCompletionContext() (context.Context, context.CancelFunc) {
if c.opts.Budget == 0 {
if c.opts.budget == 0 {
return context.WithCancel(c.ctx)
}
return context.WithDeadline(c.ctx, c.startTime.Add(c.opts.Budget))
return context.WithDeadline(c.ctx, c.startTime.Add(c.opts.budget))
}
func (c *completer) setSurrounding(ident *ast.Ident) {
@ -268,11 +267,12 @@ func (c *completer) setSurrounding(ident *ast.Ident) {
mappedRange: newMappedRange(c.snapshot.View().Session().Cache().FileSet(), c.mapper, ident.Pos(), ident.End()),
}
if c.opts.FuzzyMatching {
switch c.opts.matcher {
case Fuzzy:
c.matcher = fuzzy.NewMatcher(c.surrounding.Prefix())
} else if c.opts.CaseSensitive {
case CaseSensitive:
c.matcher = prefixMatcher(c.surrounding.Prefix())
} else {
default:
c.matcher = insensitivePrefixMatcher(strings.ToLower(c.surrounding.Prefix()))
}
}
@ -405,7 +405,7 @@ func (e ErrIsDefinition) Error() string {
// The selection is computed based on the preceding identifier and can be used by
// the client to score the quality of the completion. For instance, some clients
// may tolerate imperfect matches as valid completion results, since users may make typos.
func Completion(ctx context.Context, snapshot Snapshot, fh FileHandle, pos protocol.Position, opts CompletionOptions) ([]CompletionItem, *Selection, error) {
func Completion(ctx context.Context, snapshot Snapshot, fh FileHandle, pos protocol.Position) ([]CompletionItem, *Selection, error) {
ctx, done := trace.StartSpan(ctx, "source.Completion")
defer done()
@ -439,6 +439,7 @@ func Completion(ctx context.Context, snapshot Snapshot, fh FileHandle, pos proto
return nil, nil, nil
}
opts := snapshot.View().Options()
c := &completer{
pkg: pkg,
snapshot: snapshot,
@ -451,7 +452,16 @@ func Completion(ctx context.Context, snapshot Snapshot, fh FileHandle, pos proto
seen: make(map[types.Object]bool),
enclosingFunc: enclosingFunction(path, rng.Start, pkg.GetTypesInfo()),
enclosingCompositeLiteral: enclosingCompositeLiteral(path, rng.Start, pkg.GetTypesInfo()),
opts: opts,
opts: &completionOptions{
matcher: opts.Matcher,
deepCompletion: opts.DeepCompletion,
unimported: opts.UnimportedCompletion,
documentation: opts.CompletionDocumentation,
fullDocumentation: opts.HoverKind == FullDocumentation,
placeholders: opts.Placeholders,
literal: opts.Literal,
budget: opts.CompletionBudget,
},
// default to a matcher that always matches
matcher: prefixMatcher(""),
methodSetCache: make(map[methodSetKey]*types.MethodSet),
@ -459,7 +469,7 @@ func Completion(ctx context.Context, snapshot Snapshot, fh FileHandle, pos proto
startTime: startTime,
}
if opts.Deep {
if c.opts.deepCompletion {
// Initialize max search depth to unlimited.
c.deepState.maxDepth = -1
}
@ -629,7 +639,7 @@ func (c *completer) selector(sel *ast.SelectorExpr) error {
}
// Try unimported packages.
if id, ok := sel.X.(*ast.Ident); ok && c.opts.Unimported && len(c.items) < unimportedTarget {
if id, ok := sel.X.(*ast.Ident); ok && c.opts.unimported && len(c.items) < unimportedTarget {
if err := c.unimportedMembers(id); err != nil {
return err
}
@ -862,7 +872,7 @@ func (c *completer) lexical() error {
}
}
if c.opts.Unimported && len(c.items) < unimportedTarget {
if c.opts.unimported && len(c.items) < unimportedTarget {
ctx, cancel := c.deepCompletionContext()
defer cancel()
// Suggest packages that have not been imported yet.

View File

@ -168,7 +168,7 @@ func (c *completer) item(cand candidate) (CompletionItem, error) {
snippet: snip,
}
// If the user doesn't want documentation for completion items.
if !c.opts.Documentation {
if !c.opts.documentation {
return item, nil
}
pos := c.snapshot.View().Session().Cache().FileSet().Position(obj.Pos())
@ -200,7 +200,7 @@ func (c *completer) item(cand candidate) (CompletionItem, error) {
return item, nil
}
item.Documentation = hover.Synopsis
if c.opts.FullDocumentation {
if c.opts.fullDocumentation {
item.Documentation = hover.FullDocumentation
}
return item, nil

View File

@ -20,7 +20,7 @@ import (
// literal generates composite literal, function literal, and make()
// completion items.
func (c *completer) literal(literalType types.Type, imp *importInfo) {
if !c.opts.Literal {
if !c.opts.literal {
return
}
@ -213,7 +213,7 @@ func (c *completer) functionLiteral(sig *types.Signature, matchScore float64) {
// Our parameter names are guesses, so they must be placeholders
// for easy correction. If placeholders are disabled, don't
// offer the completion.
if !c.opts.Placeholders {
if !c.opts.placeholders {
return
}
@ -367,7 +367,7 @@ func (c *completer) makeCall(typeName string, secondArg string, matchScore float
if secondArg != "" {
snip.WriteText(", ")
snip.WritePlaceholder(func(b *snippet.Builder) {
if c.opts.Placeholders {
if c.opts.placeholders {
b.WriteText(secondArg)
}
})

View File

@ -36,7 +36,7 @@ func (c *completer) structFieldSnippet(label, detail string) *snippet.Builder {
snip.WriteText(label + ": ")
snip.WritePlaceholder(func(b *snippet.Builder) {
// A placeholder snippet turns "Foo{Ba<>" into "Foo{Bar: <*int*>".
if c.opts.Placeholders {
if c.opts.placeholders {
b.WriteText(detail)
}
})
@ -79,7 +79,7 @@ func (c *completer) functionCallSnippet(name string, params []string) *snippet.B
snip := &snippet.Builder{}
snip.WriteText(name + "(")
if c.opts.Placeholders {
if c.opts.placeholders {
// A placeholder snippet turns "someFun<>" into "someFunc(<*i int*>, *s string*)".
for i, p := range params {
if i > 0 {

View File

@ -107,8 +107,8 @@ func (c *completer) shouldPrune() bool {
}
// Check our remaining budget every 100 candidates.
if c.opts.Budget > 0 && c.deepState.candidateCount%100 == 0 {
spent := float64(time.Since(c.startTime)) / float64(c.opts.Budget)
if c.opts.budget > 0 && c.deepState.candidateCount%100 == 0 {
spent := float64(time.Since(c.startTime)) / float64(c.opts.budget)
switch {
case spent >= 0.90:

View File

@ -74,16 +74,13 @@ var (
},
}
DefaultUserOptions = UserOptions{
Env: os.Environ(),
HoverKind: SynopsisDocumentation,
Completion: CompletionOptions{
Documentation: true,
Deep: true,
FuzzyMatching: true,
Literal: true,
Budget: 100 * time.Millisecond,
},
LinkTarget: "pkg.go.dev",
Env: os.Environ(),
HoverKind: SynopsisDocumentation,
LinkTarget: "pkg.go.dev",
Matcher: Fuzzy,
DeepCompletion: true,
CompletionDocumentation: true,
Literal: true,
}
DefaultHooks = Hooks{
ComputeEdits: myers.ComputeEdits,
@ -94,7 +91,9 @@ var (
DefaultExperimentalOptions = ExperimentalOptions{
TempModfile: false,
}
DefaultDebuggingOptions = DebuggingOptions{}
DefaultDebuggingOptions = DebuggingOptions{
CompletionBudget: 100 * time.Millisecond,
}
)
type Options struct {
@ -142,7 +141,37 @@ type UserOptions struct {
// LocalPrefix is used to specify goimports's -local behavior.
LocalPrefix string
Completion CompletionOptions
// Matcher specifies the type of matcher to use for completion requests.
Matcher Matcher
// DeepCompletion allows completion to perform nested searches through
// possible candidates.
DeepCompletion bool
// UnimportedCompletion enables completion for unimported packages.
UnimportedCompletion bool
// CompletionDocumentation returns additional documentation with completion
// requests.
CompletionDocumentation bool
// Placeholders adds placeholders to parameters and structs in completion
// results.
Placeholders bool
// Literal enables completion for map, slice, and function literals.
Literal bool
}
type completionOptions struct {
deepCompletion bool
unimported bool
documentation bool
fullDocumentation bool
placeholders bool
literal bool
matcher Matcher
budget time.Duration
}
type Hooks struct {
@ -161,26 +190,23 @@ type ExperimentalOptions struct {
type DebuggingOptions struct {
VerboseOutput bool
}
type CompletionOptions struct {
Deep bool
FuzzyMatching bool
CaseSensitive bool
Unimported bool
Documentation bool
FullDocumentation bool
Placeholders bool
Literal bool
// Budget is the soft latency goal for completion requests. Most
// CompletionBudget is the soft latency goal for completion requests. Most
// requests finish in a couple milliseconds, but in some cases deep
// completions can take much longer. As we use up our budget we
// dynamically reduce the search scope to ensure we return timely
// results. Zero means unlimited.
Budget time.Duration
CompletionBudget time.Duration
}
type Matcher int
const (
Fuzzy = Matcher(iota)
CaseInsensitive
CaseSensitive
)
type HoverKind int
const (
@ -280,17 +306,13 @@ func (o *Options) set(name string, value interface{}) OptionResult {
o.BuildFlags = flags
case "completionDocumentation":
result.setBool(&o.Completion.Documentation)
result.setBool(&o.CompletionDocumentation)
case "usePlaceholders":
result.setBool(&o.Completion.Placeholders)
result.setBool(&o.Placeholders)
case "deepCompletion":
result.setBool(&o.Completion.Deep)
case "fuzzyMatching":
result.setBool(&o.Completion.FuzzyMatching)
case "caseSensitiveCompletion":
result.setBool(&o.Completion.CaseSensitive)
result.setBool(&o.DeepCompletion)
case "completeUnimported":
result.setBool(&o.Completion.Unimported)
result.setBool(&o.UnimportedCompletion)
case "completionBudget":
if v, ok := result.asString(); ok {
d, err := time.ParseDuration(v)
@ -298,13 +320,26 @@ func (o *Options) set(name string, value interface{}) OptionResult {
result.errorf("failed to parse duration %q: %v", v, err)
break
}
o.Completion.Budget = d
o.CompletionBudget = d
}
case "matcher":
matcher, ok := result.asString()
if !ok {
break
}
switch matcher {
case "fuzzy":
o.Matcher = Fuzzy
case "caseSensitive":
o.Matcher = CaseSensitive
default:
o.Matcher = CaseInsensitive
}
case "hoverKind":
hoverKind, ok := value.(string)
hoverKind, ok := result.asString()
if !ok {
result.errorf("invalid type %T for string option %q", value, name)
break
}
switch hoverKind {
@ -378,6 +413,14 @@ func (o *Options) set(name string, value interface{}) OptionResult {
result.State = OptionDeprecated
result.Replacement = "completeUnimported"
case "fuzzyMatching":
result.State = OptionDeprecated
result.Replacement = "matcher"
case "caseSensitiveCompletion":
result.State = OptionDeprecated
result.Replacement = "matcher"
case "noIncrementalSync":
result.State = OptionDeprecated

View File

@ -107,10 +107,10 @@ func (r *runner) Completion(t *testing.T, src span.Span, test tests.Completion,
for _, pos := range test.CompletionItems {
want = append(want, tests.ToProtocolCompletionItem(*items[pos]))
}
prefix, list := r.callCompletion(t, src, source.CompletionOptions{
Documentation: true,
FuzzyMatching: true,
Literal: strings.Contains(string(src.URI()), "literal"),
prefix, list := r.callCompletion(t, src, func(opts *source.Options) {
opts.Matcher = source.Fuzzy
opts.Literal = strings.Contains(string(src.URI()), "literal")
opts.DeepCompletion = false
})
if !strings.Contains(string(src.URI()), "builtins") {
list = tests.FilterBuiltins(list)
@ -128,10 +128,10 @@ func (r *runner) Completion(t *testing.T, src span.Span, test tests.Completion,
}
func (r *runner) CompletionSnippet(t *testing.T, src span.Span, expected tests.CompletionSnippet, placeholders bool, items tests.CompletionItems) {
_, list := r.callCompletion(t, src, source.CompletionOptions{
Placeholders: placeholders,
Deep: true,
Literal: true,
_, list := r.callCompletion(t, src, func(opts *source.Options) {
opts.Placeholders = placeholders
opts.DeepCompletion = true
opts.Literal = true
})
got := tests.FindItem(list, *items[expected.CompletionItem])
want := expected.PlainSnippet
@ -148,8 +148,8 @@ func (r *runner) UnimportedCompletion(t *testing.T, src span.Span, test tests.Co
for _, pos := range test.CompletionItems {
want = append(want, tests.ToProtocolCompletionItem(*items[pos]))
}
_, got := r.callCompletion(t, src, source.CompletionOptions{
Unimported: true,
_, got := r.callCompletion(t, src, func(opts *source.Options) {
opts.UnimportedCompletion = true
})
if !strings.Contains(string(src.URI()), "builtins") {
got = tests.FilterBuiltins(got)
@ -164,9 +164,9 @@ func (r *runner) DeepCompletion(t *testing.T, src span.Span, test tests.Completi
for _, pos := range test.CompletionItems {
want = append(want, tests.ToProtocolCompletionItem(*items[pos]))
}
prefix, list := r.callCompletion(t, src, source.CompletionOptions{
Deep: true,
Documentation: true,
prefix, list := r.callCompletion(t, src, func(opts *source.Options) {
opts.DeepCompletion = true
opts.Matcher = source.CaseInsensitive
})
if !strings.Contains(string(src.URI()), "builtins") {
list = tests.FilterBuiltins(list)
@ -189,9 +189,9 @@ func (r *runner) FuzzyCompletion(t *testing.T, src span.Span, test tests.Complet
for _, pos := range test.CompletionItems {
want = append(want, tests.ToProtocolCompletionItem(*items[pos]))
}
_, got := r.callCompletion(t, src, source.CompletionOptions{
FuzzyMatching: true,
Deep: true,
_, got := r.callCompletion(t, src, func(opts *source.Options) {
opts.DeepCompletion = true
opts.Matcher = source.Fuzzy
})
if !strings.Contains(string(src.URI()), "builtins") {
got = tests.FilterBuiltins(got)
@ -206,8 +206,8 @@ func (r *runner) CaseSensitiveCompletion(t *testing.T, src span.Span, test tests
for _, pos := range test.CompletionItems {
want = append(want, tests.ToProtocolCompletionItem(*items[pos]))
}
_, list := r.callCompletion(t, src, source.CompletionOptions{
CaseSensitive: true,
_, list := r.callCompletion(t, src, func(opts *source.Options) {
opts.Matcher = source.CaseSensitive
})
if !strings.Contains(string(src.URI()), "builtins") {
list = tests.FilterBuiltins(list)
@ -222,25 +222,34 @@ func (r *runner) RankCompletion(t *testing.T, src span.Span, test tests.Completi
for _, pos := range test.CompletionItems {
want = append(want, tests.ToProtocolCompletionItem(*items[pos]))
}
_, got := r.callCompletion(t, src, source.CompletionOptions{
FuzzyMatching: true,
Deep: true,
Literal: true,
_, got := r.callCompletion(t, src, func(opts *source.Options) {
opts.DeepCompletion = true
opts.Matcher = source.Fuzzy
opts.Literal = true
})
if msg := tests.CheckCompletionOrder(want, got, true); msg != "" {
t.Errorf("%s: %s", src, msg)
}
}
func (r *runner) callCompletion(t *testing.T, src span.Span, options source.CompletionOptions) (string, []protocol.CompletionItem) {
func (r *runner) callCompletion(t *testing.T, src span.Span, options func(*source.Options)) (string, []protocol.CompletionItem) {
fh, err := r.view.Snapshot().GetFile(src.URI())
if err != nil {
t.Fatal(err)
}
list, surrounding, err := source.Completion(r.ctx, r.view.Snapshot(), fh, protocol.Position{
original := r.view.Options()
modified := original
options(&modified)
view, err := r.view.SetOptions(r.ctx, modified)
if err != nil {
t.Fatal(err)
}
defer r.view.SetOptions(r.ctx, original)
list, surrounding, err := source.Completion(r.ctx, view.Snapshot(), fh, protocol.Position{
Line: float64(src.Start().Line() - 1),
Character: float64(src.Start().Column() - 1),
}, options)
})
if err != nil && !errors.As(err, &source.ErrIsDefinition{}) {
t.Fatalf("failed for %v: %v", src, err)
}
@ -261,7 +270,7 @@ func (r *runner) callCompletion(t *testing.T, src span.Span, options source.Comp
// Apply deep completion filtering.
for _, item := range list {
if item.Depth > 0 {
if !options.Deep {
if !modified.DeepCompletion {
continue
}
if numDeepCompletionsSeen >= source.MaxDeepCompletions {

View File

@ -191,7 +191,7 @@ func DefaultOptions() source.Options {
}
o.HoverKind = source.SynopsisDocumentation
o.InsertTextFormat = protocol.SnippetTextFormat
o.Completion.Budget = time.Minute
o.CompletionBudget = time.Minute
return o
}