diff --git a/internal/lsp/source/completion.go b/internal/lsp/source/completion.go index b6193c5728..a9c599bbcb 100644 --- a/internal/lsp/source/completion.go +++ b/internal/lsp/source/completion.go @@ -384,8 +384,9 @@ type candidate struct { // makePointer is true if the candidate type name T should be made into *T. makePointer bool - // dereference is true if the candidate obj should be made into *obj. - dereference bool + // dereference is a count of how many times to dereference the candidate obj. + // For example, dereference=2 turns "foo" into "**foo" when formatting. + dereference int // imp is the import that needs to be added to this package in order // for this candidate to be valid. nil if no import needed. @@ -1804,9 +1805,10 @@ func (c *completer) matchingCandidate(cand *candidate, seen map[types.Type]struc seen[cand.obj.Type()] = struct{}{} } - if !saw && c.matchingCandidate(&candidate{obj: c.fakeObj(ptr.Elem())}, seen) { + fakeCandidate := candidate{obj: c.fakeObj(ptr.Elem())} + if !saw && c.matchingCandidate(&fakeCandidate, seen) { // Mark the candidate so we know to prepend "*" when formatting. - cand.dereference = true + cand.dereference = 1 + fakeCandidate.dereference return true } } diff --git a/internal/lsp/source/completion_format.go b/internal/lsp/source/completion_format.go index c5e8bbd8df..f44b553eba 100644 --- a/internal/lsp/source/completion_format.go +++ b/internal/lsp/source/completion_format.go @@ -134,8 +134,10 @@ func (c *completer) item(cand candidate) (CompletionItem, error) { var prefixOp string if cand.takeAddress { prefixOp = "&" - } else if cand.makePointer || cand.dereference { + } else if cand.makePointer { prefixOp = "*" + } else if cand.dereference > 0 { + prefixOp = strings.Repeat("*", cand.dereference) } if prefixOp != "" { diff --git a/internal/lsp/testdata/lsp/primarymod/address/address.go b/internal/lsp/testdata/lsp/primarymod/address/address.go index f1c95280ae..59d5d4c9e1 100644 --- a/internal/lsp/testdata/lsp/primarymod/address/address.go +++ b/internal/lsp/testdata/lsp/primarymod/address/address.go @@ -37,6 +37,10 @@ func _() { wantsVariadic() //@rank(")", addrCPtr, addrA),snippet(")", addrCPtr, "*c", "*c") + var d **int + **d //@item(addrDPtr, "**d", "**int", "var") + var _ int = _ //@rank("_ //", addrDPtr, addrA),snippet("_ //", addrDPtr, "**d", "**d") + type namedPtr *int var np namedPtr *np //@item(addrNamedPtr, "*np", "namedPtr", "var") diff --git a/internal/lsp/testdata/lsp/summary.txt.golden b/internal/lsp/testdata/lsp/summary.txt.golden index d6d706caca..c5efd04365 100644 --- a/internal/lsp/testdata/lsp/summary.txt.golden +++ b/internal/lsp/testdata/lsp/summary.txt.golden @@ -1,10 +1,10 @@ -- summary -- CompletionsCount = 227 -CompletionSnippetCount = 66 +CompletionSnippetCount = 67 UnimportedCompletionsCount = 11 DeepCompletionsCount = 5 FuzzyCompletionsCount = 8 -RankedCompletionsCount = 84 +RankedCompletionsCount = 86 CaseSensitiveCompletionsCount = 4 DiagnosticsCount = 38 FoldingRangesCount = 2