-- Language servers local ensure_installed = { 'clangd', -- C/C++ 'lua_ls', -- Lua 'opencl_ls', -- OpenCL } if vim.fn.executable('npm') == 1 then local ensure_install_from_npm = { 'ansiblels', -- Ansible 'bashls', -- Bash 'docker_compose_language_service', -- Docker Compose 'dockerls', -- Dockerfile 'html', -- HTML 'jsonls', -- JSON 'pyright', -- Python 'vimls', -- VimScript 'yamlls', -- YAML } for _, package in ipairs(ensure_install_from_npm) do table.insert(ensure_installed, package) end end if vim.fn.executable('pip') == 1 then local ensure_install_from_pip = { 'cmake', -- CMake 'esbonio', -- Sphinx 'ruff_lsp', -- Python } for _, package in ipairs(ensure_install_from_pip) do table.insert(ensure_installed, package) end end if vim.fn.has('win32') == 1 then table.insert(ensure_installed, 'powershell_es') end return { 'neovim/nvim-lspconfig', dependencies = { -- Language server management plugins -- 'williamboman/mason.nvim', 'kbenzie/mason.nvim', 'williamboman/mason-lspconfig.nvim', -- Completion sources plugins 'hrsh7th/cmp-nvim-lsp', -- Source for built-in language server client 'saadparwaiz1/cmp_luasnip', -- Source for LuaSnip snippets 'hrsh7th/cmp-buffer', -- Source for buffer words 'hrsh7th/cmp-path', -- Source for filesystem paths 'kbenzie/cmp-git', -- Source for Git/GitHub/GitLab 'hrsh7th/nvim-cmp', -- Completion engine combines and uses the above -- Lua vim module support in lua language server 'folke/neodev.nvim', -- Expose clangd extensions 'p00f/clangd_extensions.nvim', -- LSP UI plugins 'aznhe21/actions-preview.nvim', 'j-hui/fidget.nvim', 'nvim-tree/nvim-web-devicons', 'ray-x/lsp_signature.nvim', -- TODO: https://github.com/b0o/SchemaStore.nvim -- TODO: https://github.com/jmbuhr/otter.nvim -- TODO: https://github.com/nvimtools/none-ls.nvim -- TODO: https://github.com/mfussenegger/nvim-dap -- TODO: https://github.com/rcarriga/nvim-dap-ui }, config = function() require('mason').setup() require('mason-lspconfig').setup({ automatic_installation = false, ensure_installed = ensure_installed, handlers = { -- Default handler, sets up everything unless a custom language server -- setup handler is defined below function(server_name) require('lspconfig')[server_name].setup({}) end, ['lua_ls'] = function() require('neodev').setup() require('lspconfig').lua_ls.setup({ settings = { Lua = { diagnostics = { disable = { 'missing-fields', }, globals = { 'vim', }, } } } }) end, ['pyright'] = function() require('lspconfig').pyright.setup({ settings = { pyright = { disableOrganizeImports = true, -- Use ruff import sorter instead }, } }) end, }, }) local cmp = require('cmp') cmp.setup({ snippet = { expand = function(args) require('luasnip').lsp_expand(args.body) end }, mapping = cmp.mapping.preset.insert({ -- Open completion menu/confirm completion [''] = cmp.mapping.complete(), [''] = cmp.mapping.confirm({ select = true }), -- Select completion from menu [''] = cmp.mapping.select_next_item(), [''] = cmp.mapping.select_prev_item(), -- Scroll documentation of selected completion item [''] = cmp.mapping.scroll_docs(4), [''] = cmp.mapping.scroll_docs(-4), }), sources = { { name = 'nvim_lsp' }, { name = 'luasnip' }, { name = 'buffer' }, { name = 'path' }, { name = 'git' }, }, window = { completion = cmp.config.window.bordered(), documentation = cmp.config.window.bordered(), }, }) require("cmp_git").setup({}) -- Mappings created when LSP is attached to a buffer local augroup = vim.api.nvim_create_augroup('lsp', { clear = true }) vim.api.nvim_create_autocmd('LspAttach', { pattern = '*', group = augroup, callback = function(ev) local opts = { noremap = true, buffer = ev.buf } -- Fixit mapping, or close enough, actually any code action vim.keymap.set('n', 'fi', require('actions-preview').code_actions, opts) -- Goto mappings local tb = require('telescope.builtin') vim.keymap.set('n', 'gd', tb.lsp_definitions, opts) vim.keymap.set('n', 'gD', vim.lsp.buf.declaration, opts) vim.keymap.set('n', 'gi', tb.lsp_implementations, opts) vim.keymap.set('n', 'go', tb.lsp_type_definitions, opts) vim.keymap.set('n', 'gr', tb.lsp_references, opts) vim.keymap.set('n', 'ic', tb.lsp_incoming_calls, opts) vim.keymap.set('n', 'oc', tb.lsp_outgoing_calls, opts) vim.keymap.set('n', 'ss', tb.lsp_document_symbols, opts) vim.keymap.set('n', 'sw', tb.lsp_workspace_symbols, opts) -- Refactoring mappings vim.keymap.set('n', 'rn', vim.lsp.buf.rename, opts) -- Help mappings -- TODO: v0.10.0 |vim.lsp.start()| now maps |K| to use -- |vim.lsp.buf.hover()| if the server supports it, unless -- |'keywordprg'| was customized before calling |vim.lsp.start()|. vim.keymap.set('n', 'K', vim.lsp.buf.hover, opts) -- Format whole buffer mapping vim.keymap.set('n', 'gq', vim.lsp.buf.format, opts) end }) -- LSP UI plugins require('fidget').setup({}) require('lsp_signature').setup({ floating_window = true, hint_enable = false, toggle_key = '', toggle_key_flip_floatwin_setting = true, select_signature_key = '', }) end }