|
| 1 | +return { -- LSP Configuration & Plugins |
| 2 | + 'neovim/nvim-lspconfig', |
| 3 | + dependencies = { |
| 4 | + -- Automatically install LSPs and related tools to stdpath for Neovim |
| 5 | + 'williamboman/mason.nvim', |
| 6 | + 'williamboman/mason-lspconfig.nvim', |
| 7 | + 'WhoIsSethDaniel/mason-tool-installer.nvim', |
| 8 | + |
| 9 | + -- Useful status updates for LSP. |
| 10 | + -- NOTE: `opts = {}` is the same as calling `require('fidget').setup({})` |
| 11 | + { 'j-hui/fidget.nvim', opts = {} }, |
| 12 | + |
| 13 | + -- `neodev` configures Lua LSP for your Neovim config, runtime and plugins |
| 14 | + -- used for completion, annotations and signatures of Neovim apis |
| 15 | + { 'folke/neodev.nvim', opts = {} }, |
| 16 | + }, |
| 17 | + config = function() |
| 18 | + -- Brief aside: **What is LSP?** |
| 19 | + -- |
| 20 | + -- LSP is an initialism you've probably heard, but might not understand what it is. |
| 21 | + -- |
| 22 | + -- LSP stands for Language Server Protocol. It's a protocol that helps editors |
| 23 | + -- and language tooling communicate in a standardized fashion. |
| 24 | + -- |
| 25 | + -- In general, you have a "server" which is some tool built to understand a particular |
| 26 | + -- language (such as `gopls`, `lua_ls`, `rust_analyzer`, etc.). These Language Servers |
| 27 | + -- (sometimes called LSP servers, but that's kind of like ATM Machine) are standalone |
| 28 | + -- processes that communicate with some "client" - in this case, Neovim! |
| 29 | + -- |
| 30 | + -- LSP provides Neovim with features like: |
| 31 | + -- - Go to definition |
| 32 | + -- - Find references |
| 33 | + -- - Autocompletion |
| 34 | + -- - Symbol Search |
| 35 | + -- - and more! |
| 36 | + -- |
| 37 | + -- Thus, Language Servers are external tools that must be installed separately from |
| 38 | + -- Neovim. This is where `mason` and related plugins come into play. |
| 39 | + -- |
| 40 | + -- If you're wondering about lsp vs treesitter, you can check out the wonderfully |
| 41 | + -- and elegantly composed help section, `:help lsp-vs-treesitter` |
| 42 | + |
| 43 | + -- This function gets run when an LSP attaches to a particular buffer. |
| 44 | + -- That is to say, every time a new file is opened that is associated with |
| 45 | + -- an lsp (for example, opening `main.rs` is associated with `rust_analyzer`) this |
| 46 | + -- function will be executed to configure the current buffer |
| 47 | + vim.api.nvim_create_autocmd('LspAttach', { |
| 48 | + group = vim.api.nvim_create_augroup('kickstart-lsp-attach', { clear = true }), |
| 49 | + callback = function(event) |
| 50 | + -- NOTE: Remember that Lua is a real programming language, and as such it is possible |
| 51 | + -- to define small helper and utility functions so you don't have to repeat yourself. |
| 52 | + -- |
| 53 | + -- In this case, we create a function that lets us more easily define mappings specific |
| 54 | + -- for LSP related items. It sets the mode, buffer and description for us each time. |
| 55 | + local map = function(keys, func, desc) |
| 56 | + vim.keymap.set('n', keys, func, { buffer = event.buf, desc = 'LSP: ' .. desc }) |
| 57 | + end |
| 58 | + |
| 59 | + -- Jump to the definition of the word under your cursor. |
| 60 | + -- This is where a variable was first declared, or where a function is defined, etc. |
| 61 | + -- To jump back, press <C-t>. |
| 62 | + map('<leader>gd', require('telescope.builtin').lsp_definitions, '[G]oto [D]efinition') |
| 63 | + |
| 64 | + -- Find references for the word under your cursor. |
| 65 | + map('<leader>gr', require('telescope.builtin').lsp_references, '[G]oto [R]eferences') |
| 66 | + |
| 67 | + -- Jump to the implementation of the word under your cursor. |
| 68 | + -- Useful when your language has ways of declaring types without an actual implementation. |
| 69 | + map('<leader>gI', require('telescope.builtin').lsp_implementations, '[G]oto [I]mplementation') |
| 70 | + |
| 71 | + -- Jump to the type of the word under your cursor. |
| 72 | + -- Useful when you're not sure what type a variable is and you want to see |
| 73 | + -- the definition of its *type*, not where it was *defined*. |
| 74 | + map('<leader>D', require('telescope.builtin').lsp_type_definitions, 'Type [D]efinition') |
| 75 | + |
| 76 | + -- Fuzzy find all the symbols in your current document. |
| 77 | + -- Symbols are things like variables, functions, types, etc. |
| 78 | + map('<leader>ds', require('telescope.builtin').lsp_document_symbols, '[D]ocument [S]ymbols') |
| 79 | + |
| 80 | + -- Fuzzy find all the symbols in your current workspace. |
| 81 | + -- Similar to document symbols, except searches over your entire project. |
| 82 | + map('<leader>ws', require('telescope.builtin').lsp_dynamic_workspace_symbols, '[W]orkspace [S]ymbols') |
| 83 | + |
| 84 | + -- Rename the variable under your cursor. |
| 85 | + -- Most Language Servers support renaming across files, etc. |
| 86 | + map('<leader>rn', vim.lsp.buf.rename, '[R]e[n]ame') |
| 87 | + |
| 88 | + -- Execute a code action, usually your cursor needs to be on top of an error |
| 89 | + -- or a suggestion from your LSP for this to activate. |
| 90 | + map('<leader>ca', vim.lsp.buf.code_action, '[C]ode [A]ction') |
| 91 | + |
| 92 | + -- Opens a popup that displays documentation about the word under your cursor |
| 93 | + -- See `:help K` for why this keymap. |
| 94 | + map('K', vim.lsp.buf.hover, 'Hover Documentation') |
| 95 | + |
| 96 | + -- WARN: This is not Goto Definition, this is Goto Declaration. |
| 97 | + -- For example, in C this would take you to the header. |
| 98 | + map('gD', vim.lsp.buf.declaration, '[G]oto [D]eclaration') |
| 99 | + |
| 100 | + -- The following two autocommands are used to highlight references of the |
| 101 | + -- word under your cursor when your cursor rests there for a little while. |
| 102 | + -- See `:help CursorHold` for information about when this is executed |
| 103 | + -- |
| 104 | + -- When you move your cursor, the highlights will be cleared (the second autocommand). |
| 105 | + local client = vim.lsp.get_client_by_id(event.data.client_id) |
| 106 | + if client and client.server_capabilities.documentHighlightProvider then |
| 107 | + vim.api.nvim_create_autocmd({ 'CursorHold', 'CursorHoldI' }, { |
| 108 | + buffer = event.buf, |
| 109 | + callback = vim.lsp.buf.document_highlight, |
| 110 | + }) |
| 111 | + |
| 112 | + vim.api.nvim_create_autocmd({ 'CursorMoved', 'CursorMovedI' }, { |
| 113 | + buffer = event.buf, |
| 114 | + callback = vim.lsp.buf.clear_references, |
| 115 | + }) |
| 116 | + end |
| 117 | + end, |
| 118 | + }) |
| 119 | + |
| 120 | + -- LSP servers and clients are able to communicate to each other what features they support. |
| 121 | + -- By default, Neovim doesn't support everything that is in the LSP specification. |
| 122 | + -- When you add nvim-cmp, luasnip, etc. Neovim now has *more* capabilities. |
| 123 | + -- So, we create new capabilities with nvim cmp, and then broadcast that to the servers. |
| 124 | + local capabilities = vim.lsp.protocol.make_client_capabilities() |
| 125 | + capabilities = vim.tbl_deep_extend('force', capabilities, require('cmp_nvim_lsp').default_capabilities()) |
| 126 | + |
| 127 | + -- Enable the following language servers |
| 128 | + -- Feel free to add/remove any LSPs that you want here. They will automatically be installed. |
| 129 | + -- |
| 130 | + -- Add any additional override configuration in the following tables. Available keys are: |
| 131 | + -- - cmd (table): Override the default command used to start the server |
| 132 | + -- - filetypes (table): Override the default list of associated filetypes for the server |
| 133 | + -- - capabilities (table): Override fields in capabilities. Can be used to disable certain LSP features. |
| 134 | + -- - settings (table): Override the default settings passed when initializing the server. |
| 135 | + -- For example, to see the options for `lua_ls`, you could go to: https://luals.github.io/wiki/settings/ |
| 136 | + local servers = { |
| 137 | + -- clangd = {}, |
| 138 | + -- gopls = {}, |
| 139 | + -- pyright = {}, |
| 140 | + -- rust_analyzer = {}, |
| 141 | + -- ... etc. See `:help lspconfig-all` for a list of all the pre-configured LSPs |
| 142 | + -- |
| 143 | + -- Some languages (like typescript) have entire language plugins that can be useful: |
| 144 | + -- https://github.com/pmizio/typescript-tools.nvim |
| 145 | + -- |
| 146 | + -- But for many setups, the LSP (`tsserver`) will work just fine |
| 147 | + -- tsserver = {}, |
| 148 | + -- |
| 149 | + |
| 150 | + lua_ls = { |
| 151 | + -- cmd = {...}, |
| 152 | + -- filetypes = { ...}, |
| 153 | + -- capabilities = {}, |
| 154 | + settings = { |
| 155 | + Lua = { |
| 156 | + completion = { |
| 157 | + callSnippet = 'Replace', |
| 158 | + }, |
| 159 | + -- You can toggle below to ignore Lua_LS's noisy `missing-fields` warnings |
| 160 | + -- diagnostics = { disable = { 'missing-fields' } }, |
| 161 | + }, |
| 162 | + }, |
| 163 | + }, |
| 164 | + } |
| 165 | + |
| 166 | + -- Ensure the servers and tools above are installed |
| 167 | + -- To check the current status of installed tools and/or manually install |
| 168 | + -- other tools, you can run |
| 169 | + -- :Mason |
| 170 | + -- |
| 171 | + -- You can press `g?` for help in this menu. |
| 172 | + require('mason').setup() |
| 173 | + |
| 174 | + -- You can add other tools here that you want Mason to install |
| 175 | + -- for you, so that they are available from within Neovim. |
| 176 | + local ensure_installed = vim.tbl_keys(servers or {}) |
| 177 | + vim.list_extend(ensure_installed, { |
| 178 | + 'stylua', -- Used to format Lua code |
| 179 | + }) |
| 180 | + require('mason-tool-installer').setup { ensure_installed = ensure_installed } |
| 181 | + |
| 182 | + require('mason-lspconfig').setup { |
| 183 | + handlers = { |
| 184 | + function(server_name) |
| 185 | + local server = servers[server_name] or {} |
| 186 | + -- This handles overriding only values explicitly passed |
| 187 | + -- by the server configuration above. Useful when disabling |
| 188 | + -- certain features of an LSP (for example, turning off formatting for tsserver) |
| 189 | + server.capabilities = vim.tbl_deep_extend('force', {}, capabilities, server.capabilities or {}) |
| 190 | + require('lspconfig')[server_name].setup(server) |
| 191 | + end, |
| 192 | + }, |
| 193 | + } |
| 194 | + end, |
| 195 | +} |
0 commit comments