From 71bc53926716242845ae9cbcb5a2a9bfeae6de9d Mon Sep 17 00:00:00 2001 From: wsdjeg Date: Mon, 24 Oct 2022 21:54:20 +0800 Subject: [PATCH] feat(lsp): fix lsp layer options ref: https://github.com/SpaceVim/SpaceVim/issues/4679 --- autoload/SpaceVim/layers/lsp.vim | 128 ++++++++---------------- docs/layers/language-server-protocol.md | 34 +++++-- lua/spacevim/lsp.lua | 63 ++++++++++++ 3 files changed, 128 insertions(+), 97 deletions(-) diff --git a/autoload/SpaceVim/layers/lsp.vim b/autoload/SpaceVim/layers/lsp.vim index d6a9dc816..ea4cff642 100644 --- a/autoload/SpaceVim/layers/lsp.vim +++ b/autoload/SpaceVim/layers/lsp.vim @@ -53,66 +53,10 @@ endfunction function! SpaceVim#layers#lsp#setup() abort - lua << EOF - local nvim_lsp = require('lspconfig') - - -- Use an on_attach function to only map the following keys - -- after the language server attaches to the current buffer - local on_attach = function(client, bufnr) - local function buf_set_keymap(...) vim.api.nvim_buf_set_keymap(bufnr, ...) end - local function buf_set_option(...) vim.api.nvim_buf_set_option(bufnr, ...) end - - -- Enable completion triggered by - buf_set_option('omnifunc', 'v:lua.vim.lsp.omnifunc') - - -- Mappings. - -- local opts = { noremap=true, silent=true } - - -- See `:help vim.lsp.*` for documentation on any of the below functions - -- buf_set_keymap('n', 'gD', 'lua vim.lsp.buf.declaration()', opts) - -- buf_set_keymap('n', 'gd', 'lua vim.lsp.buf.definition()', opts) - -- buf_set_keymap('n', 'K', 'lua vim.lsp.buf.hover()', opts) - -- buf_set_keymap('n', 'gi', 'lua vim.lsp.buf.implementation()', opts) - -- buf_set_keymap('n', '', 'lua vim.lsp.buf.signature_help()', opts) - -- buf_set_keymap('n', 'wa', 'lua vim.lsp.buf.add_workspace_folder()', opts) - -- buf_set_keymap('n', 'wr', 'lua vim.lsp.buf.remove_workspace_folder()', opts) - -- buf_set_keymap('n', 'wl', 'lua print(vim.inspect(vim.lsp.buf.list_workspace_folders()))', opts) - -- buf_set_keymap('n', 'D', 'lua vim.lsp.buf.type_definition()', opts) - -- buf_set_keymap('n', 'rn', 'lua vim.lsp.buf.rename()', opts) - -- buf_set_keymap('n', 'ca', 'lua vim.lsp.buf.code_action()', opts) - -- buf_set_keymap('n', 'gr', 'lua vim.lsp.buf.references()', opts) - -- buf_set_keymap('n', 'e', 'lua require("spacevim.diagnostic").show_line_diagnostics()', opts) - -- buf_set_keymap('n', '[d', 'lua require("spacevim.diagnostic").goto_prev()', opts) - -- buf_set_keymap('n', ']d', 'lua require("spacevim.diagnostic").goto_next()', opts) - -- buf_set_keymap('n', 'q', 'lua require("spacevim.diagnostic").set_loclist()', opts) - -- buf_set_keymap('n', 'f', 'lua vim.lsp.buf.formatting()', opts) - -end - --- Use a loop to conveniently call 'setup' on multiple servers and --- map buffer local keybindings when the language server attaches -local servers = require('spacevim').eval('s:enabled_clients') -for _, lsp in ipairs(servers) do - nvim_lsp[lsp].setup { - on_attach = on_attach, - flags = { - debounce_text_changes = 150, - } - } -end -local override_client_cmds = require('spacevim').eval('s:override_client_cmds') -for client, override_cmd in pairs(override_client_cmds) do - if type(client) == "string" then - nvim_lsp[client].setup { - cmd = override_cmd, - on_attach = on_attach, - flags = { - debounce_text_changes = 150, - } - } - end -end -EOF + lua require("spacevim.lsp").setup( + \ require("spacevim").eval("s:enabled_clients"), + \ require("spacevim").eval("s:override_client_cmds") + \ ) endfunction function! SpaceVim#layers#lsp#plugins() abort @@ -144,9 +88,14 @@ function! SpaceVim#layers#lsp#plugins() abort endfunction function! SpaceVim#layers#lsp#config() abort - for ft in s:enabled_fts - call SpaceVim#lsp#reg_server(ft, s:lsp_servers[ft]) - endfor + " if nvim-lspconfig is using, do not check enabled_fts + if (has('nvim-0.5.0') && s:NVIM_VERSION.is_release_version()) || has('nvim-0.6.0') + else + + for ft in s:enabled_fts + call SpaceVim#lsp#reg_server(ft, s:lsp_servers[ft]) + endfor + endif " SpaceVim/LanguageClient-neovim {{{ let g:LanguageClient_diagnosticsDisplay = { \ 1: { @@ -267,32 +216,35 @@ let s:lsp_servers = { \ } function! SpaceVim#layers#lsp#set_variable(var) abort - let s:enabled_clients = get(a:var, 'enabled_clients', s:enabled_clients) - let override = get(a:var, 'override_cmd', {}) - let s:override_client_cmds = get(a:var, 'override_client_cmds', {}) - if !empty(override) - call extend(s:lsp_servers, override, 'force') - endif - let l:cwd = s:FILE.path_to_fname(getcwd()) - for ft in get(a:var, 'filetypes', []) - let l:cmds = get(s:lsp_servers, ft, ['']) - let l:exec = l:cmds[0] - if empty(l:exec) - call SpaceVim#logger#warn('Failed to find the lsp server command for ' . ft) - else - if executable(l:exec) - call add(s:enabled_fts, ft) - let l:newcmds = [] - for l:cmd in l:cmds - let l:newcmd = substitute(l:cmd, '#{cwd}', l:cwd, 'g') - call add(l:newcmds, l:newcmd) - endfor - let s:lsp_servers[ft] = l:newcmds - else - call SpaceVim#logger#warn('Failed to enable lsp for ' . ft . ', ' . l:exec . ' is not executable!') - endif + if (has('nvim-0.5.0') && s:NVIM_VERSION.is_release_version()) || has('nvim-0.6.0') + let s:enabled_clients = get(a:var, 'enabled_clients', s:enabled_clients) + let s:override_client_cmds = get(a:var, 'override_client_cmds', {}) + else + let override = get(a:var, 'override_cmd', {}) + if !empty(override) + call extend(s:lsp_servers, override, 'force') endif - endfor + let l:cwd = s:FILE.path_to_fname(getcwd()) + for ft in get(a:var, 'filetypes', []) + let l:cmds = get(s:lsp_servers, ft, ['']) + let l:exec = l:cmds[0] + if empty(l:exec) + call SpaceVim#logger#warn('Failed to find the lsp server command for ' . ft) + else + if executable(l:exec) + call add(s:enabled_fts, ft) + let l:newcmds = [] + for l:cmd in l:cmds + let l:newcmd = substitute(l:cmd, '#{cwd}', l:cwd, 'g') + call add(l:newcmds, l:newcmd) + endfor + let s:lsp_servers[ft] = l:newcmds + else + call SpaceVim#logger#warn('Failed to enable lsp for ' . ft . ', ' . l:exec . ' is not executable!') + endif + endif + endfor + endif endfunction function! SpaceVim#layers#lsp#check_filetype(ft) abort diff --git a/docs/layers/language-server-protocol.md b/docs/layers/language-server-protocol.md index 4f1adf62d..b868875e1 100644 --- a/docs/layers/language-server-protocol.md +++ b/docs/layers/language-server-protocol.md @@ -12,6 +12,8 @@ description: "This layers provides language server protocol for vim and neovim" - [Install](#install) - [Install language server](#install-language-server) - [Configuration](#configuration) + - [neovim(`>=0.5.0`)](#neovim050) + - [vim or neovim(`<0.5.0`)](#vim-or-neovim050) - [Key bindings](#key-bindings) @@ -126,6 +128,29 @@ npm install -g vim-language-server ## Configuration +### neovim(`>=0.5.0`) + +If you are using `nvim(>=0.5.0)`. You need to use `enabled_clients` to specific the language servers. +for example: + +```toml +[[layers]] + name = 'lsp' + enabled_clients = ['vimls', 'clangd'] +``` + +To override the command of client, you may need to use `override_client_cmds` option: + +```toml +[[layers]] + name = "lsp" + enabled_clients = ['vimls', 'clangd'] + [layers.override_client_cmds] + vimls = ["vim-language-server", "--stdio"] +``` + +### vim or neovim(`<0.5.0`) + To enable lsp support for a specified filetype, you may need to load this layer with `filetypes` option, for example: ```toml @@ -181,15 +206,6 @@ To override the server command, you may need to use `override_cmd` option: rust = ["rustup", "run", "nightly", "rls"] ``` -If you are using `nvim(>=0.5.0)`. You need to use `enabled_clients` to specific the language servers. -for example: - -```toml -[[layers]] - name = 'lsp' - enabled_clients = ['vimls', 'clangd'] -``` - ## Key bindings | Key Binding | Description | diff --git a/lua/spacevim/lsp.lua b/lua/spacevim/lsp.lua index 5e2b910a5..2ea591bb4 100644 --- a/lua/spacevim/lsp.lua +++ b/lua/spacevim/lsp.lua @@ -10,6 +10,69 @@ function M.register(filetype, cmd) } end +function M.setup(enabled_clients, override_client_cmds) -- {{{ + local nvim_lsp = require('lspconfig') + + -- Use an on_attach function to only map the following keys + -- after the language server attaches to the current buffer + local on_attach = function(client, bufnr) + local function buf_set_keymap(...) + vim.api.nvim_buf_set_keymap(bufnr, ...) + end + local function buf_set_option(...) + vim.api.nvim_buf_set_option(bufnr, ...) + end + + -- Enable completion triggered by + buf_set_option('omnifunc', 'v:lua.vim.lsp.omnifunc') + + -- Mappings. + -- local opts = { noremap=true, silent=true } + + -- See `:help vim.lsp.*` for documentation on any of the below functions + -- buf_set_keymap('n', 'gD', 'lua vim.lsp.buf.declaration()', opts) + -- buf_set_keymap('n', 'gd', 'lua vim.lsp.buf.definition()', opts) + -- buf_set_keymap('n', 'K', 'lua vim.lsp.buf.hover()', opts) + -- buf_set_keymap('n', 'gi', 'lua vim.lsp.buf.implementation()', opts) + -- buf_set_keymap('n', '', 'lua vim.lsp.buf.signature_help()', opts) + -- buf_set_keymap('n', 'wa', 'lua vim.lsp.buf.add_workspace_folder()', opts) + -- buf_set_keymap('n', 'wr', 'lua vim.lsp.buf.remove_workspace_folder()', opts) + -- buf_set_keymap('n', 'wl', 'lua print(vim.inspect(vim.lsp.buf.list_workspace_folders()))', opts) + -- buf_set_keymap('n', 'D', 'lua vim.lsp.buf.type_definition()', opts) + -- buf_set_keymap('n', 'rn', 'lua vim.lsp.buf.rename()', opts) + -- buf_set_keymap('n', 'ca', 'lua vim.lsp.buf.code_action()', opts) + -- buf_set_keymap('n', 'gr', 'lua vim.lsp.buf.references()', opts) + -- buf_set_keymap('n', 'e', 'lua require("spacevim.diagnostic").show_line_diagnostics()', opts) + -- buf_set_keymap('n', '[d', 'lua require("spacevim.diagnostic").goto_prev()', opts) + -- buf_set_keymap('n', ']d', 'lua require("spacevim.diagnostic").goto_next()', opts) + -- buf_set_keymap('n', 'q', 'lua require("spacevim.diagnostic").set_loclist()', opts) + -- buf_set_keymap('n', 'f', 'lua vim.lsp.buf.formatting()', opts) + end + + -- Use a loop to conveniently call 'setup' on multiple servers and + -- map buffer local keybindings when the language server attaches + for _, lsp in ipairs(enabled_clients) do + nvim_lsp[lsp].setup({ + on_attach = on_attach, + flags = { + debounce_text_changes = 150, + }, + }) + end + for client, override_cmd in pairs(override_client_cmds) do + if type(client) == 'string' then + nvim_lsp[client].setup({ + cmd = override_cmd, + on_attach = on_attach, + flags = { + debounce_text_changes = 150, + }, + }) + end + end +end +-- }}} + local function spliteof(data, delimiter) local result = {} local from = 1