From 0e99a1dcaf3125489c409c9056edca05fdbfcb9c Mon Sep 17 00:00:00 2001 From: Yegappan Lakshmanan Date: Wed, 5 Apr 2023 22:37:37 -0700 Subject: [PATCH] Add support for the workspace/didChangeConfiguration notification --- autoload/lsp/capabilities.vim | 2 +- autoload/lsp/handlers.vim | 6 ++++-- autoload/lsp/lsp.vim | 5 +++++ autoload/lsp/lspserver.vim | 35 +++++++++++++++++++++++++++++++++++ doc/lsp.txt | 21 +++++++++++++++------ 5 files changed, 60 insertions(+), 9 deletions(-) diff --git a/autoload/lsp/capabilities.vim b/autoload/lsp/capabilities.vim index ac9b080..5fdb1dd 100644 --- a/autoload/lsp/capabilities.vim +++ b/autoload/lsp/capabilities.vim @@ -259,7 +259,7 @@ export def GetClientCaps(): dict workspace: { workspaceFolders: true, applyEdit: true, - configuration: false + configuration: true }, textDocument: { callHierarchy: { diff --git a/autoload/lsp/handlers.vim b/autoload/lsp/handlers.vim index c2479e8..a62fbfb 100644 --- a/autoload/lsp/handlers.vim +++ b/autoload/lsp/handlers.vim @@ -142,9 +142,11 @@ enddef # process the workspace/configuration LSP server request # Request: "workspace/configuration" -# Param: none +# Param: ConfigurationParams def ProcessWorkspaceConfiguration(lspserver: dict, request: dict) - lspserver.sendResponse(request, {}, {}) + var items = request.params.items + var response = items->map((_, item) => lspserver.workspaceConfigGet(item)) + lspserver.sendResponse(request, response, {}) enddef # process the window/workDoneProgress/create LSP server request diff --git a/autoload/lsp/lsp.vim b/autoload/lsp/lsp.vim index 12f4461..f4f6f01 100644 --- a/autoload/lsp/lsp.vim +++ b/autoload/lsp/lsp.vim @@ -510,9 +510,14 @@ export def AddServer(serverList: list>) server.debug = false endif + if !server->has_key('workspaceConfig') + server.workspaceConfig = {} + endif + var lspserver: dict = lserver.NewLspServer(server.name, server.path, args, server.syncInit, initializationOptions, + server.workspaceConfig, customNotificationHandlers, server.debug) diff --git a/autoload/lsp/lspserver.vim b/autoload/lsp/lspserver.vim index 2a64da1..01df434 100644 --- a/autoload/lsp/lspserver.vim +++ b/autoload/lsp/lspserver.vim @@ -119,6 +119,10 @@ def ServerInitReply(lspserver: dict, initResult: dict): void # send a "initialized" notification to server lspserver.sendInitializedNotif() + # send any workspace configuration (optional) + if !lspserver.workspaceConfig->empty() + lspserver.sendWorkspaceConfig() + endif lspserver.ready = true if exists($'#User#LspServerReady{lspserver.name}') exe $'doautocmd User LspServerReady{lspserver.name}' @@ -429,6 +433,33 @@ def WaitForResponse(lspserver: dict, req: dict) endwhile enddef +# Retrieve the Workspace configuration asked by the server. +# Request: workspace/configuration +def WorkspaceConfigGet(lspserver: dict, configItem: dict): dict + if lspserver.workspaceConfig->empty() + return {} + endif + if !configItem->has_key('section') || configItem.section->empty() + return lspserver.workspaceConfig + endif + var config: dict = lspserver.workspaceConfig + for part in configItem.section->split('\.') + if !config->has_key(part) + return {} + endif + config = config[part] + endfor + return config +enddef + +# Send a "workspace/didChangeConfiguration" notification to the language +# server. +def SendWorkspaceConfig(lspserver: dict) + # Params: DidChangeConfigurationParams + var params = {settings: lspserver.workspaceConfig} + lspserver.sendNotification('workspace/didChangeConfiguration', params) +enddef + # Send a file/document opened notification to the language server. def TextdocDidOpen(lspserver: dict, bnr: number, ftype: string): void # Notification: 'textDocument/didOpen' @@ -1352,6 +1383,7 @@ enddef export def NewLspServer(name_arg: string, path_arg: string, args: list, isSync: bool, initializationOptions: any, + workspaceConfig: dict, customNotificationHandlers: dict, debug_arg: bool): dict var lspserver: dict = { @@ -1380,6 +1412,7 @@ export def NewLspServer(name_arg: string, path_arg: string, args: list, peekSymbolFilePopup: -1, callHierarchyType: '', selection: {}, + workspaceConfig: workspaceConfig, debug: debug_arg } lspserver.logfile = $'lsp-{lspserver.name}.log' @@ -1414,6 +1447,7 @@ export def NewLspServer(name_arg: string, path_arg: string, args: list, textdocDidClose: function(TextdocDidClose, [lspserver]), textdocDidChange: function(TextdocDidChange, [lspserver]), sendInitializedNotif: function(SendInitializedNotif, [lspserver]), + sendWorkspaceConfig: function(SendWorkspaceConfig, [lspserver]), getCompletion: function(GetCompletion, [lspserver]), resolveCompletion: function(ResolveCompletion, [lspserver]), gotoDefinition: function(GotoDefinition, [lspserver]), @@ -1446,6 +1480,7 @@ export def NewLspServer(name_arg: string, path_arg: string, args: list, selectionShrink: function(SelectionShrink, [lspserver]), foldRange: function(FoldRange, [lspserver]), executeCommand: function(ExecuteCommand, [lspserver]), + workspaceConfigGet: function(WorkspaceConfigGet, [lspserver]), showCapabilities: function(ShowCapabilities, [lspserver]) }) diff --git a/doc/lsp.txt b/doc/lsp.txt index f0c73d7..d837fc1 100644 --- a/doc/lsp.txt +++ b/doc/lsp.txt @@ -250,12 +250,15 @@ To add a language server, the following information is needed: or useful for initialization. Those can be provided in this dictionary and if present will be transmitted to the lsp server. - *lsp-cfg-debug* - debug (Optional) log the messages printed by this language - server in stdout and stderr to a file. Useful for - debugging a language server. By default the - messages are not logged. See |lsp-debug| for more - information. + *lsp-cfg-workspaceConfig* + workspaceConfig (Optional) a json encodable value that will be sent to + the language server after initialization as the + "settings" in a "workspace/didChangeConfiguration" + notification. Refer to the language server + documentation for the values that will be accepted in + this notification. This configuration is also used to + respond to the "workspace/configuration" request + message from the language server. Aditionally the following configurations can be made: @@ -278,6 +281,12 @@ Aditionally the following configurations can be made: call is used to initialize the language server, otherwise the server is initialized asynchronously. By default this is set to "v:false". + *lsp-cfg-debug* + debug (Optional) log the messages printed by this language + server in stdout and stderr to a file. Useful for + debugging a language server. By default the + messages are not logged. See |lsp-debug| for more + information. The language servers are added using the LspAddServer() function. This function accepts a list of language servers with the above information. -- 2.48.1