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