diff options
Diffstat (limited to '.vim/lua/internal/lsp.lua')
| -rw-r--r-- | .vim/lua/internal/lsp.lua | 299 |
1 files changed, 299 insertions, 0 deletions
diff --git a/.vim/lua/internal/lsp.lua b/.vim/lua/internal/lsp.lua new file mode 100644 index 0000000..669c2c7 --- /dev/null +++ b/.vim/lua/internal/lsp.lua @@ -0,0 +1,299 @@ +local lsp = require('lspconfig') +local lspstatus = require('lsp-status') + +local my_attach = function(client, bufnr) + if vim.opt.diff:get() then + vim.notify('not running LSP client in diff mode', vim.log.levels.WARN) + vim.lsp.stop_client() + return + end + + local group = vim.api.nvim_create_augroup('LspOnAttach', {}) + vim.api.nvim_create_autocmd('CursorHold', { + buffer = bufnr, + group = group, + callback = function() + if not _G.diagnostic_hidden then + vim.diagnostic.open_float(nil, { + focusable = false, + close_events = {'BufLeave', 'CursorMoved', 'InsertEnter', 'FocusLost'}, + border = _G.floating_win_border, + source = 'always', + prefix = ' ', + scope = 'cursor', + }) + end + end, + }) + + lspstatus.on_attach(client) + if client.supports_method('textDocument/documentSymbol') then + require('nvim-navic').attach(client, bufnr) + -- require('aerial').on_attach(client, bufnr) + -- vim.keymap.set('n', 'g0', vim.lsp.buf.document_symbol, {buffer = bufnr}) + end + if client.supports_method('workspace/symbol') then + vim.keymap.set('n', 'gW' , vim.lsp.buf.workspace_symbol, {buffer = bufnr, desc = 'goto symbol'}) + vim.keymap.set('n', ';s' , require('telescope.builtin').lsp_workspace_symbols, {desc='lsp workspace symbols'}) + end + if client.supports_method('textDocument/definition') then + vim.keymap.set('n', '<C-]>' , vim.lsp.buf.definition, {buffer = bufnr, desc = 'goto definition'}) + vim.keymap.set('n', 'gd' , vim.lsp.buf.definition, {buffer = bufnr, desc = 'goto definition'}) + vim.keymap.set('n', 'gR' , vim.lsp.buf.references, {buffer = bufnr, desc = 'goto references'}) + vim.keymap.set('n', ';R' , require('telescope.builtin').lsp_references, {desc='lsp references'}) + end + if client.supports_method('textDocument/hover') then + vim.keymap.set('n', 'K' , vim.lsp.buf.hover, {buffer = bufnr, desc = 'hover'}) + end + if client.supports_method('textDocument/rename') then + vim.keymap.set('n', 'grr' , vim.lsp.buf.rename, {buffer = bufnr, desc = 'rename'}) + end + if client.supports_method('signatureHelp') then + vim.keymap.set('n', '<c-h>' , vim.lsp.buf.signature_help, {buffer = bufnr, desc = 'signature help'}) + end + if client.supports_method('textDocument/formatting') then + vim.api.nvim_buf_set_option(bufnr, 'formatexpr', 'v:lua.vim.lsp.formatexpr()') + vim.keymap.set('n', '<leader>f' , vim.lsp.buf.format, {buffer = bufnr, desc = 'format'}) + vim.api.nvim_create_autocmd('BufWritePre', { + buffer = bufnr, + group = group, + callback = function() require('internal.lsp').format(vim.fn.expand('<afile>:p')) end, + }) + end + if client.supports_method('textDocument/typeDefinition') then + vim.keymap.set('n', 'gT' , vim.lsp.buf.type_definition, {buffer = bufnr, desc = 'goto typedef'}) + end + if client.supports_method('textDocument/declaration') then + vim.keymap.set('n', 'gD' , vim.lsp.buf.declaration, {buffer = bufnr, desc = 'goto declaration'}) + end + if client.supports_method('textDocument/implementation') then + vim.keymap.set('n', 'gI' , vim.lsp.buf.implementation, {buffer = bufnr, desc = 'goto implementation'}) + end + if client.supports_method('textDocument/codeAction') then + vim.keymap.set('n', 'ga', vim.lsp.buf.code_action, {buffer = bufnr, desc = 'code action'}) + end + + if client.supports_method('textDocument/documentHighlight') then + vim.keymap.set('n', '<leader>8', vim.lsp.buf.document_highlight, {buffer = bufnr, desc = 'document highlight'}) + -- vim.keymap.set('n', '', vim.lsp.buf.clear_references, {buffer = bufnr, desc = 'clear references'}) + vim.api.nvim_create_autocmd('CursorMoved', { + callback = vim.lsp.buf.clear_references, + buffer = bufnr, + }) + end +end + +local my_exit = function(_, _, _) +end + +local capabilities = function() + local caps = vim.lsp.protocol.make_client_capabilities() + -- enable lsp-based snippets + caps.textDocument.completion.completionItem.snippetSupport = true + caps.textDocument.completion.completionItem.resolveSupport = { + properties = { + 'documentation', + 'detail', + 'additionalTextEdits', + } + } + -- add window/workDoneProgress capability + caps = vim.tbl_extend('keep', caps or {}, lspstatus.capabilities) + return caps +end + +local servers = { + ccls = { disabled = true, + root_dir = lsp.util.root_pattern('.ccls','meson.build','.git'), + init_options = { + compilationDatabaseDirectory = "build", + index = { threads = 0 }, + completion = { + filterAndSort = false, + }, + clang = { excludeArgs = { '-frounding-math' } }, + }, + }, + clangd = { + root_dir = lsp.util.root_pattern('.ccls','meson.build','.git'), + }, + elixirls = { + cmd = { 'elixir-ls' }, + settings = { + elixirLS = { + dialyzerEnabled = false, + } + } + }, + gopls = { + settings = { + gopls = { + analyses = { + -- composites = false, + fieldalignment = true, + nilness = true, + shadow = false, + unusedparams = true, + unusedwrite = true, + }, + gofumpt = true, + -- hoverKind = 'Structured', + } + } + }, + sumneko_lua = { + cmd = { 'lua-language-server' }, + settings = { + Lua = { + runtime = { + version = 'LuaJIT', + path = vim.split(package.path, ';'), + }, + diagnostics = { + globals = { + '_G', + 'assert', + 'error', + 'os', + 'package', + 'pairs', 'ipairs', + 'pcall', + 'require', + 'string', + 'table', + 'type', + 'vim', + }, + neededFileStatus = { + ['code-style-check'] = 'Any', + } + }, + format = { + enable = true, + defaultConfig = { + indent_style = 'space', + indent_size = '2', + } + }, + workspace = { + -- library = vim.api.nvim_get_runtime_file("", true), + library = { + [vim.env.VIMRUNTIME .. '/lua'] = true, + [vim.env.VIMRUNTIME .. '/lua/vim/lsp'] = true, + [vim.fn.stdpath('config') .. '/lua'] = true, + } + }, + telemetry = { + enable = false, + }, + }, + }, + }, + rust_analyzer = { + cmd = { 'env', 'CARGO_TARGET_DIR=/tmp', 'RUST_SRC_PATH=/usr/src/rustlib/library', 'rust-analyzer' }, + settings = { + ['rust-analyzer'] = { + checkOnSave = { + command = 'clippy' + } + } + }, + }, + tsserver = { disabled = true, + cmd = { + 'toolbox', 'run', '--', + 'sh', '-c', + '. /etc/profile.d/nvm.sh && typescript-language-server --stdio' + }, + }, + zls = { disabled = true, + }, + zk = { disabled = true, + root_dir = lsp.util.root_pattern('.zk'), + }, +} + +local setup = function() + -- configure floating win handlers + vim.lsp.handlers['textDocument/hover'] = vim.lsp.with( + vim.lsp.handlers.hover, { border = _G.floating_win_border }) + vim.lsp.handlers['textDocument/signature_help'] = vim.lsp.with( + vim.lsp.handlers.signature_help, { border = _G.floating_win_border }) + + local caps = capabilities() + for server, opts in pairs(servers) do + if not opts.disabled then + opts = vim.tbl_extend('error', opts, { + on_attach = my_attach, + on_exit = my_exit, + capabilities = caps, + }) + -- lsp-status custom handlers + local ok, lspstatus_ext = pcall(lspstatus.extensions[server]) + if ok then + opts = vim.tbl_extend('error', opts, { + handlers = lspstatus_ext.setup(), + }) + end + lsp[server].setup(opts) + end + end +end + +local format = function(afile) + if vim.g.nofmt then return end + if not string.match(afile, '^/home/robert/devel/upstream') then + vim.lsp.buf.format() + if string.match(afile, '.go$') then + vim.lsp.buf.code_action({ only = {'source.organizeImports'} }) + end + -- vim.notify('%#MoreMsg#%#Italic# fmt') + vim.notify('%#MoreMsg#%#Italic# fmt') + end +end + +local symbols = { + -- + Array = ' ', + Boolean = ' ', + Class = ' ', + Color = ' ', + Constant = ' ', + Constructor = ' ', + Enum = ' ', + EnumMember = ' ', + Event = ' ', + -- Field = ' ', + Field = ' ', + File = ' ', + Folder = ' ', + Function = ' ', + Interface = ' ', + Key = ' ', + Keyword = ' ', + Method = ' ', + Module = ' ', + Namespace = ' ', + Null = ' ', + Object = ' ', + Operator = ' ', + Property = ' ', + Package = ' ', + Reference = ' ', + Snippet = ' ', + Struct = ' ', + Text = ' ', + TypeParameter = ' ', + Unit = ' ', + Value = ' ', + Variable = ' ', +} + +return { + my_attach = my_attach, + my_exit = my_exit, + capabilities = capabilities, + setup = setup, + format = format, + symbols = symbols, +} |