diff --git a/home.nix b/home.nix index cb6d190c..0e3b628a 100644 --- a/home.nix +++ b/home.nix @@ -14,7 +14,7 @@ let ./home/gtk.nix ./home/i3status-rust.nix ./home/lf.nix - ./home/neovim.nix + ./home/neovim ./home/nushell.nix ./home/picom.nix ./home/redshift.nix diff --git a/home/neovim.nix b/home/neovim/default.nix similarity index 99% rename from home/neovim.nix rename to home/neovim/default.nix index 8d129525..1da4b18c 100644 --- a/home/neovim.nix +++ b/home/neovim/default.nix @@ -599,6 +599,8 @@ in vim-numbertoggle { plugin = mason-nvim; # Automatically install LSP servers + config = builtins.readFile ./lsp.lua; + type = "lua"; } { plugin = mason-lspconfig-nvim; # Automatically install LSP servers diff --git a/home/neovim/lsp.lua b/home/neovim/lsp.lua new file mode 100644 index 00000000..049a1f9d --- /dev/null +++ b/home/neovim/lsp.lua @@ -0,0 +1,87 @@ +-- [[ Configure LSP ]] +-- This function gets run when an LSP connects to a particular buffer. +local on_attach = function(_, bufnr) + local nmap = function(keys, func, desc) + if desc then + desc = 'LSP: ' .. desc + end + + vim.keymap.set('n', keys, func, { buffer = bufnr, desc = desc }) + end + + nmap('rn', vim.lsp.buf.rename, '[R]e[n]ame') + nmap('ca', vim.lsp.buf.code_action, '[C]ode [A]ction') + + nmap('gd', require('telescope.builtin').lsp_definitions, '[G]oto [D]efinition') + nmap('gD', vim.lsp.buf.declaration, '[G]oto [D]eclaration') + nmap('gr', require('telescope.builtin').lsp_references, '[G]oto [R]eferences') + nmap('gI', require('telescope.builtin').lsp_implementations, '[G]oto [I]mplementation') + nmap('t', require('telescope.builtin').lsp_type_definitions, 'Type [D]efinition') + nmap('ds', require('telescope.builtin').lsp_document_symbols, '[D]ocument [S]ymbols') + nmap('ws', require('telescope.builtin').lsp_dynamic_workspace_symbols, '[W]orkspace [S]ymbols') + + nmap('K', vim.lsp.buf.hover, 'Hover Documentation') + nmap('', vim.lsp.buf.signature_help, 'Signature Documentation') + + -- Workspace Fu + nmap('wa', vim.lsp.buf.add_workspace_folder, '[W]orkspace [A]dd Folder') + nmap('wr', vim.lsp.buf.remove_workspace_folder, '[W]orkspace [R]emove Folder') + nmap('wl', function() + print(vim.inspect(vim.lsp.buf.list_workspace_folders())) + end, '[W]orkspace [L]ist Folders') + + -- Create a command `:Format` local to the LSP buffer + vim.api.nvim_buf_create_user_command(bufnr, 'Format', function(_) + vim.lsp.buf.format() + end, { desc = 'Format current buffer with LSP' }) +end + +-- Document workspace keymap +require('which-key').register { + ['w'] = { name = '[W]orkspace', _ = 'which_key_ignore' }, +} + +-- mason-lspconfig requires that these setup functions are called in this order +-- before setting up the servers. +require('mason').setup() +require('mason-lspconfig').setup() + +local servers = { + -- clangd = {}, + -- gopls = {}, + -- pyright = {}, + -- rust_analyzer = {}, + -- tsserver = {}, + -- html = { filetypes = { 'html', 'twig', 'hbs'} }, + + lua_ls = { + Lua = { + workspace = { checkThirdParty = false }, + telemetry = { enable = false }, + diagnostics = { disable = { 'missing-fields' } }, + }, + }, +} + +-- Setup neovim lua configuration +require('neodev').setup() + +-- nvim-cmp supports additional completion capabilities, so broadcast that to servers +local capabilities = vim.lsp.protocol.make_client_capabilities() +capabilities = require('cmp_nvim_lsp').default_capabilities(capabilities) + +-- Ensure the servers above are installed +local mason_lspconfig = require 'mason-lspconfig' +mason_lspconfig.setup { + ensure_installed = vim.tbl_keys(servers), +} +mason_lspconfig.setup_handlers { + function(server_name) + require('lspconfig')[server_name].setup { + capabilities = capabilities, + on_attach = on_attach, + settings = servers[server_name], + filetypes = (servers[server_name] or {}).filetypes, + } + end, +}