Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

x/tools/cmd/gopls: completions don't expand correctly in Emacs #32078

Closed
muirdm opened this issue May 16, 2019 · 12 comments
Closed

x/tools/cmd/gopls: completions don't expand correctly in Emacs #32078

muirdm opened this issue May 16, 2019 · 12 comments
Labels
FrozenDueToAge gopls Issues related to the Go language server, gopls.
Milestone

Comments

@muirdm
Copy link

muirdm commented May 16, 2019

In Emacs when accepting a completion candidate, the already typed prefix is not replaced properly:

EmacsComplete

When we set the newText's range we properly move the range's start back to the start of the prefix, but we also move the range's end to the start of the prefix, so we end up just inserting the completion without overwriting anything. I think we need to leave the range's end at the cursor position so the prefix is overwritten. I'm not sure why VSCode doesn't show the same problem.

/cc @stamblerre

@gopherbot gopherbot added this to the Unreleased milestone May 16, 2019
@gopherbot gopherbot added the gopls Issues related to the Go language server, gopls. label May 16, 2019
@stamblerre
Copy link
Contributor

My guess is VSCode only ever cares about the start. Thanks for catching this. The earlier change actually broke vim-go because it wasn't using the positions coming from the completion items, so it also might be worth checking if Emacs does that.

I'm just wary of adding an end position at the original start because its technically not the end of the completion item. But then, to get the real end we would have to get the length of the insertText, which will include special characters that shouldn't be counted...

@muirdm
Copy link
Author

muirdm commented May 16, 2019

I'm just wary of adding an end position at the original start because its technically not the end of the completion item

The end of the range needs to to be the end of the text you are overwriting, not the end of the text you are inserting. Setting the end to the cursor position is correct except for the postfix completion case. To handle postfix, you need to basically set the start to the start of the *ast.Ident, and the end to the end of the *ast.Ident.

@muirdm
Copy link
Author

muirdm commented May 16, 2019

it wasn't using the positions coming from the completion items, so it also might be worth checking if Emacs does that.

Emacs definitely uses the positions properly (and so does VSCode). I've been running with a patch that does what I describe above for a while since it is required for fuzzy matching (the typed prefix is not actually a prefix of the insertion text so you have to overwrite it).

The TextEdit range is the area of text you want to replace with the insertText. That's why you set start==end to insert text without replacing anything. As for why VSCode works, I would guess it sees start==end and the text after the cursor is a prefix of the completion item, so it automatically overwrites it.

interface TextEdit {
	/**
	 * The range of the text document to be manipulated. To insert
	 * text into a document create a range where start === end.
	 */
	range: Range;

@gopherbot
Copy link

Change https://golang.org/cl/177657 mentions this issue: internal/lsp: use ranges instead of positions in completion items

@Stumble
Copy link

Stumble commented May 17, 2019

Tested with newest company-lsp + this version of gopls, spaces after the completion point and some symbol is eaten.

Before completion:
Selection_077

After:
Selection_078

@stamblerre

@gopherbot
Copy link

Change https://golang.org/cl/177757 mentions this issue: internal/lsp: fix completion insertion

gopherbot pushed a commit to golang/tools that referenced this issue May 17, 2019
The insertion range for completion items was not right. The range's
end was 1 before the start. Fix by taking into account the length of
the prefix when generating the range start and end.

Now instead of a "prefix", we track the completion's
"surrounding". This is basically the start and end of the abutting
identifier along with the cursor position. When we insert the
completion text, we overwrite the entire identifier, not just the
prefix. This fixes postfix completion like completing "foo.<>Bar" to
"foo.BarBaz".

Fixes golang/go#32078
Fixes golang/go#32057

Change-Id: I9d065a413ff9a6e20ae662ff93ad0092c2007c1d
GitHub-Last-Rev: af5ab4d
GitHub-Pull-Request: #103
Reviewed-on: https://go-review.googlesource.com/c/tools/+/177757
Run-TryBot: Ian Cottrell <iancottrell@google.com>
Reviewed-by: Ian Cottrell <iancottrell@google.com>
@shackra
Copy link

shackra commented Jul 7, 2019

I installed recently gopls I'm experiencing this bug for some reason

@stamblerre
Copy link
Contributor

Which version of gopls are you using (gopls version)?

@shackra
Copy link

shackra commented Jul 8, 2019

@stamblerre version v0.1.1, built in $GOPATH mode

@stamblerre
Copy link
Contributor

My guess is that this is likely a bug with the Emacs integration, rather than gopls. This issue was fixed in gopls quite some time ago, but it's possible that some Emacs clients aren't looking at the correct insertion ranges provided by the TextEdit field of a completion item.

@muirdm
Copy link
Author

muirdm commented Jul 8, 2019

@shackra can you open a separate issue with details about what you are seeing including reproduction steps and gopls debug log if possible?

@shackra
Copy link

shackra commented Jul 8, 2019

@muirrn yes I can, will do that during the week

@golang golang locked and limited conversation to collaborators Jul 7, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge gopls Issues related to the Go language server, gopls.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants