Having an RPC log is essential for troubleshooting. I can’t give you the opening Nova / Language Server dialog for your language server, but I can give you one from a language server.
Here is the opening exchange of Nova talking to the gopls language server in my (unpublished) Go extension. The “Sending” and “Received” are from Nova’s point of view. The initializationOptions
in the message are passed through via the last argument of the LanguageClient
constructor. (Here I have a function that feeds in the values for…reasons, but they could be a literal set of key-value pairs.)
var clientOptions = {
// The set of document syntaxes for which the server is valid
syntaxes: ['go'],
initializationOptions: gopls.Settings(),
};
var client = new LanguageClient(
'gopls',
'gopls',
serverOptions,
clientOptions
);
[Trace - 09:13:21.248 AM] Sending request ‘initialize - (0)’.
Nova sends this to the language server
Params:
{
"capabilities": {
"workspace": {
"configuration": true,
"applyEdit": true,
"executeCommand": {},
"workspaceFolders": true,
"workspaceEdit": {
"failureHandling": "undo",
"documentChanges": true,
"resourceOperations": [
"create",
"rename",
"delete"
]
}
},
"textDocument": {
"rename": {
"prepareSupport": true
},
"codeAction": {
"codeActionLiteralSupport": {
"codeActionKind": {
"valueSet": [
"",
"quickfix",
"refactor",
"refactor.inline",
"refactor.extract",
"refactor.rewrite",
"source",
"source.organizeImports"
]
}
},
"isPreferredSupport": true
},
"hover": {
"contentFormat": [
"markdown",
"plaintext"
]
},
"completion": {
"completionItem": {
"snippetSupport": true,
"deprecatedSupport": true,
"commitCharactersSupport": true,
"documentationFormat": [
"markdown",
"plaintext"
],
"tagSupport": {
"valueSet": [
1
]
}
},
"completionItemKind": {
"valueSet": [
1,
2,
3,
4,
5,
6,
7,
8,
9,
10,
11,
12,
13,
14,
15,
16,
17,
18,
19,
20,
21,
22,
23,
24,
25
]
},
"contextSupport": true
},
"codeLens": {},
"documentHighlight": {},
"synchronization": {
"didSave": true,
"willSave": true,
"willSaveWaitUntil": true
},
"publishDiagnostics": {
"versionSupport": true,
"relatedInformation": true
},
"declaration": {
"linkSupport": true
},
"typeDefinition": {
"linkSupport": true
},
"definition": {
"linkSupport": true
},
"implementation": {
"linkSupport": true
},
"signatureHelp": {
"signatureInformation": {
"documentationFormat": [
"markdown",
"plaintext"
]
}
}
}
},
"workspaceFolders": [
{
"uri": "file:///Users/jfieber/Documents/code/github.com/jfieber/wgn/",
"name": "wgn"
}
],
"rootPath": "/Volumes/gamut/Users/jfieber/Documents/code/github.com/jfieber/wgn",
"processId": 732,
"initializationOptions": {
"ui.completion.usePlaceholders": true,
"build.buildFlags": [],
"formatting.gofumpt": false,
"ui.navigation.importShortcut": "Both",
"ui.navigation.symbolMatcher": "Fuzzy",
"formatting.local": "",
"ui.documentation.linksInHover": true,
"build.directoryFilters": [],
"ui.navigation.symbolStyle": "Dynamic",
"ui.documentation.hoverKind": "FullDocumentation",
"ui.completion.matcher": "Fuzzy",
"ui.documentation.linkTarget": "pkg.go.dev"
},
"rootUri": "file:///Users/jfieber/Documents/code/github.com/jfieber/wgn/",
"clientInfo": {
"name": "Nova",
"version": "6.1"
}
}
[Trace - 09:13:21.249 AM] Received response ‘initialize - (0)’ in 1ms.
This is from the language server.
Result:
{
"capabilities": {
"textDocumentSync": {
"openClose": true,
"change": 2,
"save": {}
},
"completionProvider": {
"triggerCharacters": [
"."
]
},
"hoverProvider": true,
"signatureHelpProvider": {
"triggerCharacters": [
"(",
","
]
},
"definitionProvider": true,
"typeDefinitionProvider": true,
"implementationProvider": true,
"referencesProvider": true,
"documentHighlightProvider": true,
"documentSymbolProvider": true,
"codeActionProvider": {
"codeActionKinds": [
"quickfix",
"refactor.extract",
"refactor.rewrite",
"source.fixAll",
"source.organizeImports"
]
},
"codeLensProvider": {},
"documentLinkProvider": {},
"workspaceSymbolProvider": true,
"documentFormattingProvider": true,
"documentOnTypeFormattingProvider": {
"firstTriggerCharacter": ""
},
"renameProvider": {
"prepareProvider": true
},
"foldingRangeProvider": true,
"executeCommandProvider": {
"commands": [
"gopls.add_dependency",
"gopls.add_import",
"gopls.apply_fix",
"gopls.check_upgrades",
"gopls.gc_details",
"gopls.generate",
"gopls.generate_gopls_mod",
"gopls.go_get_package",
"gopls.list_known_packages",
"gopls.regenerate_cgo",
"gopls.remove_dependency",
"gopls.run_tests",
"gopls.test",
"gopls.tidy",
"gopls.toggle_gc_details",
"gopls.update_go_sum",
"gopls.upgrade_dependency",
"gopls.vendor"
]
},
"callHierarchyProvider": true,
"workspace": {
"workspaceFolders": {
"supported": true,
"changeNotifications": "workspace/didChangeWorkspaceFolders"
}
}
},
"serverInfo": {
"name": "gopls",
"version": "{\"path\":\"golang.org/x/tools/gopls\",\"version\":\"v0.6.9\",\"sum\":\"h1:LBBcE2y3Tb4bp79JVLWCQBbvYCFEs5ADGWsQDoSLk1Q=\",\"deps\":[{\"path\":\"github.com/BurntSushi/toml\",\"version\":\"v0.3.1\",\"sum\":\"h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=\"},{\"path\":\"github.com/google/go-cmp\",\"version\":\"v0.5.4\",\"sum\":\"h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M=\"},{\"path\":\"github.com/sergi/go-diff\",\"version\":\"v1.1.0\",\"sum\":\"h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=\"},{\"path\":\"golang.org/x/mod\",\"version\":\"v0.4.1\",\"sum\":\"h1:Kvvh58BN8Y9/lBi7hTekvtMpm07eUZ0ck5pRHpsMWrY=\"},{\"path\":\"golang.org/x/sync\",\"version\":\"v0.0.0-20201020160332-67f06af15bc9\",\"sum\":\"h1:SQFwaSi55rU7vdNs9Yr0Z324VNlrF+0wMqRXT4St8ck=\"},{\"path\":\"golang.org/x/sys\",\"version\":\"v0.0.0-20210124154548-22da62e12c0c\",\"sum\":\"h1:VwygUrnw9jn88c4u8GD3rZQbqrP/tgas88tPUbBxQrk=\"},{\"path\":\"golang.org/x/tools\",\"version\":\"v0.1.1-0.20210319172145-bda8f5cee399\",\"sum\":\"h1:O5bm8buX/OaamnfcBrkjn0SPUIU30jFmaS8lP+ikkxs=\"},{\"path\":\"golang.org/x/xerrors\",\"version\":\"v0.0.0-20200804184101-5ec99f83aff1\",\"sum\":\"h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=\"},{\"path\":\"honnef.co/go/tools\",\"version\":\"v0.1.1\",\"sum\":\"h1:EVDuO03OCZwpV2t/tLLxPmPiomagMoBOgfPt0FM+4IY=\"},{\"path\":\"mvdan.cc/gofumpt\",\"version\":\"v0.1.0\",\"sum\":\"h1:hsVv+Y9UsZ/mFZTxJZuHVI6shSQCtzZ11h1JEFPAZLw=\"},{\"path\":\"mvdan.cc/xurls/v2\",\"version\":\"v2.2.0\",\"sum\":\"h1:NSZPykBXJFCetGZykLAxaL6SIpvbVy/UFEniIfHAa8A=\"}]}"
}
}
[Trace - 09:13:21.249 AM] Sending notification ‘initialized’.
Params:
{}
The language server can ask Nova for the workspace configuration at any time. The section
is a configuration scope and the values come from Nova’s configuration item key space. So in the response, where you see ui.completion.usePlaceholders
, the actual Nova configuration item key is gopls.ui.completion.usePlaceholders
. Nova just enumerates the keys starting with gopls.
and hands them over. Whether your language server request stuff in exactly the same way, I don’t know.
(@logan: would be super nifty if we could register a callback to supply the workspace configuration. I would love to keep the gopls options scoped to my extension. The problem case: I flip back and forth between my Go extension, and the Go extension in the registry by @GwynethLlewelyn, the two currently have no choice but to compete over the gopls.
configuration key space. Hand-editing UserConfiguration.json
when switching isn’t a great option.)
[Trace - 09:13:21.250 AM] Received request ‘workspace/configuration - (1)’.
Params:
{
"items": [
{
"scopeUri": "file:///Users/jfieber/Documents/code/github.com/jfieber/wgn/",
"section": "gopls"
}
]
}
[Trace - 09:13:21.264 AM] Sending response ‘workspace/configuration - (1)’ in 13ms.
Result:
[
{
"ui.completion.usePlaceholders": true,
"ui.navigation.importShortcut": "Both",
"build.buildFlags": [],
"formatting.gofumpt": false,
"ui.navigation.symbolMatcher": "Fuzzy",
"formatting.local": "",
"ui.documentation.linksInHover": true,
"ui.navigation.symbolStyle": "Dynamic",
"build.directoryFilters": [],
"ui.documentation.hoverKind": "FullDocumentation",
"ui.completion.matcher": "Fuzzy",
"ui.documentation.linkTarget": "pkg.go.dev"
}
]