gopls/completion: prepend space when completing right after "//" before a declaration
When a user places the cursor immediately after "//" (no space) on a
line directly above a declaration, gopls already suggests the
declaration name as a completion candidate. However the inserted text
lacked the conventional space, producing "//Name" instead of the
proper Go doc comment form "// Name".
Detect this case in populateCommentCompletions (cursor at slash+2
with comment text exactly "//") and set a new
commentNeedsLeadingSpace flag on the completionContext. item() checks
the flag and prepends a space to the insert text (and snippet), so
accepting the completion yields "// Name".
A marker test is added to comment.txt asserting that a function name
is offered when the cursor is right after "//" directly above its
declaration. All existing completion marker tests continue to pass.
Fixes golang/go#76374
diff --git a/gopls/internal/golang/completion/completion.go b/gopls/internal/golang/completion/completion.go
index 314165a..f84bf63 100644
--- a/gopls/internal/golang/completion/completion.go
+++ b/gopls/internal/golang/completion/completion.go
@@ -366,6 +366,12 @@
// commentCompletion is true if we are completing a comment.
commentCompletion bool
+ // commentNeedsLeadingSpace is true when completing a comment whose text
+ // is exactly "//" (cursor placed immediately after the slashes, with no
+ // space). Completion items should prepend a space so that accepting a
+ // suggestion produces "// Name" rather than "//Name".
+ commentNeedsLeadingSpace bool
+
// packageCompletion is true if we are completing a package name.
packageCompletion bool
}
@@ -1049,6 +1055,16 @@
// comment is valid, set surrounding as word boundaries around cursor
c.setSurroundingForComment(comment)
+ // If the cursor is placed immediately after "//" with no following text,
+ // completions must prepend a space to produce proper Go doc comment style
+ // ("// Name" rather than "//Name").
+ for _, cmt := range comment.List {
+ if c.pos == cmt.Slash+2 && cmt.Text == "//" {
+ c.completionContext.commentNeedsLeadingSpace = true
+ break
+ }
+ }
+
// Using the next line pos, grab and parse the exported symbol on that line
for _, n := range c.pgf.File.Decls {
declLine := safetoken.Line(file, n.Pos())
diff --git a/gopls/internal/golang/completion/format.go b/gopls/internal/golang/completion/format.go
index 9f5d277..7b2e802 100644
--- a/gopls/internal/golang/completion/format.go
+++ b/gopls/internal/golang/completion/format.go
@@ -229,6 +229,14 @@
if cand.detail != "" {
detail = cand.detail
}
+
+ // When completing right after "//" (cursor at the slashes with no space),
+ // prepend a space so the result is "// Name" rather than "//Name".
+ if c.completionContext.commentNeedsLeadingSpace {
+ insert = " " + insert
+ snip.PrependText(" ")
+ }
+
item := CompletionItem{
Label: label,
InsertText: insert,
diff --git a/gopls/internal/test/marker/testdata/completion/comment.txt b/gopls/internal/test/marker/testdata/completion/comment.txt
index 57a3882..da5e32e 100644
--- a/gopls/internal/test/marker/testdata/completion/comment.txt
+++ b/gopls/internal/test/marker/testdata/completion/comment.txt
@@ -72,6 +72,11 @@
return 0
}
+// This tests that completing right after "//" (no space) above a declaration
+// suggests the identifier name, prepending a space for proper doc comment style.
+//@complete(re"//()", plainFunc)
+func PlainFunc() {} //@item(plainFunc, "PlainFunc", "func()", "func")
+
// This tests multiline block comments and completion with prefix
// Lorem Ipsum Multili//@complete(re"()Multi", multiline)
// Lorem ipsum dolor sit ametom
| Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. |
commentNeedsLeadingSpace boolThe fix in this CL seems rather narrowly tailored to the specific text of the test case in the attached issue: it works only if completion is triggered on the `//` without additional characters. It might be more useful to check whether the completion's edit range (being replaced) begins immediately after "//" without a space.
| Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. |
| Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. |
Thanks for the feedback. You're right that the check was too narrow.
I've updated it to use c.surrounding.start (the start of the edit range, set by setSurroundingForComment) instead of checking c.pos == cmt.Slash+2 && cmt.Text == "//". If the edit range starts immediately at slash+2, there is no space between // and the identifier being replaced, so completions should prepend a space — regardless of how many characters the user has already typed (e.g. //Foo still gets // FooBar).
Also added a marker test for the partial-prefix case (//Plain → // PlainFunc).
The fix in this CL seems rather narrowly tailored to the specific text of the test case in the attached issue: it works only if completion is triggered on the `//` without additional characters. It might be more useful to check whether the completion's edit range (being replaced) begins immediately after "//" without a space.
Done
| Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. |
| Auto-Submit | +1 |
| Code-Review | +2 |
| Commit-Queue | +1 |
Looks good. Thanks for contributing this fix!
| Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. |
The CI failure is in gopls/internal/debug with package "bufio" without types — this appears to be a pre-existing infrastructure issue unrelated to this CL. Could you re-add Commit-Queue+1?
| Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. |