return { -- Mason for managing external tools (LSP servers, linters, etc.) { "williamboman/mason.nvim", version = "=1.0.1", config = function() require("mason").setup() end }, -- Mason LSP config to bridge Mason and nvim-lspconfig { "williamboman/mason-lspconfig.nvim", version = "=1.0.1", config = function() require("mason-lspconfig").setup { ensure_installed = {"pyright"}, automatic_installation = false, -- Set to true to automatically install servers } end }, -- nvim-lspconfig for configuring LSP servers { "neovim/nvim-lspconfig", config = function() local lspconfig = require("lspconfig") local capabilities = require('cmp_nvim_lsp').default_capabilities() -- Setup LSP server (Pyright for Python) lspconfig.pyright.setup { capabilities = capabilities, on_attach = function(client, bufnr) local buf_set_keymap = vim.api.nvim_buf_set_keymap local buf_set_option = vim.api.nvim_buf_set_option buf_set_option(bufnr, 'omnifunc', 'v:lua.vim.lsp.omnifunc') -- Key mappings for LSP local opts = { noremap = true, silent = true } buf_set_keymap(bufnr, 'n', 'gD', 'lua vim.lsp.buf.declaration()', opts) buf_set_keymap(bufnr, 'n', 'gd', 'lua vim.lsp.buf.definition()', opts) buf_set_keymap(bufnr, 'n', 'K', 'lua vim.lsp.buf.hover()', opts) buf_set_keymap(bufnr, 'n', 'gi', 'lua vim.lsp.buf.implementation()', opts) buf_set_keymap(bufnr, 'n', '', 'lua vim.lsp.buf.signature_help()', opts) buf_set_keymap(bufnr, 'n', 'wa', 'lua vim.lsp.buf.add_workspace_folder()', opts) buf_set_keymap(bufnr, 'n', 'wr', 'lua vim.lsp.buf.remove_workspace_folder()', opts) buf_set_keymap(bufnr, 'n', 'wl', 'lua print(vim.inspect(vim.lsp.buf.list_workspace_folders()))', opts) buf_set_keymap(bufnr, 'n', 'D', 'lua vim.lsp.buf.type_definition()', opts) buf_set_keymap(bufnr, 'n', 'rn', 'lua vim.lsp.buf.rename()', opts) buf_set_keymap(bufnr, 'n', 'gr', 'lua vim.lsp.buf.references()', opts) buf_set_keymap(bufnr, 'n', 'e', 'lua vim.lsp.diagnostic.show_line_diagnostics()', opts) buf_set_keymap(bufnr, 'n', '[d', 'lua vim.lsp.diagnostic.goto_prev()', opts) buf_set_keymap(bufnr, 'n', ']d', 'lua vim.lsp.diagnostic.goto_next()', opts) buf_set_keymap(bufnr, 'n', 'q', 'lua vim.lsp.diagnostic.set_loclist()', opts) buf_set_keymap(bufnr, 'n', 'so', [[lua require('telescope.builtin').lsp_document_symbols()]], opts) vim.cmd [[ command! Format execute 'lua vim.lsp.buf.formatting()' ]] -- Scroll hover documentation buf_set_keymap(bufnr, 'n', '', 'lua vim.lsp.util.scroll_popup(1)', opts) buf_set_keymap(bufnr, 'n', '', 'lua vim.lsp.util.scroll_popup(-1)', opts) end, } end }, -- nvim-cmp for autocompletion { "hrsh7th/nvim-cmp", dependencies = { "SirVer/ultisnips", "hrsh7th/cmp-nvim-lsp", "hrsh7th/cmp-buffer", "hrsh7th/cmp-path", "hrsh7th/cmp-cmdline", "quangnguyen30192/cmp-nvim-ultisnips", -- "nvim-treesitter/nvim-treesitter", -- Ensure this for better syntax highlighting "onsails/lspkind-nvim", "hrsh7th/cmp-nvim-lsp-signature-help", "R-nvim/cmp-r" }, config = function() local cmp = require'cmp' local lspkind = require('lspkind') cmp.setup({ snippet = { expand = function(args) vim.fn["UltiSnips#Anon"](args.body) end, }, mapping = { [''] = cmp.mapping.scroll_docs(-4), [''] = cmp.mapping.scroll_docs(4), [''] = cmp.mapping.complete(), [''] = cmp.mapping.abort(), [''] = cmp.mapping.confirm({ select = true }), [''] = cmp.mapping(function(fallback) if cmp.visible() then cmp.select_next_item() elseif vim.fn["UltiSnips#CanExpandSnippet"]() == 1 then vim.fn.feedkeys(vim.api.nvim_replace_termcodes("=UltiSnips#ExpandSnippet()", true, true, true), "") elseif vim.fn["UltiSnips#CanJumpForwards"]() == 1 then vim.fn.feedkeys(vim.api.nvim_replace_termcodes("=UltiSnips#JumpForwards()", true, true, true), "") else fallback() end end, { "i", "s" }), [''] = cmp.mapping(function(fallback) if cmp.visible() then cmp.select_prev_item() elseif vim.fn["UltiSnips#CanJumpBackwards"]() == 1 then vim.fn.feedkeys(vim.api.nvim_replace_termcodes("=UltiSnips#JumpBackwards()", true, true, true), "") else fallback() end end, { "i", "s" }), }, sources = cmp.config.sources({ { name = 'nvim_lsp' }, { name = 'nvim_lsp_signature_help' }, { name = 'ultisnips' }, { name = "cmp_r" } }, { { name = 'buffer' }, }), formatting = { format = lspkind.cmp_format({ with_text = true, maxwidth = 50 }) } }) -- -- -- Use buffer source for `/` and `?` (if you enabled `native_menu`, this won't work anymore). -- cmp.setup.cmdline('/', { -- sources = { -- { name = 'buffer' } -- } -- }) -- -- cmp.setup.cmdline('?', { -- sources = { -- { name = 'buffer' } -- } -- }) -- -- -- Use cmdline & path source for ':' (if you enabled `native_menu`, this won't work anymore). -- cmp.setup.cmdline(':', { -- sources = cmp.config.sources({ -- { name = 'path' } -- }, { -- { name = 'cmdline' } -- }) -- }) require("cmp_r").setup({ }) end } }