|
| 1 | +-- ╭─────────────────────────────────────────────────────────╮ |
| 2 | +-- │ CMP CONFIGURATION │ |
| 3 | +-- ╰─────────────────────────────────────────────────────────╯ |
| 4 | +return { |
| 5 | + 'hrsh7th/nvim-cmp', |
| 6 | + enabled = true, |
| 7 | + event = { 'InsertEnter', 'CmdlineEnter' }, |
| 8 | + dependencies = { |
| 9 | + 'hrsh7th/cmp-buffer', |
| 10 | + 'hrsh7th/cmp-cmdline', |
| 11 | + 'hrsh7th/cmp-nvim-lsp', |
| 12 | + 'hrsh7th/cmp-nvim-lsp-signature-help', |
| 13 | + 'hrsh7th/cmp-nvim-lua', |
| 14 | + 'hrsh7th/cmp-path', |
| 15 | + 'mfussenegger/nvim-jdtls', |
| 16 | + 'octaltree/cmp-look', |
| 17 | + 'L3MON4D3/cmp-luasnip-choice', |
| 18 | + 'chrisgrieser/cmp-nerdfont', |
| 19 | + 'MeanderingProgrammer/render-markdown.nvim', |
| 20 | + 'ray-x/cmp-treesitter', |
| 21 | + 'saadparwaiz1/cmp_luasnip', |
| 22 | + 'lukas-reineke/cmp-rg', |
| 23 | + 'prabirshrestha/vim-lsp', |
| 24 | + 'SergioRibera/cmp-dotenv', |
| 25 | + 'jcha0713/cmp-tw2css', |
| 26 | + 'dmitmel/cmp-vim-lsp', |
| 27 | + 'roginfarrer/cmp-css-variables', |
| 28 | + 'PhilippFeO/cmp-help-tags', |
| 29 | + |
| 30 | + 'JMarkin/cmp-diag-codes', |
| 31 | + |
| 32 | + -- 'chrisgrieser/cmp_yanky', |
| 33 | + }, |
| 34 | + config = function() |
| 35 | + -- ╭───────────────╮ |
| 36 | + -- │ LOAD SNIPPETS │ |
| 37 | + -- ╰───────────────╯ |
| 38 | + require('luasnip/loaders/from_lua').lazy_load() |
| 39 | + require('luasnip.loaders.from_snipmate').lazy_load() |
| 40 | + require('luasnip/loaders/from_vscode').lazy_load() |
| 41 | + |
| 42 | + -- ╭────────────────╮ |
| 43 | + -- │ COMPLETEOPTION │ |
| 44 | + -- ╰────────────────╯ |
| 45 | + vim.opt.completeopt = { 'menu', 'menuone', 'noselect', 'preview' } |
| 46 | + |
| 47 | + -- ╭────────────╮ |
| 48 | + -- │ KIND ICONS │ |
| 49 | + -- ╰────────────╯ |
| 50 | + local kind_icons = { |
| 51 | + Class = ' ', |
| 52 | + Color = ' ', |
| 53 | + Comment = '//', |
| 54 | + Constant = ' ', |
| 55 | + Constructor = ' ', |
| 56 | + Enum = ' ', |
| 57 | + EnumMember = ' ', |
| 58 | + Event = '', |
| 59 | + Field = ' ', |
| 60 | + File = ' ', |
| 61 | + Folder = ' ', |
| 62 | + Function = 'ƒ ', |
| 63 | + Interface = ' ', |
| 64 | + Keyword = ' ', |
| 65 | + Method = ' ', |
| 66 | + Module = ' ', |
| 67 | + Operator = ' ', |
| 68 | + Property = ' ', |
| 69 | + Reference = ' ', |
| 70 | + Snippet = ' ', |
| 71 | + String = ' ', |
| 72 | + Struct = ' ', |
| 73 | + Text = ' ', |
| 74 | + TypeParameter = ' ', |
| 75 | + Unit = ' ', |
| 76 | + Value = ' ', |
| 77 | + Variable = '', |
| 78 | + } |
| 79 | + |
| 80 | + -- ╭──────────────╮ |
| 81 | + -- │ LOAD LUASNIP │ |
| 82 | + -- ╰──────────────╯ |
| 83 | + local luasnip = require('luasnip') |
| 84 | + |
| 85 | + -- ╭──────────╮ |
| 86 | + -- │ LOAD CMP │ |
| 87 | + -- ╰──────────╯ |
| 88 | + local cmp = require('cmp') |
| 89 | + |
| 90 | + -- ╭───────────╮ |
| 91 | + -- │ CMP SETUP │ |
| 92 | + -- ╰───────────╯ |
| 93 | + cmp.setup({ |
| 94 | + snippet = { |
| 95 | + expand = function(args) |
| 96 | + require('luasnip').lsp_expand(args.body) |
| 97 | + end, |
| 98 | + }, |
| 99 | + window = { |
| 100 | + completion = { |
| 101 | + border = { '┌', '─', '┐', '│', '┘', '─', '└', '│' }, |
| 102 | + winhighlight = 'Normal:CmpPmenu,FloatBorder:FloatBorder,CursorLine:PmenuSel,Search:None', |
| 103 | + }, |
| 104 | + documentation = { |
| 105 | + border = { '┌', '─', '┐', '│', '┘', '─', '└', '│' }, |
| 106 | + winhighlight = 'Normal:CmpPmenu,FloatBorder:FloatBorder,CursorLine:PmenuSel,Search:None', |
| 107 | + }, |
| 108 | + }, |
| 109 | + view = { |
| 110 | + entries = { |
| 111 | + name = 'custom', |
| 112 | + selection_order = 'near_cursor', |
| 113 | + follow_cursor = true, |
| 114 | + }, |
| 115 | + }, |
| 116 | + mapping = cmp.mapping.preset.insert({ |
| 117 | + -- ['<C-n>'] = cmp.mapping(cmp.mapping.select_next_item(), { 'i', 'c' }), |
| 118 | + -- ['<C-p>'] = cmp.mapping(cmp.mapping.select_prev_item(), { 'i', 'c' }), |
| 119 | + -- ['<C-b>'] = cmp.mapping(cmp.mapping.scroll_docs(-4), { 'i', 'c' }), |
| 120 | + -- ['<C-f>'] = cmp.mapping(cmp.mapping.scroll_docs(4), { 'i', 'c' }), |
| 121 | + -- ['<C-Space>'] = cmp.mapping(cmp.mapping.complete(), { 'i', 'c' }), |
| 122 | + ['<C-n>'] = cmp.mapping.select_next_item({ behavior = cmp.SelectBehavior.Insert }), |
| 123 | + ['<C-p>'] = cmp.mapping.select_prev_item({ behavior = cmp.SelectBehavior.Insert }), |
| 124 | + ['<C-u>'] = cmp.mapping.scroll_docs(-4), |
| 125 | + ['<C-d>'] = cmp.mapping.scroll_docs(4), |
| 126 | + ['<C-Space>'] = cmp.mapping.complete(), |
| 127 | + ['<C-y>'] = cmp.config.disable, -- Specify `cmp.config.disable` if you want to remove the default `<C-y>` mapping. |
| 128 | + ['<C-e>'] = cmp.mapping({ |
| 129 | + i = cmp.mapping.abort(), |
| 130 | + c = cmp.mapping.close(), |
| 131 | + }), |
| 132 | + ['<CR>'] = cmp.mapping.confirm({ |
| 133 | + behavior = cmp.ConfirmBehavior.Insert, |
| 134 | + select = true, |
| 135 | + }), -- Accept currently selected item. Set `select` to `false` to only confirm explicitly selected items. |
| 136 | + -- ['<CR>'] = cmp.mapping(function(fallback) |
| 137 | + -- if cmp.visible() then |
| 138 | + -- if luasnip.expandable() then |
| 139 | + -- luasnip.expand() |
| 140 | + -- else |
| 141 | + -- cmp.confirm({ |
| 142 | + -- select = true, |
| 143 | + -- }) |
| 144 | + -- end |
| 145 | + -- else |
| 146 | + -- fallback() |
| 147 | + -- end |
| 148 | + -- end), |
| 149 | + ['<C-CR>'] = cmp.mapping.confirm({ |
| 150 | + behavior = cmp.ConfirmBehavior.Replace, |
| 151 | + select = true, |
| 152 | + }), |
| 153 | + ['<Tab>'] = cmp.mapping(function(fallback) |
| 154 | + if cmp.visible() then |
| 155 | + cmp.select_next_item() |
| 156 | + elseif luasnip.locally_jumpable(1) then |
| 157 | + luasnip.jump(1) |
| 158 | + else |
| 159 | + fallback() |
| 160 | + end |
| 161 | + end, { 'i', 's' }), |
| 162 | + ['<S-Tab>'] = cmp.mapping(function(fallback) |
| 163 | + if cmp.visible() then |
| 164 | + cmp.select_prev_item() |
| 165 | + elseif luasnip.locally_jumpable(-1) then |
| 166 | + luasnip.jump(-1) |
| 167 | + else |
| 168 | + fallback() |
| 169 | + end |
| 170 | + end, { 'i', 's' }), |
| 171 | + }), |
| 172 | + sources = cmp.config.sources({ |
| 173 | + { name = 'nvim_lsp' }, |
| 174 | + { name = 'nvim_lsp_signature_help' }, |
| 175 | + { name = 'luasnip' }, |
| 176 | + { name = 'luasnip_choice' }, |
| 177 | + { name = 'render-markdown' }, |
| 178 | + { name = 'buffer' }, |
| 179 | + { name = 'path' }, |
| 180 | + { name = 'nvim_lua' }, |
| 181 | + { name = 'treesitter' }, |
| 182 | + { name = 'vim_lsp' }, |
| 183 | + { name = 'dotenv' }, |
| 184 | + { name = 'diag-codes' }, |
| 185 | + { name = 'css-variables' }, |
| 186 | + { name = 'tw2css' }, |
| 187 | + { |
| 188 | + name = 'cmp_help_tags', -- '_' not '-' 😯 |
| 189 | + -- recommended to avoid cluttering |
| 190 | + keyword_length = 5, |
| 191 | + }, |
| 192 | + { |
| 193 | + name = 'look', |
| 194 | + keyword_length = 3, |
| 195 | + option = { |
| 196 | + convert_case = true, |
| 197 | + loud = true, |
| 198 | + }, |
| 199 | + max_item_count = 5, |
| 200 | + }, |
| 201 | + { |
| 202 | + name = 'rg', |
| 203 | + -- Try it when you feel cmp performance is poor |
| 204 | + -- keyword_length = 3 |
| 205 | + }, |
| 206 | + { name = 'nerdfont' }, |
| 207 | + }), |
| 208 | + formatting = { |
| 209 | + fields = { 'abbr', 'kind', 'menu' }, |
| 210 | + format = function(entry, vim_item) |
| 211 | + -- Kind icons |
| 212 | + -- This concatenates the icons with the name of the item kind |
| 213 | + vim_item.kind = string.format('%s %s', kind_icons[vim_item.kind], vim_item.kind) |
| 214 | + -- Trim text function |
| 215 | + function trim(text) |
| 216 | + local max = 40 |
| 217 | + if text and text:len(1, max) > max then |
| 218 | + text = text:sub(1, max) .. '...' |
| 219 | + end |
| 220 | + return text |
| 221 | + end |
| 222 | + vim_item.abbr = trim(vim_item.abbr) |
| 223 | + -- Source |
| 224 | + vim_item.menu = ({ |
| 225 | + nvim_lsp = '( LSP )', |
| 226 | + nvim_lsp_signature_help = '( Signature )', |
| 227 | + luasnip = '( LuaSnip )', |
| 228 | + buffer = '( Buffer )', |
| 229 | + path = '( Path )', |
| 230 | + nvim_lua = '( Lua )', |
| 231 | + treesitter = '( Treesitter )', |
| 232 | + look = '( Look )', |
| 233 | + cmdline = '( CMD )', |
| 234 | + })[entry.source.name] |
| 235 | + return vim_item |
| 236 | + end, |
| 237 | + }, |
| 238 | + sorting = { |
| 239 | + comparators = { |
| 240 | + cmp.config.compare.score, |
| 241 | + cmp.config.compare.offset, |
| 242 | + cmp.config.compare.exact, |
| 243 | + cmp.config.compare.recently_used, |
| 244 | + cmp.config.compare.length, |
| 245 | + cmp.config.compare.locality, |
| 246 | + cmp.config.compare.kind, |
| 247 | + cmp.config.compare.sort_text, |
| 248 | + cmp.config.compare.order, |
| 249 | + }, |
| 250 | + }, |
| 251 | + experimental = { |
| 252 | + ghost_text = true, |
| 253 | + }, |
| 254 | + }) |
| 255 | + |
| 256 | + -- ╭─────────────────────────╮ |
| 257 | + -- │ CMP CMDLINE FOR / AND ?│ |
| 258 | + -- ╰─────────────────────────╯ |
| 259 | + cmp.setup.cmdline({ '/', '?' }, { |
| 260 | + mapping = cmp.mapping.preset.cmdline(), |
| 261 | + sources = { |
| 262 | + { name = 'buffer' }, |
| 263 | + }, |
| 264 | + }) |
| 265 | + |
| 266 | + -- ╭───────────────────╮ |
| 267 | + -- │ CMP CMDLINE FOR : │ |
| 268 | + -- ╰───────────────────╯ |
| 269 | + cmp.setup.cmdline(':', { |
| 270 | + mapping = cmp.mapping.preset.cmdline(), |
| 271 | + sources = cmp.config.sources({ |
| 272 | + { name = 'path', group_index = 1 }, |
| 273 | + { name = 'cmdline', group_index = 2 }, |
| 274 | + }), |
| 275 | + matching = { disallow_symbol_nonprefix_matching = false }, |
| 276 | + }) |
| 277 | + |
| 278 | + -- ╭────────────────╮ |
| 279 | + -- │ NVIM-AUTOPAIRS │ |
| 280 | + -- ╰────────────────╯ |
| 281 | + local cmp_autopairs = require('nvim-autopairs.completion.cmp') |
| 282 | + local ts_utils = require('nvim-treesitter.ts_utils') |
| 283 | + |
| 284 | + local ts_node_func_parens_disabled = { |
| 285 | + -- ecma |
| 286 | + named_imports = true, |
| 287 | + -- rust |
| 288 | + use_declaration = true, |
| 289 | + } |
| 290 | + |
| 291 | + local default_handler = cmp_autopairs.filetypes['*']['('].handler |
| 292 | + cmp_autopairs.filetypes['*']['('].handler = function(char, item, bufnr, rules, commit_character) |
| 293 | + local node_type = ts_utils.get_node_at_cursor():type() |
| 294 | + if ts_node_func_parens_disabled[node_type] then |
| 295 | + if item.data then |
| 296 | + item.data.funcParensDisabled = true |
| 297 | + else |
| 298 | + char = '' |
| 299 | + end |
| 300 | + end |
| 301 | + default_handler(char, item, bufnr, rules, commit_character) |
| 302 | + end |
| 303 | + |
| 304 | + cmp.event:on('confirm_done', cmp_autopairs.on_confirm_done()) |
| 305 | + end, |
| 306 | +} |
0 commit comments