dotfiles

My personal shell configs and stuff
git clone git://git.alex.balgavy.eu/dotfiles.git
Log | Files | Refs | Submodules | README | LICENSE

lsp.lua (8626B)


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