return { -- completion setup { "hrsh7th/nvim-cmp", branch = "main", version = false, dependencies = { "andersevenrud/cmp-tmux", "cbarrete/completion-vcard", "f3fora/cmp-spell", "hrsh7th/cmp-nvim-lsp", "hrsh7th/cmp-path", "hrsh7th/cmp-buffer", "hrsh7th/cmp-calc", "hrsh7th/cmp-cmdline", "hrsh7th/cmp-nvim-lua", "hrsh7th/cmp-nvim-lsp-signature-help", "dmitmel/cmp-digraphs", "jc-doyle/cmp-pandoc-references", "kdheepak/cmp-latex-symbols", "lukas-reineke/cmp-rg", "crispgm/cmp-beancount", { "ray-x/cmp-treesitter", dependencies = { "nvim-treesitter/nvim-treesitter" } }, { "saadparwaiz1/cmp_luasnip", dependencies = { { "L3MON4D3/LuaSnip", dependencies = { "rafamadriz/friendly-snippets", { "benfowler/telescope-luasnip.nvim", dependencies = { { "nvim-telescope/telescope.nvim", optional = true } }, config = function() require("telescope").load_extension("luasnip") end, }, }, build = "make install_jsregexp", config = function() require("luasnip.loaders.from_vscode").lazy_load({ exclude = { "markdown", "quarto" } }) require("luasnip.loaders.from_snipmate").lazy_load() end, }, }, }, }, config = function() local luasnip = require("luasnip") local cmp = require("cmp") local has_words_before = function() ---@diagnostic disable-next-line:deprecated local line, col = unpack(vim.api.nvim_win_get_cursor(0)) return col ~= 0 and vim.api.nvim_buf_get_lines(0, line - 1, line, true)[1]:sub(col, col):match("%s") == nil end local kind_icons = { Text = "", Method = "", Function = "󰊕", Constructor = "", Field = "", Variable = "", Class = "", Interface = "", Module = "", Property = "", Unit = "", Value = "V", Enum = "", Keyword = "", Snippet = "", Color = "", File = "", Reference = "", Folder = "", EnumMember = "", Constant = "", Struct = "", Event = "", Operator = "", TypeParameter = "", } cmp.setup({ window = { documentation = cmp.config.window.bordered() }, snippet = { expand = function(args) require("luasnip").lsp_expand(args.body) end, }, sources = { { name = "nvim_lua" }, { name = "beancount", option = { account = vim.env["HOME"] .. "/documents/records/budget/main.beancount", -- TODO implement dynamically }, }, { name = "otter" }, { name = "nvim_lsp" }, { name = "nvim_lsp_signature_help" }, { name = "luasnip", keyword_length = 1 }, { name = "pandoc_references" }, { name = "calc" }, { name = "path" }, { name = "buffer", keyword_length = 3 }, { name = "latex_symbols" }, { name = "spell", keyword_length = 3 }, { name = "tmux" }, -- { name = 'rg', keyword_length = 5 }, { name = "vCard" }, { name = "digraphs", keyword_length = 2 }, }, mapping = cmp.mapping.preset.insert({ [""] = cmp.mapping.scroll_docs(-4), [""] = cmp.mapping.scroll_docs(4), [""] = cmp.mapping({ i = function(fallback) if cmp.visible() and cmp.get_active_entry() then cmp.confirm({ behavior = cmp.ConfirmBehavior.Replace, select = false, }) else fallback() end end, s = cmp.mapping.confirm({ select = true }), c = cmp.mapping.confirm({ behavior = cmp.ConfirmBehavior.Replace, select = false, }), -- disable selection in cmd mode }), [""] = cmp.mapping(function(fallback) if cmp.visible() then cmp.select_next_item() -- You could replace the expand_or_jumpable() calls with expand_or_locally_jumpable() -- they way you will only jump inside the snippet region elseif luasnip.expand_or_jumpable() then luasnip.expand_or_jump() elseif has_words_before() then cmp.complete() else fallback() end end, { "i", "s" }), [""] = cmp.mapping(function(fallback) if cmp.visible() then cmp.select_prev_item() elseif luasnip.jumpable(-1) then luasnip.jump(-1) else fallback() end end, { "i", "s" }), }), formatting = { fields = { "kind", "abbr", "menu" }, format = function(entry, vim_item) -- Kind icons, removing kind text leaving only icon -- vim_item.kind = string.format('%s %s', kind_icons[vim_item.kind], vim_item.kind) vim_item.kind = string.format("%s", kind_icons[vim_item.kind]) -- Source vim_item.menu = ({ buffer = "", calc = "󰃬", digraphs = "∬", latex_symbols = "𝓧", luasnip = "", nvim_lsp = "ℒ", nvim_lua = "󰢱", pandoc_references = "", spell = "󰓆", vCard = "󰛋", })[entry.source.name] return vim_item end, }, }) -- `/` cmdline setup. cmp.setup.cmdline("/", { mapping = cmp.mapping.preset.cmdline(), sources = { { name = "buffer" } }, }) -- `:` cmdline setup. cmp.setup.cmdline(":", { mapping = cmp.mapping.preset.cmdline(), sources = cmp.config.sources({ { name = "path" } }, { { name = "cmdline", option = { ignore_cmds = { "Man", "!" } } }, }), }) end, event = { "InsertEnter", "CmdlineEnter" }, }, }