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/internal/lsp: gopls does not support emacs lsp client #31178

Closed
saibing opened this issue Apr 1, 2019 · 19 comments
Closed

x/tools/internal/lsp: gopls does not support emacs lsp client #31178

saibing opened this issue Apr 1, 2019 · 19 comments
Labels
FrozenDueToAge gopls Issues related to the Go language server, gopls. NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Milestone

Comments

@saibing
Copy link

saibing commented Apr 1, 2019

The origin issue is on here: saibing/bingo#181

@gopherbot gopherbot added this to the Unreleased milestone Apr 1, 2019
@saibing
Copy link
Author

saibing commented Apr 1, 2019

@stamblerre

@stamblerre stamblerre added the gopls Issues related to the Go language server, gopls. label Apr 1, 2019
@andybons andybons added the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label Apr 1, 2019
@stamblerre stamblerre self-assigned this Apr 3, 2019
@parhamdoustdar
Copy link

parhamdoustdar commented Apr 4, 2019

So, I'm setting up the client configuration in lsp in Emacs as documented in the gopls wiki, and I'm getting this error when I try to run lsp:

panic: runtime error: index out of range

goroutine 18 [running]:
golang.org/x/tools/internal/lsp.(*Server).Initialized(0xc0001683f0, 0x14c5b60, 0xc0000a2000, 0x1789490, 0x1789490, 0x0)
	/Users/pdoustdar/src/gopath/src/golang.org/x/tools/internal/lsp/server.go:218 +0x339
golang.org/x/tools/internal/lsp/protocol.serverHandler.func1(0x14c5b60, 0xc0000a2000, 0xc000168460, 0xc0001c8020)
	/Users/pdoustdar/src/gopath/src/golang.org/x/tools/internal/lsp/protocol/server.go:75 +0x6e2
golang.org/x/tools/internal/jsonrpc2.(*Conn).Run.func1(0xc00009e900, 0xc000168460)
	/Users/pdoustdar/src/gopath/src/golang.org/x/tools/internal/jsonrpc2/jsonrpc2.go:276 +0xda
created by golang.org/x/tools/internal/jsonrpc2.(*Conn).Run
	/Users/pdoustdar/src/gopath/src/golang.org/x/tools/internal/jsonrpc2/jsonrpc2.go:270 +0xba

I'm using the HEAD of Emacs, and I'm using the latest version of gopls that I just pulled now.

For reference, here is what I'm using to create and store the client in Emacs:

(lsp-register-client
   (make-lsp-client :new-connection (lsp-stdio-connection "gopls")
                    :major-modes '(go-mode)
                    :server-id 'gopls))

Thanks for all your work on gopls, I really appreciate it!

@stamblerre
Copy link
Contributor

Just filed emacs-lsp/lsp-mode#747, so hopefully we can get this resolved soon.

In the meantime, a work-around is to rebuild gopls with the configurationSupported field of the server hardcoded to false (https://github.com/golang/tools/blob/923d25813098b2ffdf1b4bb7ee4ec425fef796a9/internal/lsp/server.go#L118).

@stamblerre
Copy link
Contributor

The issue that was causing this in lsp-mode has been fixed, so hopefully this should be resolved now.
Can someone who is using lsp-mode from head confirm?

@muirdm
Copy link

muirdm commented Apr 5, 2019

I tried out the patch and it works now. "no room in queue" still shows up for a period at startup, but after that things work to some degree.

@stamblerre
Copy link
Contributor

@muirrn: thanks for confirming! Is there anything else specifically that's broken for you? I'm curious to know what you mean by "to some degree"?

@muirdm
Copy link

muirdm commented Apr 5, 2019

I have no idea if these are client or server (or me), or if they are supposed to work or not, but:

  • i see "cannot find an enclosing function" LSP warning all the time (whenever cursor changes lines)
  • find all references doesn't work (i get an elisp error, haven't investigated yet)
  • documentation doesn't seem to show up (i only see the function signature in the documentation popup, but not the function's comments)

I had another issue where flycheck (i.e. gutter) errors weren't disappearing after the code issue was fixed, but that is not happening anymore.

@stamblerre
Copy link
Contributor

Thanks for the information!

  • The enclosing function warning sounds like it's coming from the signatureHelp feature. I'm guessing it's lsp-mode trying to call signatureHelp whenever you move your cursor, so if you're not typing the parameters of a function, it's getting an error. I would say the problem here lies with lsp-mode, I don't think it's useful to call signatureHelp every time the user moves the cursor.
  • Find all references isn't yet supported in gopls, but we're working on it.
  • gopls don't yet offer documentation for signature help.

@muirdm
Copy link

muirdm commented Apr 5, 2019

Great, thanks. Keep up the good work.

@fjl
Copy link

fjl commented Apr 8, 2019

@stamblerre Regarding signature help: the editor might not necessarily know when to ask for signature help. Would it be acceptable to remove the error?

@fjl
Copy link

fjl commented Apr 10, 2019

Looks like golang/tools@96f2e7e removed the error. Thank you!

@parhamdoustdar
Copy link

parhamdoustdar commented Apr 12, 2019 via email

@muirdm
Copy link

muirdm commented Apr 12, 2019

I think a recent change has made auto completion stop working in emacs. The initial list of completions shows up, but when you type a letter to narrow the completions, the completion popup disappears and it displays no object for ident D (or whatever letter you just typed). gopls seems to work fine in other editors, so it is something with lsp-mode (although by the same token, lsp-mode completions work fine with other language servers). Let me know if you think this is a lsp-mode issue and I'll engage with them. Below is the rpc trace of me typing "." to bring up the completion popup, then typing "P" to narrow the completions (after which the completion errors out with no object for ident P):

[Trace - 3:53:49 PM] Sending notification 'textDocument/didChange'.
Params: {"textDocument":{"uri":"file:///Users/muir/scratch/go/foo.go","version":155},"contentChanges":[{"text":"package scratch\n\nimport \"fmt\"\n\nfunc main() {\n\tfmt.\n}\n"}]}


[Trace - 3:53:49 PM] Received notification 'textDocument/publishDiagnostics'.
Params: {"uri":"file:///Users/muir/scratch/go/foo.go","diagnostics":[{"range":{"start":{"line":6,"character":0},"end":{"line":6,"character":0}},"severity":1,"source":"LSP","message":"expected selector or type assertion, found '}'"}]}


[Trace - 3:53:49 PM] Received notification 'textDocument/publishDiagnostics'.
Params: {"uri":"file:///Users/muir/scratch/go/foo_test.go","diagnostics":[]}


[Trace - 3:53:49 PM] Sending request 'textDocument/completion - (1081)'.
Params: {"textDocument":{"uri":"file:///Users/muir/scratch/go/foo.go"},"position":{"line":5,"character":5}}


[Trace - 3:53:49 PM] Received response 'textDocument/completion - (1081)' in 0ms.
Params: {"isIncomplete":false,"items":[{"label":"Errorf(format string, a ...interface{})","kind":3,"detail":"error","preselect":true,"sortText":"00000","filterText":"Errorf($1)","insertTextFormat":2,"textEdit":{"range":{"start":{"line":5,"character":5},"end":{"line":5,"character":5}},"newText":"Errorf($1)"}},{"label":"Formatter","kind":8,"detail":"interface{...}","sortText":"00001","filterText":"Formatter","insertTextFormat":2,"textEdit":{"range":{"start":{"line":5,"character":5},"end":{"line":5,"character":5}},"newText":"Formatter"}},{"label":"Fprint(w io.Writer, a ...interface{})","kind":3,"detail":"n int, err error","sortText":"00002","filterText":"Fprint($1)","insertTextFormat":2,"textEdit":{"range":{"start":{"line":5,"character":5},"end":{"line":5,"character":5}},"newText":"Fprint($1)"}},{"label":"Fprintf(w io.Writer, format string, a ...interface{})","kind":3,"detail":"n int, err error","sortText":"00003","filterText":"Fprintf($1)","insertTextFormat":2,"textEdit":{"range":{"start":{"line":5,"character":5},"end":{"line":5,"character":5}},"newText":"Fprintf($1)"}},{"label":"Fprintln(w io.Writer, a ...interface{})","kind":3,"detail":"n int, err error","sortText":"00004","filterText":"Fprintln($1)","insertTextFormat":2,"textEdit":{"range":{"start":{"line":5,"character":5},"end":{"line":5,"character":5}},"newText":"Fprintln($1)"}},{"label":"Fscan(r io.Reader, a ...interface{})","kind":3,"detail":"n int, err error","sortText":"00005","filterText":"Fscan($1)","insertTextFormat":2,"textEdit":{"range":{"start":{"line":5,"character":5},"end":{"line":5,"character":5}},"newText":"Fscan($1)"}},{"label":"Fscanf(r io.Reader, format string, a ...interface{})","kind":3,"detail":"n int, err error","sortText":"00006","filterText":"Fscanf($1)","insertTextFormat":2,"textEdit":{"range":{"start":{"line":5,"character":5},"end":{"line":5,"character":5}},"newText":"Fscanf($1)"}},{"label":"Fscanln(r io.Reader, a ...interface{})","kind":3,"detail":"n int, err error","sortText":"00007","filterText":"Fscanln($1)","insertTextFormat":2,"textEdit":{"range":{"start":{"line":5,"character":5},"end":{"line":5,"character":5}},"newText":"Fscanln($1)"}},{"label":"GoStringer","kind":8,"detail":"interface{...}","sortText":"00008","filterText":"GoStringer","insertTextFormat":2,"textEdit":{"range":{"start":{"line":5,"character":5},"end":{"line":5,"character":5}},"newText":"GoStringer"}},{"label":"Print(a ...interface{})","kind":3,"detail":"n int, err error","sortText":"00009","filterText":"Print($1)","insertTextFormat":2,"textEdit":{"range":{"start":{"line":5,"character":5},"end":{"line":5,"character":5}},"newText":"Print($1)"}},{"label":"Printf(format string, a ...interface{})","kind":3,"detail":"n int, err error","sortText":"00010","filterText":"Printf($1)","insertTextFormat":2,"textEdit":{"range":{"start":{"line":5,"character":5},"end":{"line":5,"character":5}},"newText":"Printf($1)"}},{"label":"Println(a ...interface{})","kind":3,"detail":"n int, err error","sortText":"00011","filterText":"Println($1)","insertTextFormat":2,"textEdit":{"range":{"start":{"line":5,"character":5},"end":{"line":5,"character":5}},"newText":"Println($1)"}},{"label":"Scan(a ...interface{})","kind":3,"detail":"n int, err error","sortText":"00012","filterText":"Scan($1)","insertTextFormat":2,"textEdit":{"range":{"start":{"line":5,"character":5},"end":{"line":5,"character":5}},"newText":"Scan($1)"}},{"label":"ScanState","kind":8,"detail":"interface{...}","sortText":"00013","filterText":"ScanState","insertTextFormat":2,"textEdit":{"range":{"start":{"line":5,"character":5},"end":{"line":5,"character":5}},"newText":"ScanState"}},{"label":"Scanf(format string, a ...interface{})","kind":3,"detail":"n int, err error","sortText":"00014","filterText":"Scanf($1)","insertTextFormat":2,"textEdit":{"range":{"start":{"line":5,"character":5},"end":{"line":5,"character":5}},"newText":"Scanf($1)"}},{"label":"Scanln(a ...interface{})","kind":3,"detail":"n int, err error","sortText":"00015","filterText":"Scanln($1)","insertTextFormat":2,"textEdit":{"range":{"start":{"line":5,"character":5},"end":{"line":5,"character":5}},"newText":"Scanln($1)"}},{"label":"Scanner","kind":8,"detail":"interface{...}","sortText":"00016","filterText":"Scanner","insertTextFormat":2,"textEdit":{"range":{"start":{"line":5,"character":5},"end":{"line":5,"character":5}},"newText":"Scanner"}},{"label":"Sprint(a ...interface{})","kind":3,"detail":"string","sortText":"00017","filterText":"Sprint($1)","insertTextFormat":2,"textEdit":{"range":{"start":{"line":5,"character":5},"end":{"line":5,"character":5}},"newText":"Sprint($1)"}},{"label":"Sprintf(format string, a ...interface{})","kind":3,"detail":"string","sortText":"00018","filterText":"Sprintf($1)","insertTextFormat":2,"textEdit":{"range":{"start":{"line":5,"character":5},"end":{"line":5,"character":5}},"newText":"Sprintf($1)"}},{"label":"Sprintln(a ...interface{})","kind":3,"detail":"string","sortText":"00019","filterText":"Sprintln($1)","insertTextFormat":2,"textEdit":{"range":{"start":{"line":5,"character":5},"end":{"line":5,"character":5}},"newText":"Sprintln($1)"}},{"label":"Sscan(str string, a ...interface{})","kind":3,"detail":"n int, err error","sortText":"00020","filterText":"Sscan($1)","insertTextFormat":2,"textEdit":{"range":{"start":{"line":5,"character":5},"end":{"line":5,"character":5}},"newText":"Sscan($1)"}},{"label":"Sscanf(str string, format string, a ...interface{})","kind":3,"detail":"n int, err error","sortText":"00021","filterText":"Sscanf($1)","insertTextFormat":2,"textEdit":{"range":{"start":{"line":5,"character":5},"end":{"line":5,"character":5}},"newText":"Sscanf($1)"}},{"label":"Sscanln(str string, a ...interface{})","kind":3,"detail":"n int, err error","sortText":"00022","filterText":"Sscanln($1)","insertTextFormat":2,"textEdit":{"range":{"start":{"line":5,"character":5},"end":{"line":5,"character":5}},"newText":"Sscanln($1)"}},{"label":"State","kind":8,"detail":"interface{...}","sortText":"00023","filterText":"State","insertTextFormat":2,"textEdit":{"range":{"start":{"line":5,"character":5},"end":{"line":5,"character":5}},"newText":"State"}},{"label":"Stringer","kind":8,"detail":"interface{...}","sortText":"00024","filterText":"Stringer","insertTextFormat":2,"textEdit":{"range":{"start":{"line":5,"character":5},"end":{"line":5,"character":5}},"newText":"Stringer"}}]}


[Trace - 3:53:50 PM] Sending notification 'textDocument/didChange'.
Params: {"textDocument":{"uri":"file:///Users/muir/scratch/go/foo.go","version":156},"contentChanges":[{"text":"package scratch\n\nimport \"fmt\"\n\nfunc main() {\n\tfmt.P\n}\n"}]}


[Trace - 3:53:50 PM] Received notification 'textDocument/publishDiagnostics'.
Params: {"uri":"file:///Users/muir/scratch/go/foo.go","diagnostics":[{"range":{"start":{"line":5,"character":5},"end":{"line":5,"character":6}},"severity":1,"source":"LSP","message":"P not declared by package fmt"}]}


[Trace - 3:53:50 PM] Received notification 'textDocument/publishDiagnostics'.
Params: {"uri":"file:///Users/muir/scratch/go/foo_test.go","diagnostics":[]}


[Trace - 3:53:50 PM] Sending request 'textDocument/completion - (1082)'.
Params: {"textDocument":{"uri":"file:///Users/muir/scratch/go/foo.go"},"position":{"line":5,"character":6}}


[Trace - 3:53:50 PM] Received response 'textDocument/completion - (1082)' in 0ms.
Params: {"isIncomplete":false,"items":[{"label":"Print(a ...interface{})","kind":3,"detail":"n int, err error","sortText":"00009","filterText":"rint($1)","insertTextFormat":2,"textEdit":{"range":{"start":{"line":5,"character":6},"end":{"line":5,"character":6}},"newText":"rint($1)"}},{"label":"Printf(format string, a ...interface{})","kind":3,"detail":"n int, err error","sortText":"00010","filterText":"rintf($1)","insertTextFormat":2,"textEdit":{"range":{"start":{"line":5,"character":6},"end":{"line":5,"character":6}},"newText":"rintf($1)"}},{"label":"Println(a ...interface{})","kind":3,"detail":"n int, err error","sortText":"00011","filterText":"rintln($1)","insertTextFormat":2,"textEdit":{"range":{"start":{"line":5,"character":6},"end":{"line":5,"character":6}},"newText":"rintln($1)"}}]}


[Trace - 3:53:50 PM] Sending request 'textDocument/completion - (1083)'.
Params: {"textDocument":{"uri":"file:///Users/muir/scratch/go/foo.go"},"position":{"line":5,"character":6}}


[Trace - 3:53:50 PM] Received response 'textDocument/completion - (1083)' in 0ms.
Params: {"isIncomplete":false,"items":[{"label":"Print(a ...interface{})","kind":3,"detail":"n int, err error","sortText":"00009","filterText":"rint($1)","insertTextFormat":2,"textEdit":{"range":{"start":{"line":5,"character":6},"end":{"line":5,"character":6}},"newText":"rint($1)"}},{"label":"Printf(format string, a ...interface{})","kind":3,"detail":"n int, err error","sortText":"00010","filterText":"rintf($1)","insertTextFormat":2,"textEdit":{"range":{"start":{"line":5,"character":6},"end":{"line":5,"character":6}},"newText":"rintf($1)"}},{"label":"Println(a ...interface{})","kind":3,"detail":"n int, err error","sortText":"00011","filterText":"rintln($1)","insertTextFormat":2,"textEdit":{"range":{"start":{"line":5,"character":6},"end":{"line":5,"character":6}},"newText":"rintln($1)"}}]}


[Trace - 3:53:50 PM] Sending request 'textDocument/documentHighlight - (1084)'.
Params: {"textDocument":{"uri":"file:///Users/muir/scratch/go/foo.go"},"position":{"line":5,"character":6}}


[Trace - 3:53:50 PM] Received response 'textDocument/documentHighlight - (1084)' in 0ms.
Params: []


[Trace - 3:53:51 PM] Sending request 'textDocument/hover - (1085)'.
Params: {"textDocument":{"uri":"file:///Users/muir/scratch/go/foo.go"},"position":{"line":5,"character":6}}


[Error - 3:53:51 PM] send textDocument/hover#1085 no object for ident P


[Trace - 3:53:51 PM] Sending request 'textDocument/signatureHelp - (1086)'.
Params: {"textDocument":{"uri":"file:///Users/muir/scratch/go/foo.go"},"position":{"line":5,"character":6}}


[Trace - 3:53:51 PM] Received notification 'window/logMessage'.
Params: {"type":3,"message":"no signature help for file:///Users/muir/scratch/go/foo.go:5:6"}


[Trace - 3:53:51 PM] Received response 'textDocument/signatureHelp - (1086)' in 0ms.
Params: {"signatures":null,"activeSignature":0,"activeParameter":0}

@stamblerre
Copy link
Contributor

@muirrn: it seems like the error you are getting from the hover request - if you notice, the completion returns the results for fmt that begin with P in the last 2 completion results. It seems like the interactions between the different requests is what's causing the problem. Would you mind opening this issue in lsp-mode so we can get some input from the folks who maintain it?

@vbauerster
Copy link

Formatting of the hover feature is not usable at all, for such clients as emacs and kak-lsp. Following screenshots are from kak but it's same in emacs. When struct or any other hover element is big, it's just not readable.
Screenshot-2019-04-13-at-15-35-06.png
In contrast this is how bingo displays same hover:
Screenshot-2019-04-13-at-15-25-36.png

Is it possible to preserve same formatting as bingo did?

@yyoncho
Copy link

yyoncho commented Apr 13, 2019

@vbauerster

Formatting of the hover feature is not usable at all, for such clients as emacs

Just for the record, emacs is able to handle markdown, we had a bug which now is going to be fixed. There are at least two several language servers which return the same hover info format: scala metals and ruby language.

@vbauerster
Copy link

@yyoncho The issue is not in markdown handling (I use spacemacs, and there is no triple `), it is that any hover gets it output as one liner, thus making big structures unreadable. Notice a semicolon between struct fields in the first screenshoot, if there were 20 fields they would be all in one line separated by semicolons.

@muirdm
Copy link

muirdm commented Apr 17, 2019

@stamblerre I looked in to the completion issue and the problem is gopls is using the prefix-trimmed insertion text as the filterText, and lsp-mode prefers the filterText if it is set. For example, you have typed fmt.P and you get back a completion with ~{Label: "Print", Insert: "rint", FilterText: "rint"}. lsp-mode says "P doesn't match filterText of rint", so it filters those completion options (and you are left with no options).

I surveyed some other clients/servers:

  • java/rust lsp don't set filterText
  • clangd sets it, but does not trim the prefix
  • vscode seems to match using the label or filterText, so you can mix and match from either (that is why the trimmed prefixes don't break vscode). the lsp spec seems to suggest filterText should supersede label if present, but maybe vscode does this to be more lenient in general.

@stamblerre
Copy link
Contributor

Fixed as of https://golang.org/cl/176958.

@golang golang locked and limited conversation to collaborators May 14, 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. NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Projects
None yet
Development

No branches or pull requests

9 participants