I try use the latest version go-langserver that support completion feature.
It report the follow error that receive from go-langserver on initialize:
bundle.js:1 [LANGUAGE CLIENT - STDERR]: langserver-go: reading on stdin, writing on stdout
bundle.js:1 Error: json: cannot unmarshal bool into Go struct field TextDocumentClientCapabilities.completion of type struct { CompletionItemKind struct { ValueSet []lsp.CompletionItemKind "json:\"valueSet,omitempty\"" } "json:\"completionItemKind,omitempty\"" }
at new ResponseError (/data/saibing/git/ts/oni/node_modules/vscode-jsonrpc/lib/messages.js:46)
at handleResponse (/data/saibing/git/ts/oni/node_modules/vscode-jsonrpc/lib/main.js:430)
at processMessageQueue (/data/saibing/git/ts/oni/node_modules/vscode-jsonrpc/lib/main.js:258)
at Immediate._onImmediate (/data/saibing/git/ts/oni/node_modules/vscode-jsonrpc/lib/main.js:242)
at runCallback (timers.js:781)
at tryOnImmediate (timers.js:743)
at processImmediate [as _immediateCallback] (timers.js:714)
t.error @ bundle.js:1
(anonymous) @ 0.bundle.js:27
s @ 0.bundle.js:27
bundle.js:1 [Language Client] Notification textDocument/didOpen - /data/saibing/git/go/src/jvmgo/cmd.go: start
bundle.js:1 [Language Client] Notification textDocument/didOpen - /data/saibing/git/go/src/jvmgo/cmd.go: end
but vscode running is ok:
langserver-go: reading on stdin, writing on stdout
--> request #0: initialize: {"processId":24192,"rootPath":"/data/saibing/git/go/src/github.com/sourcegraph/go-langserver","capabilities":{},"trace":"off"}
<-- result #0: initialize: {"capabilities":{"textDocumentSync":2,"hoverProvider":true,"signatureHelpProvider":{"triggerCharacters":["(",","]},"definitionProvider":true,"referencesProvider":true,"documentSymbolProvider":true,"workspaceSymbolProvider":true,"documentFormattingProvider":true,"xworkspaceReferencesProvider":true,"xdefinitionProvider":true,"xworkspaceSymbolByProperties":true}}
--> notif: textDocument/didOpen: {"textDocument":
Maybe Oni does not support ClientCapabilities message?
interface ClientCapabilities {
/**
* Workspace specific client capabilities.
*/
workspace?: WorkspaceClientCapabilities;
/**
* Text document specific client capabilities.
*/
textDocument?: TextDocumentClientCapabilities;
/**
* Experimental client capabilities.
*/
experimental?: any;
}
The go-langserver struct definition as flow:
type ClientCapabilities struct {
Workspace WorkspaceClientCapabilities `json:"workspace,omitempty"`
TextDocument TextDocumentClientCapabilities `json:"textDocument,omitempty"`
Experimental interface{} `json:"experimental,omitempty"`
// Below are Sourcegraph extensions. They do not live in lspext since
// they are extending the field InitializeParams.Capabilities
// XFilesProvider indicates the client provides support for
// workspace/xfiles. This is a Sourcegraph extension.
XFilesProvider bool `json:"xfilesProvider,omitempty"`
// XContentProvider indicates the client provides support for
// textDocument/xcontent. This is a Sourcegraph extension.
XContentProvider bool `json:"xcontentProvider,omitempty"`
// XCacheProvider indicates the client provides support for cache/get
// and cache/set.
XCacheProvider bool `json:"xcacheProvider,omitempty"`
}
type WorkspaceClientCapabilities struct{}
type TextDocumentClientCapabilities struct {
Completion struct {
CompletionItemKind struct {
ValueSet []CompletionItemKind `json:"valueSet,omitempty"`
} `json:"completionItemKind,omitempty"`
} `json:"completion,omitempty"`
}
I trace the detail message of go-langserver as follow:
langserver-go: reading on stdin, writing on stdout
--> request #0: initialize: {"clientName":"oni","rootPath":"/data/saibing/git/go/src/jvmgo","rootUri":"file:///data/saibing/git/go/src/jvmgo","capabilities":{"workspace":{"applyEdit":true,"configuration":true,
"workspaceEdit":{"documentChanges":false},"didChangeConfiguration":true,"didChangeWatchedFiles":false,"symbol":true,"executeCommand":true},"textDocument":{"synchronization":true,"completion":true,"hover":true,
"signatureHelp":true,"references":true,"documentHighlight":false,"documentSymbol":true,"formatting":true,"rangeFormatting":true,"onTypeFormatting":false,"definition":true,"codeAction":true,"codeLens":true,
"documentLink":false,"rename":true}}}
<-- error #0: initialize: {"code":0,"message":"json: cannot unmarshal bool into Go struct field TextDocumentClientCapabilities.completion of type struct { CompletionItemKind struct { ValueSet []lsp.
CompletionItemKind \"json:\\\"valueSet,omitempty\\\"\" } \"json:\\\"completionItemKind,omitempty\\\"\" }","data":null}
--> notif: textDocument/didOpen: {"textDocument":{"uri":"file:///data/saibing/git/go/src/jvmgo/jvm.go","languageId":"go","text":"package main\n\nimport \"fmt\"\nimport \"strings\"\nimport \"jvmgo/
classpath\"\nimport \"jvmgo/instructions/base\"\nimport \"jvmgo/rtda\"\nimport \"jvmgo/rtda/heap\"\n\ntype JVM struct {\n\tcmd *Cmd\n\tclassLoader *heap.ClassLoader\n\tmainThread *rtda.
Thread\n}\n\nfunc newJVM(cmd *Cmd) *JVM {\n\tcp := classpath.Parse(cmd.XjreOption, cmd.cpOption)\n\tclassLoader := heap.NewClassLoader(cp, cmd.verboseClassFlag)\n\treturn \u0026JVM{\n\t\tcmd: cmd,
\n\t\tclassLoader: classLoader,\n\t\tmainThread: rtda.NewThread(),\n\t}\n}\n\nfunc (self *JVM) start() {\n\tself.initVM()\n\tself.execMain()\n}\n\nfunc (self *JVM) initVM() {\n\tvmClass := self.classLoader.
LoadClass(\"sun/misc/VM\")\n\tbase.InitClass(self.mainThread, vmClass)\n\tinterpret(self.mainThread, self.cmd.verboseInstFlag)\n}\n\nfunc (self *JVM) execMain() {\n\tclassName := strings.Replace(self.cmd.class,
\".\", \"/\", -1)\n\tmainClass := self.classLoader.LoadClass(className)\n\tmainMethod := mainClass.GetMainMethod()\n\tif mainMethod == nil {\n\t\tfmt.Printf(\"Main method not found in class %s\\n\", self.cmd.
class)\n\t\treturn\n\t}\n\n\targsArr := self.createArgsArray()\n\tframe := self.mainThread.NewFrame(mainMethod)\n\tframe.LocalVars().SetRef(0, argsArr)\n\tself.mainThread.PushFrame(frame)\n\tinterpret(self.
mainThread, self.cmd.verboseInstFlag)\n}\n\nfunc (self *JVM) createArgsArray() *heap.Object {\n\tstringClass := self.classLoader.LoadClass(\"java/lang/String\")\n\targsLen := uint(len(self.cmd.
args))\n\targsArr := stringClass.ArrayClass().NewArray(argsLen)\n\tjArgs := argsArr.Refs()\n\tfor i, arg := range self.cmd.args {\n\t\tjArgs[i] = heap.JString(self.classLoader, arg)\n\t}\n\treturn argsArr\n}"}}
jsonrpc2 handler: notification "textDocument/didOpen" handling error: server must be initialized
"textDocument":{"synchronization":true,"completion":true
"completion":true may be wrong
~Try setting "language.go.languageServer.arguments": ["--gocodecompletion"], then the language server will enable completion for you. See https://github.com/sourcegraph/go-langserver/blob/6d17b634f244650517ca2ec9a82068d02a581b09/main.go#L32~
~This is an experimental feature. Sorry for that it is not well documented.~
Sorry for my irrelevent rushed answer. I checked the LSP spec and how Oni initialize LSP
It seems that many of the above params should not be simply set as a bool. Besides, a few entries' names seem mismatch with the spec.
@Contextualist
Thank you very much. I have already setting this in config.js:
"language.go.languageServer.rootFiles": [".git"],
"language.go.completionTriggerCharacters": ["."],
"language.go.languageServer.arguments": ["--logfile", "goserver.log", "--trace", "--gocodecompletion"],
So I think the problem is that: {"completion":true} can not be unmarshal to golang struct in go-langserver.
May be {"completion":true} does not accord with the new version Language Server Protocol?
/**
* Capabilities specific to the `textDocument/completion`
*/
completion?: {
/**
* Whether completion supports dynamic registration.
*/
dynamicRegistration?: boolean;
/**
* The client supports the following `CompletionItem` specific
* capabilities.
*/
completionItem?: {
/**
* Client supports snippets as insert text.
*
* A snippet can define tab stops and placeholders with `$1`, `$2`
* and `${3:foo}`. `$0` defines the final tab stop, it defaults to
* the end of the snippet. Placeholders with equal identifiers are linked,
* that is typing in one will update others too.
*/
snippetSupport?: boolean;
/**
* Client supports commit characters on a completion item.
*/
commitCharactersSupport?: boolean
/**
* Client supports the follow content formats for the documentation
* property. The order describes the preferred format of the client.
*/
documentationFormat?: MarkupKind[];
}
completionItemKind?: {
/**
* The completion item kind values the client supports. When this
* property exists the client also guarantees that it will
* handle values outside its set gracefully and falls back
* to a default value when unknown.
*
* If this property is not present the client only supports
* the completion items kinds from `Text` to `Reference` as defined in
* the initial version of the protocol.
*/
valueSet?: CompletionItemKind[];
},
/**
* The client supports to send additional context information for a
* `textDocument/completion` requestion.
*/
contextSupport?: boolean;
};
@saibing , I agree with you. I'm sure it will be addressed soon. If you are eager to see it work, you can simply delete L152-179 in oni/browser/src/Services/Language/LanguageClientProcess.ts and build Oni, since these params are optional.
By the way, @bryphe , to what extent and when would you like to implement these optional params? Just curious.
@saibing @Contextualist - thank you both for the _very_ detailed investigation and notes! Was a huge help and made it very easy for me to get up to speed. (As an aside, the completion functionality is really cool, I didn't know that was available now!)
By the way, @bryphe , to what extent and when would you like to implement these optional params? Just curious.
@Contextualist - ideally these parameter should be up-to-date and accurate - at least for the functionality Oni provides. I took a pass and corrected them, and validated that other language servers still work with the new options.
Opened #1185 to correct this - let me know if it addresses the issue for you. Thanks @Contextualist and @saibing for your help and investigation here!
Most helpful comment
@saibing , I agree with you. I'm sure it will be addressed soon. If you are eager to see it work, you can simply delete L152-179 in oni/browser/src/Services/Language/LanguageClientProcess.ts and build Oni, since these params are optional.
By the way, @bryphe , to what extent and when would you like to implement these optional params? Just curious.