aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthieu Coudron <teto@users.noreply.github.com>2021-01-01 23:52:48 +0100
committerGitHub <noreply@github.com>2021-01-01 23:52:48 +0100
commit48caf1df8581a9a9da9072f901411b918333952d (patch)
treec1dfa6befd03c69c8d70fcc67996905ce6faf091
parent4a0a6f7bff64b03c80dd84444fc4dbddbe1065ad (diff)
parentf3bbc92476df1112deb34b9c7408cd594ee47a50 (diff)
downloadrneovim-48caf1df8581a9a9da9072f901411b918333952d.tar.gz
rneovim-48caf1df8581a9a9da9072f901411b918333952d.tar.bz2
rneovim-48caf1df8581a9a9da9072f901411b918333952d.zip
Merge pull request #13649 from mjlbach/move_from_nvim-lspconfig
LSP: Move workspace/configuration from nvim-lspconfig to core
-rw-r--r--runtime/doc/lsp.txt4
-rw-r--r--runtime/lua/vim/lsp/handlers.lua25
-rw-r--r--runtime/lua/vim/lsp/util.lua15
-rw-r--r--test/functional/fixtures/fake-lsp-server.lua17
-rw-r--r--test/functional/plugin/lsp_spec.lua42
5 files changed, 103 insertions, 0 deletions
diff --git a/runtime/doc/lsp.txt b/runtime/doc/lsp.txt
index 8e93b188e9..02d41e7f53 100644
--- a/runtime/doc/lsp.txt
+++ b/runtime/doc/lsp.txt
@@ -755,6 +755,10 @@ start_client({config}) *vim.lsp.start_client()*
array.
{handlers} Map of language server method names to
|lsp-handler|
+ {settings} Map with language server specific
+ settings. These are returned to the language server if
+ requested via `workspace/configuration`. Keys are
+ case-sensitive.
{init_options} Values to pass in the initialization
request as `initializationOptions` .
See `initialize` in the LSP spec.
diff --git a/runtime/lua/vim/lsp/handlers.lua b/runtime/lua/vim/lsp/handlers.lua
index c26affc100..de00d36188 100644
--- a/runtime/lua/vim/lsp/handlers.lua
+++ b/runtime/lua/vim/lsp/handlers.lua
@@ -148,6 +148,31 @@ M['workspace/applyEdit'] = function(_, _, workspace_edit)
}
end
+--@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#workspace_configuration
+M['workspace/configuration'] = function(err, _, params, client_id)
+ local client = vim.lsp.get_client_by_id(client_id)
+ if not client then
+ err_message("LSP[id=", client_id, "] client has shut down after sending the message")
+ end
+ if err then error(vim.inspect(err)) end
+ if not params.items then
+ return {}
+ end
+
+ local result = {}
+ for _, item in ipairs(params.items) do
+ if item.section then
+ local value = util.lookup_section(client.config.settings, item.section) or vim.NIL
+ -- For empty sections with no explicit '' key, return settings as is
+ if value == vim.NIL and item.section == '' then
+ value = client.config.settings or vim.NIL
+ end
+ table.insert(result, value)
+ end
+ end
+ return result
+end
+
M['textDocument/publishDiagnostics'] = function(...)
return require('vim.lsp.diagnostic').on_publish_diagnostics(...)
end
diff --git a/runtime/lua/vim/lsp/util.lua b/runtime/lua/vim/lsp/util.lua
index 0972ea83c4..ecff95f61e 100644
--- a/runtime/lua/vim/lsp/util.lua
+++ b/runtime/lua/vim/lsp/util.lua
@@ -1422,6 +1422,21 @@ function M.character_offset(buf, row, col)
return str_utfindex(line, col)
end
+--- Helper function to return nested values in language server settings
+---
+--@param settings a table of language server settings
+--@param section a string indicating the field of the settings table
+--@returns (table or string) The value of settings accessed via section
+function M.lookup_section(settings, section)
+ for part in vim.gsplit(section, '.', true) do
+ settings = settings[part]
+ if not settings then
+ return
+ end
+ end
+ return settings
+end
+
M._get_line_byte_from_position = get_line_byte_from_position
M._warn_once = warn_once
diff --git a/test/functional/fixtures/fake-lsp-server.lua b/test/functional/fixtures/fake-lsp-server.lua
index a30eb748d0..252db88b6b 100644
--- a/test/functional/fixtures/fake-lsp-server.lua
+++ b/test/functional/fixtures/fake-lsp-server.lua
@@ -109,6 +109,23 @@ function tests.basic_init()
}
end
+function tests.check_workspace_configuration()
+ skeleton {
+ on_init = function(_params)
+ return { capabilities = {} }
+ end;
+ body = function()
+ notify('start')
+ notify('workspace/configuration', { items = {
+ { section = "testSetting1" };
+ { section = "testSetting2" };
+ } })
+ expect_notification('workspace/configuration', { true; vim.NIL})
+ notify('shutdown')
+ end;
+ }
+end
+
function tests.basic_check_capabilities()
skeleton {
on_init = function(params)
diff --git a/test/functional/plugin/lsp_spec.lua b/test/functional/plugin/lsp_spec.lua
index f01d90bbeb..ec06cb0639 100644
--- a/test/functional/plugin/lsp_spec.lua
+++ b/test/functional/plugin/lsp_spec.lua
@@ -262,6 +262,48 @@ describe('LSP', function()
}
end)
+ it('client should return settings via workspace/configuration handler', function()
+ local expected_callbacks = {
+ {NIL, "shutdown", {}, 1};
+ {NIL, "workspace/configuration", { items = {
+ { section = "testSetting1" };
+ { section = "testSetting2" };
+ }}, 1};
+ {NIL, "start", {}, 1};
+ }
+ local client
+ test_rpc_server {
+ test_name = "check_workspace_configuration";
+ on_init = function(_client)
+ client = _client
+ end;
+ on_exit = function(code, signal)
+ eq(0, code, "exit code", fake_lsp_logfile)
+ eq(0, signal, "exit signal", fake_lsp_logfile)
+ end;
+ on_callback = function(err, method, params, client_id)
+ eq(table.remove(expected_callbacks), {err, method, params, client_id}, "expected callback")
+ if method == 'start' then
+ exec_lua([=[
+ local client = vim.lsp.get_client_by_id(TEST_RPC_CLIENT_ID)
+ client.config.settings = {
+ testSetting1 = true;
+ testSetting2 = false;
+ }]=])
+ end
+ if method == 'workspace/configuration' then
+ local result = exec_lua([=[
+ local method, params = ...
+ return require'vim.lsp.handlers'['workspace/configuration'](err, method, params, TEST_RPC_CLIENT_ID)]=], method, params)
+ client.notify('workspace/configuration', result)
+ end
+ if method == 'shutdown' then
+ client.stop()
+ end
+ end;
+ }
+ end)
+
it('should verify capabilities sent', function()
local expected_callbacks = {
{NIL, "shutdown", {}, 1};