diff options
| author | Michael Lingelbach <m.j.lbach@gmail.com> | 2021-11-11 01:00:24 -0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-11-11 01:00:24 -0800 |
| commit | 0d1ce78d231773046320caa45fe1a18dfa366761 (patch) | |
| tree | fde488c8490f93b6ad88ef8a32e77ff9b4e49d34 /lua | |
| parent | docs: make CONTRIBUTING more visible via move (#1396) (diff) | |
| download | nvim-lspconfig-0d1ce78d231773046320caa45fe1a18dfa366761.tar nvim-lspconfig-0d1ce78d231773046320caa45fe1a18dfa366761.tar.gz nvim-lspconfig-0d1ce78d231773046320caa45fe1a18dfa366761.tar.bz2 nvim-lspconfig-0d1ce78d231773046320caa45fe1a18dfa366761.tar.lz nvim-lspconfig-0d1ce78d231773046320caa45fe1a18dfa366761.tar.xz nvim-lspconfig-0d1ce78d231773046320caa45fe1a18dfa366761.tar.zst nvim-lspconfig-0d1ce78d231773046320caa45fe1a18dfa366761.zip | |
feat: add single file mode (#1385)
* This adds a "single file mode" option for each language server
* Currently, if a root is not detected, a new language server is started
for each file opened.
* Root directory is set to `nil` in start_client. Some servers will
refuse to start, or otherwise panic. This is opt-in per server.
* Some servers, such as rust-analyzer, explicitly have a "single file
mode", we will not support that until it is officially part of the LSP
specification
Co-authored-by: Peter Lithammer <peter.lithammer@gmail.com>
Diffstat (limited to 'lua')
42 files changed, 160 insertions, 134 deletions
diff --git a/lua/lspconfig/bashls.lua b/lua/lspconfig/bashls.lua index c42f4c74..9fe3f397 100644 --- a/lua/lspconfig/bashls.lua +++ b/lua/lspconfig/bashls.lua @@ -14,9 +14,8 @@ configs[server_name] = { GLOB_PATTERN = vim.env.GLOB_PATTERN or '*@(.sh|.inc|.bash|.command)', }, filetypes = { 'sh' }, - root_dir = function(fname) - return util.root_pattern '.git'(fname) or util.path.dirname(fname) - end, + root_dir = util.root_pattern '.git', + single_file_support = true, }, docs = { description = [[ diff --git a/lua/lspconfig/beancount.lua b/lua/lspconfig/beancount.lua index 2aa92479..f5e69114 100644 --- a/lua/lspconfig/beancount.lua +++ b/lua/lspconfig/beancount.lua @@ -8,9 +8,8 @@ configs[server_name] = { default_config = { cmd = { bin_name }, filetypes = { 'beancount' }, - root_dir = function(fname) - return util.find_git_ancestor(fname) or util.path.dirname(fname) - end, + root_dir = util.find_git_ancestor, + single_file_support = true, init_options = { -- this is the path to the beancout journal file journalFile = '', diff --git a/lua/lspconfig/ccls.lua b/lua/lspconfig/ccls.lua index d7170662..ac5949e8 100644 --- a/lua/lspconfig/ccls.lua +++ b/lua/lspconfig/ccls.lua @@ -5,10 +5,8 @@ configs.ccls = { default_config = { cmd = { 'ccls' }, filetypes = { 'c', 'cpp', 'objc', 'objcpp' }, - root_dir = function(fname) - return util.root_pattern('compile_commands.json', '.ccls', 'compile_flags.txt', '.git')(fname) - or util.path.dirname(fname) - end, + root_dir = util.root_pattern('compile_commands.json', '.ccls', 'compile_flags.txt', '.git'), + single_file_support = true, }, docs = { description = [[ diff --git a/lua/lspconfig/clangd.lua b/lua/lspconfig/clangd.lua index d2a1000d..7fe9ada1 100644 --- a/lua/lspconfig/clangd.lua +++ b/lua/lspconfig/clangd.lua @@ -43,8 +43,9 @@ configs.clangd = { filetypes = { 'c', 'cpp', 'objc', 'objcpp' }, root_dir = function(fname) local filename = util.path.is_absolute(fname) and fname or util.path.join(vim.loop.cwd(), fname) - return root_pattern(filename) or util.path.dirname(filename) + return root_pattern(filename) end, + single_file_support = true, capabilities = default_capabilities, }, commands = { diff --git a/lua/lspconfig/cmake.lua b/lua/lspconfig/cmake.lua index a648c444..9592dec2 100644 --- a/lua/lspconfig/cmake.lua +++ b/lua/lspconfig/cmake.lua @@ -5,9 +5,8 @@ configs.cmake = { default_config = { cmd = { 'cmake-language-server' }, filetypes = { 'cmake' }, - root_dir = function(fname) - return util.root_pattern('.git', 'compile_commands.json', 'build')(fname) or util.path.dirname(fname) - end, + root_dir = util.root_pattern('.git', 'compile_commands.json', 'build'), + single_file_support = true, init_options = { buildDirectory = 'build', }, diff --git a/lua/lspconfig/codeqlls.lua b/lua/lspconfig/codeqlls.lua index 5bb13a48..e80070e7 100644 --- a/lua/lspconfig/codeqlls.lua +++ b/lua/lspconfig/codeqlls.lua @@ -3,15 +3,12 @@ local util = require 'lspconfig/util' local server_name = 'codeqlls' -local root_pattern = util.root_pattern 'qlpack.yml' - configs[server_name] = { default_config = { cmd = { 'codeql', 'execute', 'language-server', '--check-errors', 'ON_CHANGE', '-q' }, filetypes = { 'ql' }, - root_dir = function(fname) - return root_pattern(fname) or util.path.dirname(fname) - end, + root_dir = util.root_pattern 'qlpack.yml', + single_file_support = true, log_level = vim.lsp.protocol.MessageType.Warning, before_init = function(initialize_params) initialize_params['workspaceFolders'] = { diff --git a/lua/lspconfig/configs.lua b/lua/lspconfig/configs.lua index 2f4cd0d7..f69e2673 100644 --- a/lua/lspconfig/configs.lua +++ b/lua/lspconfig/configs.lua @@ -78,22 +78,29 @@ function configs.__newindex(t, config_name, config_def) function M.launch() local root_dir = get_root_dir(api.nvim_buf_get_name(0), api.nvim_get_current_buf()) - if not root_dir then - vim.notify(string.format('Launching %s failed: matching root directory not detected.', config_name)) - return - end - api.nvim_command( - string.format( - "autocmd %s unsilent lua require'lspconfig'[%q].manager.try_add_wrapper()", - 'BufReadPost ' .. root_dir .. '/*', - config.name + if root_dir then + api.nvim_command( + string.format( + "autocmd %s unsilent lua require'lspconfig'[%q].manager.try_add_wrapper()", + 'BufReadPost ' .. root_dir .. '/*', + config.name + ) ) - ) - for _, bufnr in ipairs(vim.api.nvim_list_bufs()) do - local buf_dir = api.nvim_buf_get_name(bufnr) - if buf_dir:sub(1, root_dir:len()) == root_dir then - M.manager.try_add_wrapper(bufnr) + for _, bufnr in ipairs(vim.api.nvim_list_bufs()) do + local buf_dir = api.nvim_buf_get_name(bufnr) + if buf_dir:sub(1, root_dir:len()) == root_dir then + M.manager.try_add_wrapper(bufnr) + end end + elseif config.single_file_support then + -- This allows on_new_config to use the parent directory of the file + -- Effectively this is the root from lspconfig's perspective, as we use + -- this to attach additional files in the same parent folder to the same server. + -- We just no longer send rootDirectory or workspaceFolders during initialization. + local pseudo_root = util.path.dirname(api.nvim_buf_get_name(0)) + M.manager.add(pseudo_root, true) + else + vim.notify(string.format('Autostart for %s failed: matching root directory not detected.', config_name)) end end @@ -182,11 +189,23 @@ function configs.__newindex(t, config_name, config_def) function manager.try_add(bufnr) bufnr = bufnr or api.nvim_get_current_buf() + if vim.api.nvim_buf_get_option(bufnr, 'buftype') == 'nofile' then return end + + local id local root_dir = get_root_dir(api.nvim_buf_get_name(bufnr), bufnr) - local id = manager.add(root_dir) + + if root_dir then + id = manager.add(root_dir, false) + elseif config.single_file_support then + local pseudo_root = util.path.dirname(api.nvim_buf_get_name(0)) + id = manager.add(pseudo_root, true) + else + vim.notify(string.format('Autostart for %s failed: matching root directory not detected.', config_name)) + end + if id then lsp.buf_attach_client(bufnr, id) end diff --git a/lua/lspconfig/crystalline.lua b/lua/lspconfig/crystalline.lua index 8943937d..3bd4e390 100644 --- a/lua/lspconfig/crystalline.lua +++ b/lua/lspconfig/crystalline.lua @@ -5,9 +5,8 @@ configs.crystalline = { default_config = { cmd = { 'crystalline' }, filetypes = { 'crystal' }, - root_dir = function(fname) - return util.root_pattern 'shard.yml'(fname) or util.find_git_ancestor(fname) or util.path.dirname(fname) - end, + root_dir = util.root_pattern 'shard.yml' or util.find_git_ancestor, + single_file_support = true, }, docs = { description = [[ diff --git a/lua/lspconfig/cssls.lua b/lua/lspconfig/cssls.lua index 3a2fe3c7..07cc608f 100644 --- a/lua/lspconfig/cssls.lua +++ b/lua/lspconfig/cssls.lua @@ -8,9 +8,8 @@ configs[server_name] = { default_config = { cmd = { bin_name, '--stdio' }, filetypes = { 'css', 'scss', 'less' }, - root_dir = function(fname) - return util.root_pattern('package.json', '.git')(fname) or util.path.dirname(fname) - end, + root_dir = util.root_pattern('package.json', '.git'), + single_file_support = true, settings = { css = { validate = true }, scss = { validate = true }, diff --git a/lua/lspconfig/dhall_lsp_server.lua b/lua/lspconfig/dhall_lsp_server.lua index ae08b928..9378ed62 100644 --- a/lua/lspconfig/dhall_lsp_server.lua +++ b/lua/lspconfig/dhall_lsp_server.lua @@ -5,9 +5,8 @@ configs.dhall_lsp_server = { default_config = { cmd = { 'dhall-lsp-server' }, filetypes = { 'dhall' }, - root_dir = function(fname) - return util.root_pattern '.git'(fname) or util.path.dirname(fname) - end, + root_dir = util.find_git_ancestor, + single_file_support = true, }, docs = { description = [[ diff --git a/lua/lspconfig/diagnosticls.lua b/lua/lspconfig/diagnosticls.lua index 3c61e156..ccfd76bd 100644 --- a/lua/lspconfig/diagnosticls.lua +++ b/lua/lspconfig/diagnosticls.lua @@ -10,8 +10,9 @@ end configs[server_name] = { default_config = { cmd = { bin_name, '--stdio' }, + root_dir = util.find_git_ancestor, + single_file_support = true, filetypes = {}, - root_dir = util.path.dirname, }, docs = { description = [[ diff --git a/lua/lspconfig/dotls.lua b/lua/lspconfig/dotls.lua index 7d660295..be1e86f3 100644 --- a/lua/lspconfig/dotls.lua +++ b/lua/lspconfig/dotls.lua @@ -12,9 +12,8 @@ configs[server_name] = { default_config = { cmd = { bin_name, '--stdio' }, filetypes = { 'dot' }, - root_dir = function(fname) - return util.root_pattern(unpack(root_files))(fname) or util.path.dirname(fname) - end, + root_dir = util.root_pattern(unpack(root_files)), + single_file_support = true, }, docs = { description = [[ diff --git a/lua/lspconfig/efm.lua b/lua/lspconfig/efm.lua index 0f2779d4..445dc6da 100644 --- a/lua/lspconfig/efm.lua +++ b/lua/lspconfig/efm.lua @@ -7,9 +7,8 @@ local bin_name = 'efm-langserver' configs[server_name] = { default_config = { cmd = { bin_name }, - root_dir = function(fname) - return util.root_pattern '.git'(fname) or util.path.dirname(fname) - end, + root_dir = util.find_git_ancestor, + single_file_support = true, }, docs = { @@ -31,7 +30,7 @@ require('lspconfig')['efm'].setup{ ]], default_config = { - root_dir = [[util.root_pattern(".git")(fname) or util.path.dirname(fname)]], + root_dir = [[util.root_pattern(".git")]], }, }, } diff --git a/lua/lspconfig/erlangls.lua b/lua/lspconfig/erlangls.lua index a161a194..adaf9b35 100644 --- a/lua/lspconfig/erlangls.lua +++ b/lua/lspconfig/erlangls.lua @@ -5,9 +5,8 @@ configs.erlangls = { default_config = { cmd = { 'erlang_ls' }, filetypes = { 'erlang' }, - root_dir = function(fname) - return util.root_pattern('rebar.config', 'erlang.mk', '.git')(fname) or util.path.dirname(fname) - end, + root_dir = util.root_pattern('rebar.config', 'erlang.mk', '.git'), + single_file_support = true, }, docs = { description = [[ @@ -25,7 +24,7 @@ Installation requirements: - [rebar3 3.9.1+](https://github.com/erlang/rebar3) ]], default_config = { - root_dir = [[root_pattern('rebar.config', 'erlang.mk', '.git') or util.path.dirname(fname)]], + root_dir = [[root_pattern('rebar.config', 'erlang.mk', '.git')]], }, }, } diff --git a/lua/lspconfig/html.lua b/lua/lspconfig/html.lua index 01a7dcc0..c2ac4f36 100644 --- a/lua/lspconfig/html.lua +++ b/lua/lspconfig/html.lua @@ -8,9 +8,8 @@ configs[server_name] = { default_config = { cmd = { bin_name, '--stdio' }, filetypes = { 'html' }, - root_dir = function(fname) - return util.root_pattern('package.json', '.git')(fname) or util.path.dirname(fname) - end, + root_dir = util.root_pattern('package.json', '.git'), + single_file_support = true, settings = {}, init_options = { embeddedLanguages = { css = true, javascript = true }, diff --git a/lua/lspconfig/jdtls.lua b/lua/lspconfig/jdtls.lua index d48272db..ad448448 100644 --- a/lua/lspconfig/jdtls.lua +++ b/lua/lspconfig/jdtls.lua @@ -134,8 +134,8 @@ configs[server_name] = { return root end end - return vim.fn.getcwd() end, + single_file_mode = true, init_options = { workspace = get_workspace_dir(), jvm_args = {}, diff --git a/lua/lspconfig/jedi_language_server.lua b/lua/lspconfig/jedi_language_server.lua index 714814af..4de08799 100644 --- a/lua/lspconfig/jedi_language_server.lua +++ b/lua/lspconfig/jedi_language_server.lua @@ -1,12 +1,20 @@ local configs = require 'lspconfig/configs' +local util = require 'lspconfig/util' + +local root_files = { + 'pyproject.toml', + 'setup.py', + 'setup.cfg', + 'requirements.txt', + 'Pipfile', +} configs.jedi_language_server = { default_config = { cmd = { 'jedi-language-server' }, filetypes = { 'python' }, - root_dir = function(fname) - return vim.fn.getcwd() - end, + root_dir = util.root_pattern(unpack(root_files)), + single_file_support = true, }, docs = { description = [[ diff --git a/lua/lspconfig/jsonls.lua b/lua/lspconfig/jsonls.lua index 4349d401..6b391950 100644 --- a/lua/lspconfig/jsonls.lua +++ b/lua/lspconfig/jsonls.lua @@ -11,9 +11,8 @@ configs[server_name] = { init_options = { provideFormatter = true, }, - root_dir = function(fname) - return util.root_pattern '.git'(fname) or util.path.dirname(fname) - end, + root_dir = util.root_pattern '.git', + single_file_support = true, }, docs = { -- this language server config is in VSCode built-in package.json diff --git a/lua/lspconfig/julials.lua b/lua/lspconfig/julials.lua index e67e788b..75acf07f 100644 --- a/lua/lspconfig/julials.lua +++ b/lua/lspconfig/julials.lua @@ -48,9 +48,8 @@ configs.julials = { new_config.cmd_cwd = root_dir end, filetypes = { 'julia' }, - root_dir = function(fname) - return util.find_git_ancestor(fname) or util.path.dirname(fname) - end, + root_dir = util.find_git_ancestor, + single_file_support = true, }, docs = { package_json = 'https://raw.githubusercontent.com/julia-vscode/julia-vscode/master/package.json', diff --git a/lua/lspconfig/lean3ls.lua b/lua/lspconfig/lean3ls.lua index 0ac7cf54..65dc815b 100644 --- a/lua/lspconfig/lean3ls.lua +++ b/lua/lspconfig/lean3ls.lua @@ -19,8 +19,8 @@ configs.lean3ls = { or util.root_pattern 'leanpkg.path'(fname) or stdlib_dir or util.find_git_ancestor(fname) - or util.path.dirname(fname) end, + single_file_support = true, on_new_config = function(config, root) if not config.cmd_cwd then config.cmd_cwd = root diff --git a/lua/lspconfig/leanls.lua b/lua/lspconfig/leanls.lua index 328da43e..cfefb808 100644 --- a/lua/lspconfig/leanls.lua +++ b/lua/lspconfig/leanls.lua @@ -15,11 +15,9 @@ configs.leanls = { end end - return util.root_pattern 'leanpkg.toml'(fname) - or stdlib_dir - or util.find_git_ancestor(fname) - or util.path.dirname(fname) + return util.root_pattern 'leanpkg.toml'(fname) or stdlib_dir or util.find_git_ancestor(fname) end, + single_file_support = true, on_new_config = function(config, root) if not config.cmd_cwd then config.cmd_cwd = root diff --git a/lua/lspconfig/lemminx.lua b/lua/lspconfig/lemminx.lua index ecb0b444..31f4df23 100644 --- a/lua/lspconfig/lemminx.lua +++ b/lua/lspconfig/lemminx.lua @@ -5,9 +5,8 @@ local server_name = 'lemminx' configs[server_name] = { default_config = { filetypes = { 'xml', 'xsd', 'svg' }, - root_dir = function(filename) - return util.root_pattern '.git'(filename) or util.path.dirname(filename) - end, + root_dir = util.root_pattern '.git', + single_file_support = true, }, docs = { description = [[ diff --git a/lua/lspconfig/mint.lua b/lua/lspconfig/mint.lua index 3d213d08..670d26d8 100644 --- a/lua/lspconfig/mint.lua +++ b/lua/lspconfig/mint.lua @@ -6,8 +6,9 @@ configs.mint = { cmd = { 'mint', 'ls' }, filetypes = { 'mint' }, root_dir = function(fname) - return util.root_pattern 'mint.json'(fname) or util.find_git_ancestor(fname) or util.path.dirname(fname) + return util.root_pattern 'mint.json'(fname) or util.find_git_ancestor(fname) end, + single_file_support = true, }, docs = { description = [[ diff --git a/lua/lspconfig/nimls.lua b/lua/lspconfig/nimls.lua index 3f537f7c..d74dcc99 100644 --- a/lua/lspconfig/nimls.lua +++ b/lua/lspconfig/nimls.lua @@ -6,8 +6,9 @@ configs.nimls = { cmd = { 'nimlsp' }, filetypes = { 'nim' }, root_dir = function(fname) - return util.root_pattern '*.nimble'(fname) or util.find_git_ancestor(fname) or util.path.dirname(fname) + return util.root_pattern '*.nimble'(fname) or util.find_git_ancestor(fname) end, + single_file_support = true, }, docs = { package_json = 'https://raw.githubusercontent.com/pragmagic/vscode-nim/master/package.json', diff --git a/lua/lspconfig/pasls.lua b/lua/lspconfig/pasls.lua index 4cceb13f..e818300c 100644 --- a/lua/lspconfig/pasls.lua +++ b/lua/lspconfig/pasls.lua @@ -5,9 +5,8 @@ configs.pasls = { default_config = { cmd = { 'pasls' }, filetypes = { 'pascal' }, - root_dir = function(fname) - return util.find_git_ancestor(fname) or util.path.dirname(fname) - end, + root_dir = util.find_git_ancestor, + single_file_support = true, }, docs = { description = [[ diff --git a/lua/lspconfig/perlls.lua b/lua/lspconfig/perlls.lua index 4ef81596..61275267 100644 --- a/lua/lspconfig/perlls.lua +++ b/lua/lspconfig/perlls.lua @@ -22,9 +22,8 @@ configs.perlls = { }, }, filetypes = { 'perl' }, - root_dir = function(fname) - return util.root_pattern '.git'(fname) or vim.fn.getcwd() - end, + root_dir = util.find_git_ancestor, + single_file_mode = true, }, docs = { package_json = 'https://raw.githubusercontent.com/richterger/Perl-LanguageServer/master/clients/vscode/perl/package.json', diff --git a/lua/lspconfig/perlpls.lua b/lua/lspconfig/perlpls.lua index af0b51e4..81ea7ad6 100644 --- a/lua/lspconfig/perlpls.lua +++ b/lua/lspconfig/perlpls.lua @@ -10,9 +10,8 @@ configs.perlpls = { }, }, filetypes = { 'perl' }, - root_dir = function(fname) - return util.root_pattern '.git'(fname) or util.path.dirname(fname) - end, + root_dir = util.root_pattern '.git', + single_file_support = true, }, docs = { package_json = 'https://raw.githubusercontent.com/FractalBoy/perl-language-server/master/client/package.json', diff --git a/lua/lspconfig/powershell_es.lua b/lua/lspconfig/powershell_es.lua index 528b8cf3..e2fd86ef 100644 --- a/lua/lspconfig/powershell_es.lua +++ b/lua/lspconfig/powershell_es.lua @@ -20,9 +20,8 @@ configs[server_name] = { new_config.cmd = make_cmd(bundle_path) end, filetypes = { 'ps1' }, - root_dir = function(fname) - return util.find_git_ancestor(fname) or vim.fn.getcwd() - end, + root_dir = util.find_git_ancestor, + single_file_mode = true, }, docs = { description = [[ diff --git a/lua/lspconfig/puppet.lua b/lua/lspconfig/puppet.lua index abdbfc5a..3882823d 100644 --- a/lua/lspconfig/puppet.lua +++ b/lua/lspconfig/puppet.lua @@ -15,9 +15,8 @@ configs[server_name] = { default_config = { cmd = { bin_name, '--stdio' }, filetypes = { 'puppet' }, - root_dir = function(fname) - return util.root_pattern(unpack(root_files))(fname) or util.path.dirname(fname) - end, + root_dir = util.root_pattern(unpack(root_files)), + single_file_support = true, }, docs = { package_json = 'https://raw.githubusercontent.com/puppetlabs/puppet-vscode/main/package.json', diff --git a/lua/lspconfig/pylsp.lua b/lua/lspconfig/pylsp.lua index 66756da5..42a87150 100644 --- a/lua/lspconfig/pylsp.lua +++ b/lua/lspconfig/pylsp.lua @@ -13,8 +13,9 @@ configs.pylsp = { 'requirements.txt', 'Pipfile', } - return util.root_pattern(unpack(root_files))(fname) or util.find_git_ancestor(fname) or util.path.dirname(fname) + return util.root_pattern(unpack(root_files))(fname) or util.find_git_ancestor(fname) end, + single_file_support = true, }, docs = { description = [[ diff --git a/lua/lspconfig/pyright.lua b/lua/lspconfig/pyright.lua index f9fe56d6..d17aac5e 100644 --- a/lua/lspconfig/pyright.lua +++ b/lua/lspconfig/pyright.lua @@ -7,6 +7,15 @@ if vim.fn.has 'win32' == 1 then bin_name = bin_name .. '.cmd' end +local root_files = { + 'pyproject.toml', + 'setup.py', + 'setup.cfg', + 'requirements.txt', + 'Pipfile', + 'pyrightconfig.json', +} + local function organize_imports() local params = { command = 'pyright.organizeimports', @@ -19,17 +28,8 @@ configs[server_name] = { default_config = { cmd = { bin_name, '--stdio' }, filetypes = { 'python' }, - root_dir = function(fname) - local root_files = { - 'pyproject.toml', - 'setup.py', - 'setup.cfg', - 'requirements.txt', - 'Pipfile', - 'pyrightconfig.json', - } - return util.root_pattern(unpack(root_files))(fname) or util.find_git_ancestor(fname) or util.path.dirname(fname) - end, + root_dir = util.root_pattern(unpack(root_files)), + single_file_support = true, settings = { python = { analysis = { diff --git a/lua/lspconfig/racket_langserver.lua b/lua/lspconfig/racket_langserver.lua index 7a31562b..71c95636 100644 --- a/lua/lspconfig/racket_langserver.lua +++ b/lua/lspconfig/racket_langserver.lua @@ -9,9 +9,8 @@ configs.racket_langserver = { default_config = { cmd = { 'racket', '--lib', 'racket-langserver' }, filetypes = { 'racket', 'scheme' }, - root_dir = function(fname) - return util.root_pattern(unpack(root_files))(fname) or util.path.dirname(fname) - end, + root_dir = util.root_pattern(unpack(root_files)), + single_file_support = true, }, docs = { description = [[ diff --git a/lua/lspconfig/rome.lua b/lua/lspconfig/rome.lua index a54b0168..242fa2c2 100644 --- a/lua/lspconfig/rome.lua +++ b/lua/lspconfig/rome.lua @@ -16,8 +16,8 @@ configs.rome = { return util.find_package_json_ancestor(fname) or util.find_node_modules_ancestor(fname) or util.find_git_ancestor(fname) - or util.path.dirname(fname) end, + single_file_support = true, }, docs = { description = [[ diff --git a/lua/lspconfig/scry.lua b/lua/lspconfig/scry.lua index 0d8c5b25..3d57d801 100644 --- a/lua/lspconfig/scry.lua +++ b/lua/lspconfig/scry.lua @@ -6,8 +6,9 @@ configs.scry = { cmd = { 'scry' }, filetypes = { 'crystal' }, root_dir = function(fname) - return util.root_pattern 'shard.yml'(fname) or util.find_git_ancestor(fname) or util.path.dirname(fname) + return util.root_pattern 'shard.yml'(fname) or util.find_git_ancestor(fname) end, + single_file_support = true, }, docs = { description = [[ diff --git a/lua/lspconfig/sqls.lua b/lua/lspconfig/sqls.lua index 6eeb8f83..307f204f 100644 --- a/lua/lspconfig/sqls.lua +++ b/lua/lspconfig/sqls.lua @@ -5,9 +5,8 @@ configs.sqls = { default_config = { cmd = { 'sqls' }, filetypes = { 'sql', 'mysql' }, - root_dir = function(fname) - return util.root_pattern 'config.yml'(fname) or util.path.dirname(fname) - end, + root_dir = util.root_pattern 'config.yml', + single_file_support = true, settings = {}, }, docs = { diff --git a/lua/lspconfig/sumneko_lua.lua b/lua/lspconfig/sumneko_lua.lua index da95db88..36df08ed 100644 --- a/lua/lspconfig/sumneko_lua.lua +++ b/lua/lspconfig/sumneko_lua.lua @@ -6,9 +6,8 @@ local name = 'sumneko_lua' configs[name] = { default_config = { filetypes = { 'lua' }, - root_dir = function(fname) - return util.find_git_ancestor(fname) or util.path.dirname(fname) - end, + root_dir = util.find_git_ancestor, + single_file_support = true, log_level = vim.lsp.protocol.MessageType.Warning, settings = { Lua = { telemetry = { enable = false } } }, }, diff --git a/lua/lspconfig/taplo.lua b/lua/lspconfig/taplo.lua index f9a14631..5c64adc3 100644 --- a/lua/lspconfig/taplo.lua +++ b/lua/lspconfig/taplo.lua @@ -6,8 +6,9 @@ configs.taplo = { cmd = { 'taplo-lsp', 'run' }, filetypes = { 'toml' }, root_dir = function(fname) - return util.root_pattern '*.toml'(fname) or util.find_git_ancestor(fname) or util.path.dirname(fname) + return util.root_pattern '*.toml'(fname) or util.find_git_ancestor(fname) end, + single_file_support = true, }, docs = { description = [[ @@ -21,7 +22,7 @@ cargo install taplo-lsp ``` ]], default_config = { - root_dir = [[root_pattern("*.toml", ".git") or dirname]], + root_dir = [[root_pattern("*.toml", ".git")]], }, }, } diff --git a/lua/lspconfig/texlab.lua b/lua/lspconfig/texlab.lua index 232773bc..c1612255 100644 --- a/lua/lspconfig/texlab.lua +++ b/lua/lspconfig/texlab.lua @@ -69,7 +69,8 @@ configs.texlab = { default_config = { cmd = { 'texlab' }, filetypes = { 'tex', 'bib' }, - root_dir = util.path.dirname, + root_dir = util.find_git_ancestor, + single_file_support = true, settings = { texlab = { rootDirectory = nil, diff --git a/lua/lspconfig/ui/lspinfo.lua b/lua/lspconfig/ui/lspinfo.lua index 5178939d..6aaa6196 100644 --- a/lua/lspconfig/ui/lspinfo.lua +++ b/lua/lspconfig/ui/lspinfo.lua @@ -73,7 +73,11 @@ local function make_client_info(client) local client_info = {} client_info.cmd = remove_newlines(client.config.cmd) - client_info.root_dir = client.workspaceFolders[1].name + if client.workspaceFolders then + client_info.root_dir = client.workspaceFolders[1].name + else + client_info.root_dir = 'Running in single file mode.' + end client_info.filetypes = table.concat(client.config.filetypes or {}, ', ') client_info.autostart = (client.config.autostart and 'true') or 'false' client_info.attached_buffers_list = table.concat(vim.lsp.get_buffers_by_client_id(client.id), ', ') diff --git a/lua/lspconfig/util.lua b/lua/lspconfig/util.lua index 3691da68..dbac70fd 100644 --- a/lua/lspconfig/util.lua +++ b/lua/lspconfig/util.lua @@ -233,18 +233,24 @@ end)() -- seen before, will call make_config(root_dir) and start a new client. function M.server_per_root_dir_manager(_make_config) local clients = {} + local single_file_clients = {} local manager = {} - function manager.add(root_dir) - if not root_dir then - return - end - if not M.path.is_dir(root_dir) then - return + function manager.add(root_dir, single_file_mode) + local client_id + if single_file_mode then + client_id = single_file_clients[root_dir] + else + if not root_dir then + return + end + if not M.path.is_dir(root_dir) then + return + end + client_id = clients[root_dir] end -- Check if we have a client already or start and store it. - local client_id = clients[root_dir] if not client_id then local new_config = _make_config(root_dir) -- do nothing if the client is not enabled @@ -265,9 +271,20 @@ function M.server_per_root_dir_manager(_make_config) end new_config.on_exit = M.add_hook_before(new_config.on_exit, function() clients[root_dir] = nil + single_file_clients[root_dir] = nil end) + -- Sending rootDirectory and workspaceFolders as null is not explicitly + -- codified in the spec. Certain servers crash if initialized with a NULL + -- root directory. + if single_file_mode then + new_config.root_dir = nil + end client_id = lsp.start_client(new_config) - clients[root_dir] = client_id + if single_file_mode then + single_file_clients[root_dir] = client_id + else + clients[root_dir] = client_id + end end return client_id end diff --git a/lua/lspconfig/yamlls.lua b/lua/lspconfig/yamlls.lua index 3154556d..bb432c70 100644 --- a/lua/lspconfig/yamlls.lua +++ b/lua/lspconfig/yamlls.lua @@ -8,9 +8,8 @@ configs[server_name] = { default_config = { cmd = { bin_name, '--stdio' }, filetypes = { 'yaml' }, - root_dir = function(fname) - return util.root_pattern '.git'(fname) or util.path.dirname(fname) - end, + root_dir = util.root_pattern '.git', + single_file_support = true, settings = { -- https://github.com/redhat-developer/vscode-redhat-telemetry#how-to-disable-telemetry-reporting redhat = { telemetry = { enabled = false } }, diff --git a/lua/lspconfig/zls.lua b/lua/lspconfig/zls.lua index 311be3f5..a156f029 100644 --- a/lua/lspconfig/zls.lua +++ b/lua/lspconfig/zls.lua @@ -5,9 +5,8 @@ configs.zls = { default_config = { cmd = { 'zls' }, filetypes = { 'zig', 'zir' }, - root_dir = function(fname) - return util.root_pattern('zls.json', '.git')(fname) or util.path.dirname(fname) - end, + root_dir = util.root_pattern('zls.json', '.git'), + single_file_support = true, }, docs = { description = [[ |
