lsp.lua (8375B)
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 "--no-deps", 117 "-D", "clippy::pedantic", 118 "-D", "clippy::nursery", 119 "-D", "clippy::restriction", 120 "-A", "clippy::blanket_clippy_restriction_lints", 121 "-A", "clippy::missing_docs_in_private_items", 122 "-A", "clippy::implicit_return", 123 "-A", "clippy::question_mark_used", 124 "-A", "clippy::min_ident_chars", 125 "-A", "clippy::pattern_type_mismatch", 126 "-A", "clippy::single_call_fn", 127 "-A", "clippy::as_conversions", 128 "-A", "clippy::pub_with_shorthand", 129 "-A", "clippy::shadow_reuse", 130 "-A", "clippy::separated_literal_suffix", 131 "-A", "clippy::float_arithmetic", 132 "-A", "clippy::pub_use", 133 "-A", "clippy::single_char_lifetime_names", 134 "-A", "clippy::missing_trait_methods", 135 "-A", "clippy::mod_module_files", 136 "-A", "clippy::std_instead_of_alloc", 137 "-A", "clippy::integer_division_remainder_used", 138 "-D", "rust_2018_idioms", 139 "-D", "missing_docs", 140 "-D", "warnings", 141 "-A", "clippy::too_many_lines", 142 "-A", "clippy::arbitrary_source_item_ordering", 143 "-A", "clippy::redundant_test_prefix", 144 "-A", "clippy::cognitive_complexity", 145 }, 146 }, 147 }, 148 }, 149 }) 150 vim.lsp.enable("rust_analyzer") 151 152 vim.lsp.config("bacon_ls", { 153 on_attach = on_attach, 154 init_options = { 155 updateOnSave = true, 156 updateOnSaveWaitMillis = 3000, 157 updateOnChange = true, 158 }, 159 }) 160 --[[ 161 Some issues I found: 162 - bacon-ls kept running after vim closed 163 - diagnostics did not update, the old ones showed, I had to :e to refresh 164 --]] 165 -- vim.lsp.enable('bacon_ls') 166 167 vim.lsp.config("yamlls", { on_attach = on_attach }) 168 vim.lsp.enable("yamlls") 169 170 vim.lsp.config("nixd", { on_attach = on_attach }) 171 vim.lsp.enable("nixd", { 172 opts = { 173 root_markers = { "flake.nix", ".git", "darwin-configuration.nix" }, 174 }, 175 }) 176 177 vim.lsp.config("lua_ls", { 178 on_attach = on_attach, 179 settings = { 180 Lua = { 181 runtime = { 182 -- Tell the language server which version of Lua you're using 183 -- (most likely LuaJIT in the case of Neovim) 184 version = "LuaJIT", 185 }, 186 diagnostics = { 187 -- Get the language server to recognize the `vim` global 188 globals = { 189 "vim", 190 "require", 191 "hs", 192 "spoon", 193 }, 194 }, 195 workspace = { 196 -- Make the server aware of Neovim runtime files 197 library = vim.api.nvim_get_runtime_file("", true), 198 }, 199 -- Do not send telemetry data containing a randomized but unique identifier 200 telemetry = { 201 enable = false, 202 }, 203 }, 204 }, 205 }) 206 vim.lsp.enable("lua_ls") 207 208 vim.lsp.enable("basedpyright") 209 210 vim.lsp.config("vue_ls", { 211 -- add filetypes for typescript, javascript and vue 212 filetypes = { "typescript", "javascript", "javascriptreact", "typescriptreact", "vue" }, 213 }) 214 vim.lsp.enable("vue_ls") 215 216 vim.lsp.enable("terraformls") 217 218 vim.lsp.config("ruby_lsp", { 219 init_options = { 220 formatter = "standard", 221 linters = { "standard" }, 222 }, 223 }) 224 vim.lsp.enable("ruby_lsp") 225 226 vim.lsp.enable('ansiblels') 227 228 vim.lsp.enable('clangd') 229 end 230 231 return { 232 { 233 "neovim/nvim-lspconfig", 234 config = config, 235 }, 236 { 237 "mfussenegger/nvim-lint", 238 config = function() 239 local lint = require("lint") 240 lint.linters_by_ft = { 241 sh = { "shellcheck" }, 242 } 243 244 local lint_augroup = vim.api.nvim_create_augroup("lint", { clear = true }) 245 vim.api.nvim_create_autocmd({ "BufEnter", "BufWritePost", "InsertLeave" }, { 246 group = lint_augroup, 247 callback = function() 248 -- Only run the linter in buffers that you can modify in order to 249 -- avoid superfluous noise 250 if vim.bo.modifiable then 251 lint.try_lint() 252 end 253 end, 254 }) 255 end, 256 }, 257 }