lsp.lua (8092B)
1 -- LSP settings. 2 -- This function gets run when an LSP connects to a particular buffer. 3 local on_attach = function(_, bufnr) 4 -- Enable inlay hints for current buffer 5 vim.lsp.inlay_hint.enable(true, { bufnr = bufnr }) 6 7 -- NOTE: Remember that lua is a real programming language, and as such it is possible 8 -- to define small helper and utility functions so you don't have to repeat yourself 9 -- many times. 10 -- 11 -- In this case, we create a function that lets us more easily define mappings specific 12 -- for LSP related items. It sets the mode, buffer and description for us each time. 13 local nmap = function(keys, func, desc) 14 if desc then 15 desc = 'LSP: ' .. desc 16 end 17 18 vim.keymap.set('n', keys, func, { buffer = bufnr, desc = desc }) 19 end 20 21 nmap('<leader>rn', vim.lsp.buf.rename, '[R]e[n]ame') 22 nmap('<leader>ra', vim.lsp.buf.code_action, '[C]ode [A]ction') 23 vim.keymap.set('v', '<leader>ra', vim.lsp.buf.code_action, { buffer = bufnr, desc = '[C]ode [A]ction' }) 24 25 nmap('gd', vim.lsp.buf.definition, '[G]oto [D]efinition') 26 nmap('gI', vim.lsp.buf.implementation, '[G]oto [I]mplementation') 27 nmap('<leader>D', vim.lsp.buf.type_definition, 'Type [D]efinition') 28 29 -- See `:help K` for why this keymap 30 nmap('K', vim.lsp.buf.hover, 'Hover Documentation') 31 nmap('<leader>K', vim.lsp.buf.signature_help, 'Signature Documentation') 32 33 -- Lesser used LSP functionality 34 nmap('gD', vim.lsp.buf.declaration, '[G]oto [D]eclaration') 35 nmap('<leader>wa', vim.lsp.buf.add_workspace_folder, '[W]orkspace [A]dd Folder') 36 nmap('<leader>wr', vim.lsp.buf.remove_workspace_folder, '[W]orkspace [R]emove Folder') 37 nmap('<leader>wl', function() 38 print(vim.inspect(vim.lsp.buf.list_workspace_folders())) 39 end, '[W]orkspace [L]ist Folders') 40 41 -- Create a command `:Format` local to the LSP buffer 42 vim.api.nvim_buf_create_user_command(bufnr, 'Format', function(_) 43 vim.lsp.buf.format() 44 end, { desc = 'Format current buffer with LSP' }) 45 46 vim.api.nvim_buf_create_user_command(bufnr, 'LspInspect', function(_) 47 vim.ui.input({ prompt = 'Enter LSP Client name: ' }, function(client_name) 48 if client_name then 49 local client = vim.lsp.get_clients { name = client_name } 50 51 if #client == 0 then 52 vim.notify('No active LSP clients found with this name: ' .. client_name, vim.log.levels.WARN) 53 return 54 end 55 56 -- Create a temporary buffer to show the configuration 57 local buf = vim.api.nvim_create_buf(false, true) 58 local win = vim.api.nvim_open_win(buf, true, { 59 relative = 'editor', 60 width = math.floor(vim.o.columns * 0.75), 61 height = math.floor(vim.o.lines * 0.90), 62 col = math.floor(vim.o.columns * 0.125), 63 row = math.floor(vim.o.lines * 0.05), 64 style = 'minimal', 65 border = 'rounded', 66 title = ' ' .. (client_name:gsub('^%l', string.upper)) .. ': LSP Configuration ', 67 title_pos = 'center', 68 }) 69 70 local lines = {} 71 for i, this_client in ipairs(client) do 72 if i > 1 then 73 table.insert(lines, string.rep('-', 80)) 74 end 75 table.insert(lines, 'Client: ' .. this_client.name) 76 table.insert(lines, 'ID: ' .. this_client.id) 77 table.insert(lines, '') 78 table.insert(lines, 'Configuration:') 79 80 local config_lines = vim.split(vim.inspect(this_client.config), '\n') 81 vim.list_extend(lines, config_lines) 82 end 83 84 -- Set the lines in the buffer 85 vim.api.nvim_buf_set_lines(buf, 0, -1, false, lines) 86 87 -- Set buffer options 88 vim.bo[buf].modifiable = false 89 vim.bo[buf].filetype = 'lua' 90 vim.bo[buf].bh = 'delete' 91 92 vim.api.nvim_buf_set_keymap(buf, 'n', 'q', ':q<CR>', { noremap = true, silent = true }) 93 end 94 end) 95 end, { desc = 'Inspect LSP config' }) 96 end 97 98 -- :h lspconfig-all 99 local config = function() 100 vim.lsp.config('rust_analyzer', { 101 on_attach = on_attach, 102 settings = { 103 ['rust-analyzer'] = { 104 workspace = { 105 symbol = { 106 search = { 107 kind = "all_symbols", 108 }, 109 }, 110 }, 111 check = { 112 command = "clippy", 113 features = "all", 114 extraArgs = { 115 "--", 116 "-D", "clippy::pedantic", 117 "-D", "clippy::nursery", 118 "-D", "clippy::restriction", 119 "-A", "clippy::blanket_clippy_restriction_lints", 120 "-A", "clippy::missing_docs_in_private_items", 121 "-A", "clippy::implicit_return", 122 "-A", "clippy::question_mark_used", 123 "-A", "clippy::min_ident_chars", 124 "-A", "clippy::pattern_type_mismatch", 125 "-A", "clippy::single_call_fn", 126 "-A", "clippy::as_conversions", 127 "-A", "clippy::pub_with_shorthand", 128 "-A", "clippy::shadow_reuse", 129 "-A", "clippy::separated_literal_suffix", 130 "-A", "clippy::float_arithmetic", 131 "-A", "clippy::pub_use", 132 "-A", "clippy::single_char_lifetime_names", 133 "-A", "clippy::missing_trait_methods", 134 "-A", "clippy::mod_module_files", 135 "-A", "clippy::std_instead_of_alloc", 136 "-A", "clippy::integer_division_remainder_used", 137 "-D", "rust_2018_idioms", 138 "-D", "missing_docs", 139 "-D", "warnings", 140 "-A", "clippy::too_many_lines", 141 "-A", "clippy::arbitrary_source_item_ordering", 142 "-A", "clippy::redundant_test_prefix", 143 }, 144 } 145 } 146 }, 147 }) 148 vim.lsp.enable('rust_analyzer') 149 150 vim.lsp.config('bacon_ls', { 151 on_attach = on_attach, 152 init_options = { 153 updateOnSave = true, 154 updateOnSaveWaitMillis = 3000, 155 updateOnChange = true, 156 }, 157 }) 158 --[[ 159 Some issues I found: 160 - bacon-ls kept running after vim closed 161 - diagnostics did not update, the old ones showed, I had to :e to refresh 162 --]] 163 -- vim.lsp.enable('bacon_ls') 164 165 vim.lsp.config('yamlls', { on_attach = on_attach }) 166 vim.lsp.enable('yamlls') 167 168 vim.lsp.config('nixd', { on_attach = on_attach }) 169 vim.lsp.enable('nixd') 170 171 vim.lsp.config('lua_ls', { 172 on_attach = on_attach, 173 settings = { 174 Lua = { 175 runtime = { 176 -- Tell the language server which version of Lua you're using 177 -- (most likely LuaJIT in the case of Neovim) 178 version = 'LuaJIT', 179 }, 180 diagnostics = { 181 -- Get the language server to recognize the `vim` global 182 globals = { 183 'vim', 184 'require' 185 }, 186 }, 187 workspace = { 188 -- Make the server aware of Neovim runtime files 189 library = vim.api.nvim_get_runtime_file("", true), 190 }, 191 -- Do not send telemetry data containing a randomized but unique identifier 192 telemetry = { 193 enable = false, 194 }, 195 } 196 } 197 }) 198 vim.lsp.enable('lua_ls') 199 200 vim.lsp.enable('basedpyright') 201 202 vim.lsp.config('vue_ls', { 203 -- add filetypes for typescript, javascript and vue 204 filetypes = { 'typescript', 'javascript', 'javascriptreact', 'typescriptreact', 'vue' }, 205 }) 206 vim.lsp.enable('vue_ls') 207 208 vim.lsp.enable('terraformls') 209 210 vim.lsp.config('ruby_lsp', { 211 init_options = { 212 formatter = 'standard', 213 linters = { 'standard' }, 214 }, 215 }) 216 vim.lsp.enable('ruby_lsp') 217 end 218 219 return { 220 { 221 'neovim/nvim-lspconfig', 222 config = config, 223 }, 224 { 225 'mfussenegger/nvim-lint', 226 config = function() 227 local lint = require('lint') 228 lint.linters_by_ft = { 229 sh = { 'shellcheck' }, 230 } 231 232 local lint_augroup = vim.api.nvim_create_augroup('lint', { clear = true }) 233 vim.api.nvim_create_autocmd({ 'BufEnter', 'BufWritePost', 'InsertLeave' }, { 234 group = lint_augroup, 235 callback = function() 236 -- Only run the linter in buffers that you can modify in order to 237 -- avoid superfluous noise 238 if vim.bo.modifiable then 239 lint.try_lint() 240 end 241 end, 242 }) 243 end 244 } 245 }