diff --git a/lua/plugins/cmp.lua b/lua/plugins/cmp.lua new file mode 100644 index 0000000..3451564 --- /dev/null +++ b/lua/plugins/cmp.lua @@ -0,0 +1,143 @@ +-- I've set up a comprehensive completion system using nvim-cmp with the following features: +-- +-- 1. Main Completion Sources: +-- - LSP completions (cmp-nvim-lsp) +-- - Snippets (LuaSnip + friendly-snippets) +-- - Buffer words (cmp-buffer) +-- - File paths (cmp-path) +-- - Command line completions (cmp-cmdline) +-- +-- 2. Key Mappings: +-- - `/` - Navigate through completion items +-- - `/` - Scroll documentation +-- - `` - Trigger completion +-- - `` - Close completion window +-- - `` - Confirm selection +-- - `` - Confirm with replacement +-- - `/` - Navigate completion items or snippets +-- +-- 3. Features: +-- - Ghost text preview +-- - Icons for different completion types +-- - Source indicators ([LSP], [Buffer], etc.) +-- - Command-line completion for / ? : +-- - Snippet support with friendly-snippets included +-- +-- The configuration is optimized for performance by: +-- - Loading on InsertEnter +-- - Using the latest versions of plugins +-- - Proper lazy loading of snippets + +return { + { + "hrsh7th/nvim-cmp", + version = false, -- last release is way too old + event = "InsertEnter", + dependencies = { + "hrsh7th/cmp-nvim-lsp", -- LSP source for nvim-cmp + "hrsh7th/cmp-buffer", -- Buffer completions + "hrsh7th/cmp-path", -- Path completions + "hrsh7th/cmp-cmdline", -- Cmdline completions + "saadparwaiz1/cmp_luasnip", -- Snippet completions + { + "L3MON4D3/LuaSnip", + version = "v2.*", + build = "make install_jsregexp", + dependencies = { + "rafamadriz/friendly-snippets", -- Preconfigured snippets + }, + }, + }, + config = function() + local cmp = require("cmp") + local luasnip = require("luasnip") + + -- Load friendly-snippets + require("luasnip.loaders.from_vscode").lazy_load() + + cmp.setup({ + snippet = { + expand = function(args) + luasnip.lsp_expand(args.body) + end, + }, + completion = { + completeopt = "menu,menuone,noinsert", + }, + mapping = cmp.mapping.preset.insert({ + [""] = cmp.mapping.select_next_item({ behavior = cmp.SelectBehavior.Insert }), + [""] = cmp.mapping.select_prev_item({ behavior = cmp.SelectBehavior.Insert }), + [""] = cmp.mapping.scroll_docs(-4), + [""] = cmp.mapping.scroll_docs(4), + [""] = cmp.mapping.complete(), + [""] = cmp.mapping.abort(), + [""] = cmp.mapping.confirm({ select = true }), -- Accept currently selected item. Set `select` to `false` to only confirm explicitly selected items. + [""] = cmp.mapping.confirm({ + behavior = cmp.ConfirmBehavior.Replace, + select = true, + }), -- Accept currently selected item. Set `select` to `false` to only confirm explicitly selected items. + [""] = cmp.mapping(function(fallback) + if cmp.visible() then + cmp.select_next_item() + elseif luasnip.expand_or_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.jumpable(-1) then + luasnip.jump(-1) + else + fallback() + end + end, { "i", "s" }), + }), + sources = cmp.config.sources({ + { name = "nvim_lsp" }, + { name = "luasnip" }, + { name = "buffer" }, + { name = "path" }, + }), + formatting = { + format = function(entry, vim_item) + -- Kind icons + vim_item.kind = string.format('%s %s', require("user.icons").kinds[vim_item.kind], vim_item.kind) + -- Source + vim_item.menu = ({ + buffer = "[Buffer]", + nvim_lsp = "[LSP]", + luasnip = "[Snippet]", + path = "[Path]", + })[entry.source.name] + return vim_item + end + }, + experimental = { + ghost_text = true, + }, + }) + + -- Use buffer source for `/` and `?` (if you enabled `native_menu`, this won't work anymore). + cmp.setup.cmdline({ '/', '?' }, { + mapping = cmp.mapping.preset.cmdline(), + sources = { + { name = 'buffer' } + } + }) + + -- Use cmdline & path source for ':' (if you enabled `native_menu`, this won't work anymore). + cmp.setup.cmdline(':', { + mapping = cmp.mapping.preset.cmdline(), + sources = cmp.config.sources({ + { name = 'path' } + }, { + { name = 'cmdline' } + }) + }) + end, + }, +} + diff --git a/lua/user/icons.lua b/lua/user/icons.lua new file mode 100644 index 0000000..845f914 --- /dev/null +++ b/lua/user/icons.lua @@ -0,0 +1,30 @@ +return { + kinds = { + 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 = "", + }, +} +