From bc8aaaa29e0665201b38fa5cb5d47826788fa249 Mon Sep 17 00:00:00 2001 From: Danish Dua Date: Mon, 24 Aug 2020 19:49:55 -0400 Subject: [PATCH] internal/lsp: ignore period ('.') triggered completions in comments Period triggered completions don't provide any use in comments and in worst case can be nuisance. LSP provides a completion context which provides more info about what triggered a completion and hence we can use this to ignore period triggererd completions. This will also provide us options to deal with retriggered completions etc. better in the future. Change-Id: I8449aee0fe3cf5f9acf315865ac854d5c894d044 Reviewed-on: https://go-review.googlesource.com/c/tools/+/250337 Run-TryBot: Danish Dua TryBot-Result: Gobot Gobot Reviewed-by: Rebecca Stambler --- internal/lsp/completion.go | 2 +- internal/lsp/source/completion.go | 14 ++++++++++++-- internal/lsp/source/source_test.go | 2 +- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/internal/lsp/completion.go b/internal/lsp/completion.go index aa285251b1..221ca9e2b6 100644 --- a/internal/lsp/completion.go +++ b/internal/lsp/completion.go @@ -25,7 +25,7 @@ func (s *Server) completion(ctx context.Context, params *protocol.CompletionPara var surrounding *source.Selection switch fh.Kind() { case source.Go: - candidates, surrounding, err = source.Completion(ctx, snapshot, fh, params.Position) + candidates, surrounding, err = source.Completion(ctx, snapshot, fh, params.Position, params.Context.TriggerCharacter) case source.Mod: candidates, surrounding = nil, nil } diff --git a/internal/lsp/source/completion.go b/internal/lsp/source/completion.go index bca2ac2e64..43eb01c001 100644 --- a/internal/lsp/source/completion.go +++ b/internal/lsp/source/completion.go @@ -141,6 +141,9 @@ type completer struct { qf types.Qualifier opts *completionOptions + // triggerCharacter is the character that triggered this request, if any. + triggerCharacter string + // filename is the name of the file associated with this completion request. filename string @@ -460,7 +463,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, protoPos protocol.Position) ([]CompletionItem, *Selection, error) { +func Completion(ctx context.Context, snapshot Snapshot, fh FileHandle, protoPos protocol.Position, triggerCharacter string) ([]CompletionItem, *Selection, error) { ctx, done := event.Start(ctx, "source.Completion") defer done() @@ -519,6 +522,7 @@ func Completion(ctx context.Context, snapshot Snapshot, fh FileHandle, protoPos pkg: pkg, snapshot: snapshot, qf: qualifier(pgf.File, pkg.GetTypes(), pkg.GetTypesInfo()), + triggerCharacter: triggerCharacter, filename: fh.URI().Filename(), file: pgf.File, path: path, @@ -732,8 +736,14 @@ func (c *completer) emptySwitchStmt() bool { } } -// populateCommentCompletions yields completions for comments preceding or in declarationss +// populateCommentCompletions yields completions for comments preceding or in declarations func (c *completer) populateCommentCompletions(ctx context.Context, comment *ast.CommentGroup) { + // If the completion was triggered by a period, ignore it. These types of + // completions will not be useful in comments. + if c.triggerCharacter == "." { + return + } + // Using the comment position find the line after file := c.snapshot.FileSet().File(comment.End()) if file == nil { diff --git a/internal/lsp/source/source_test.go b/internal/lsp/source/source_test.go index 657b98ec1e..85f55bd1c8 100644 --- a/internal/lsp/source/source_test.go +++ b/internal/lsp/source/source_test.go @@ -307,7 +307,7 @@ func (r *runner) callCompletion(t *testing.T, src span.Span, options func(*sourc list, surrounding, err := source.Completion(r.ctx, r.snapshot, fh, protocol.Position{ Line: float64(src.Start().Line() - 1), Character: float64(src.Start().Column() - 1), - }) + }, "") if err != nil && !errors.As(err, &source.ErrIsDefinition{}) { t.Fatalf("failed for %v: %v", src, err) }