return { 'hrsh7th/nvim-cmp', dependencies = { -- Snippet Engine & its associated nvim-cmp source 'L3MON4D3/LuaSnip', { 'onsails/lspkind.nvim', config = function() require('lspkind').init({ mode = "symbol", preset = "default", symbol_map = { Text = "", Method = " ", Function = " ", Constructor = " ", Field = " ", Variable = " ", Class = "ﴯ ", Interface = " ", Module = " ", Property = "ﰠ ", Unit = " ", Value = " ", Enum = " ", Keyword = " ", -- Snippet = " ", Color = " ", File = " ", Reference = " ", Folder = " ", EnumMember = " ", Constant = " ", Struct = " ", Event = " ", Operator = " ", TypeParameter = " " }, }) end }, 'saadparwaiz1/cmp_luasnip', -- Adds LSP completion capabilities 'hrsh7th/cmp-nvim-lsp', -- Adds a number of user-friendly snippets 'rafamadriz/friendly-snippets', }, config = function() local cmp = require 'cmp' local winhighlight = "Normal:NormalFloat,FloatBorder:FloatBorder,CursorLine:PmenuSel" local luasnip = require 'luasnip' require('luasnip.loaders.from_vscode').lazy_load() luasnip.config.setup {} cmp.setup { snippet = { expand = function(args) luasnip.lsp_expand(args.body) end, }, preselect = cmp.PreselectMode.None, completion = { completeopt = "noselect,menuone,menu" }, sorting = { -- TODO: Would be cool to add stuff like "See variable names before method names" in rust, or something like that. comparators = { cmp.config.compare.offset, cmp.config.compare.exact, cmp.config.compare.score, -- copied from cmp-under, but I don't think I need the plugin for this. -- I might add some more of my own. function(entry1, entry2) local _, entry1_under = entry1.completion_item.label:find("^_+") local _, entry2_under = entry2.completion_item.label:find("^_+") entry1_under = entry1_under or 0 entry2_under = entry2_under or 0 if entry1_under > entry2_under then return false elseif entry1_under < entry2_under then return true end end, cmp.config.compare.kind, cmp.config.compare.sort_text, cmp.config.compare.length, cmp.config.compare.order, }, }, mapping = cmp.mapping.preset.insert { [''] = cmp.mapping.select_next_item(), [''] = cmp.mapping.select_prev_item(), [''] = cmp.mapping.scroll_docs(-4), [''] = cmp.mapping.scroll_docs(4), [''] = cmp.mapping.complete {}, [''] = cmp.mapping.confirm { behavior = cmp.ConfirmBehavior.Replace, select = true, }, [''] = cmp.mapping(function(fallback) if cmp.visible() then cmp.select_next_item() elseif luasnip.expand_or_locally_jumpable() then luasnip.expand_or_jump() else fallback() end end, { 'i', 's' }), [''] = cmp.mapping(function(fallback) if cmp.visible() then cmp.select_prev_item() elseif luasnip.locally_jumpable(-1) then luasnip.jump(-1) else fallback() end end, { 'i', 's' }), }, sources = { { name = 'nvim_lsp' }, { name = 'luasnip' }, { name = 'buffer' }, { name = 'path' }, }, formatting = { fields = { "menu", "abbr", "kind" }, format = function(entry, item) local menu_icon = { nvim_lsp = " ", luasnip = " ", buffer = 'Ω ', path = "", } item.menu = menu_icon[entry.source.name] item.kind = " " .. item.kind return item end, }, window = { completion = cmp.config.window.bordered({ winhighlight }), documentation = cmp.config.window.bordered({ winhighlight }), }, } local cmp_autopairs = require('nvim-autopairs.completion.cmp') cmp.event:on( 'confirm_done', cmp_autopairs.on_confirm_done() ) end, }