-- This function gets run when an LSP connects to a particular buffer. local on_attach = function(_, bufnr) -- NOTE: Remember that lua is a real programming language, and as such it is possible -- to define small helper and utility functions so you don't have to repeat yourself -- many times. -- -- In this case, we create a function that lets us more easily define mappings specific -- for LSP related items. It sets the mode, buffer and description for us each time. local nmap = function(keys, func, desc) if desc then desc = 'LSP: ' .. desc end vim.keymap.set('n', keys, func, { buffer = bufnr, desc = desc }) end nmap('rn', vim.lsp.buf.rename, '[R]e[n]ame') nmap('c', vim.lsp.buf.code_action, '[C]ode action') -- NOTE: to see if ca is needed nmap('f', function() -- https://stackoverflow.com/a/74303272 vim.lsp.buf.code_action({ filter = function(a) return a.isPreferred end, apply = true }) end, 'code action: [F]ix' ) nmap('gd', require('telescope.builtin').lsp_definitions, '[G]oto [D]efinition') nmap('gr', require('telescope.builtin').lsp_references, '[G]oto [R]eferences') nmap('gI', require('telescope.builtin').lsp_implementations, '[G]oto [I]mplementation') nmap('D', require('telescope.builtin').lsp_type_definitions, 'Type [D]efinition') nmap('ds', require('telescope.builtin').lsp_document_symbols, '[D]ocument [S]ymbols') nmap('ws', require('telescope.builtin').lsp_dynamic_workspace_symbols, '[W]orkspace [S]ymbols') -- See `:help K` for why this keymap nmap('K', vim.lsp.buf.hover, 'Hover Documentation') nmap('', vim.lsp.buf.signature_help, 'Signature Documentation') -- Lesser used LSP functionality nmap('gD', vim.lsp.buf.declaration, '[G]oto [D]eclaration') nmap('wa', vim.lsp.buf.add_workspace_folder, '[W]orkspace [A]dd Folder') nmap('wr', vim.lsp.buf.remove_workspace_folder, '[W]orkspace [R]emove Folder') nmap('wl', function() print(vim.inspect(vim.lsp.buf.list_workspace_folders())) end, '[W]orkspace [L]ist Folders') -- Create a command `:Format` local to the LSP buffer vim.api.nvim_buf_create_user_command(bufnr, 'Format', function(_) vim.lsp.buf.format() end, { desc = 'Format current buffer with LSP' }) end -- document existing key chains require('which-key').add { -- { "c", group = "[C]ode" }, -- { "c_", hidden = true }, { "d", group = "[D]ocument" }, { "d_", hidden = true }, { "g", group = "[G]it" }, { "g_", hidden = true }, { "h", group = "Git [H]unk" }, { "h_", hidden = true }, { "r", group = "[R]ename" }, { "r_", hidden = true }, { "s", group = "[S]earch" }, { "s_", hidden = true }, { "t", group = "[T]oggle" }, { "t_", hidden = true }, { "w", group = "[W]orkspace" }, { "w_", hidden = true }, } -- register which-key VISUAL mode -- required for visual hs (hunk stage) to work require('which-key').add { { "", group = "VISUAL ", mode = "v" }, { "h", desc = "Git [H]unk", mode = "v" }, } -- mason-lspconfig requires that these setup functions are called in this order -- before setting up the servers. require('mason').setup() require('mason-lspconfig').setup() -- Enable the following language servers -- Feel free to add/remove any LSPs that you want here. They will automatically be installed. -- -- Add any additional override configuration in the following tables. They will be passed to -- the `settings` field of the server config. You must look up that documentation yourself. -- -- If you want to override the default filetypes that your language server will attach to you can -- define the property 'filetypes' to the map in question. local servers = { clangd = {}, -- gopls = {}, pyright = {}, -- rust_analyzer = {}, ts_ls = {}, eslint = {}, -- html = { filetypes = { 'html', 'twig', 'hbs'} }, texlab = {}, ltex = { filetypes = { 'markdown', 'latex', 'norg', 'gitcommit', 'jj', 'rst', 'typst' }, ltex = { language = "auto", diagnosticSeverity = "information", sentenceCacheSize = 2000, additionalRules = { enablePickyRules = true, motherTongue = "fr", }, enabledRules = { en = { "EN_CONSISTENT_APOS" }, }, disabledRules = { fr = { "APOS_TYP", "FRENCH_WHITESPACE" }, en = { "DASH_RULE", "TWO_HYPHENS" }, }, dictionnary = { fr = { "CryptPad", }, en = { "CryptPad", }, } } }, lua_ls = { Lua = { workspace = { checkThirdParty = false }, telemetry = { enable = false }, -- NOTE: toggle below to ignore Lua_LS's noisy `missing-fields` warnings -- diagnostics = { disable = { 'missing-fields' } }, }, }, } -- Setup neovim lua configuration require('neodev').setup() -- nvim-cmp supports additional completion capabilities, so broadcast that to servers local capabilities = vim.lsp.protocol.make_client_capabilities() capabilities = require('cmp_nvim_lsp').default_capabilities(capabilities) -- Ensure the servers above are installed local mason_lspconfig = require 'mason-lspconfig' mason_lspconfig.setup { ensure_installed = vim.tbl_keys(servers), } mason_lspconfig.setup_handlers { function(server_name) require('lspconfig')[server_name].setup { capabilities = capabilities, on_attach = on_attach, settings = servers[server_name], filetypes = (servers[server_name] or {}).filetypes, } end, } -- [[ System LSPs ]] local lspconfig = require('lspconfig') servers = { rust_analyzer = { ["rust-analyzer"] = { imports = { granularity = { group = "module", }, prefix = "self", }, cargo = { buildScripts = { enable = true, }, }, procMacro = { enable = true }, } }, gdscript = {}, } for server_name, server_settings in pairs(servers) do lspconfig[server_name].setup { capabilities = capabilities, on_attach = on_attach, settings = server_settings, } end local setup_godot_dap = function() local dap = require("dap") dap.adapters.godot = { type = "server", host = "127.0.0.1", port = 6006, } dap.configurations.gdscript = { { launch_game_instance = false, launch_scene = false, name = "Launch scene", project = "${workspaceFolder}", request = "launch", type = "godot", }, } end setup_godot_dap()