You can use the following examples.
Show configNote Note, that mapping TAB may interfere with your snippet-engine.
local has_words_before = function() unpack = unpack or table.unpack 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 feedkey = function(key, mode) vim.api.nvim_feedkeys(vim.api.nvim_replace_termcodes(key, true, true, true), mode, true) end local cmp = require('cmp') cmp.setup { -- ... Your other configuration ... mapping = { -- ... Your other mappings ... ["<Tab>"] = cmp.mapping(function(fallback) if cmp.visible() then cmp.select_next_item() elseif vim.fn["vsnip#available"](1) == 1 then feedkey("<Plug>(vsnip-expand-or-jump)", "") elseif has_words_before() then cmp.complete() else fallback() -- The fallback function sends a already mapped key. In this case, it's probably `<Tab>`. end end, { "i", "s" }), ["<S-Tab>"] = cmp.mapping(function() if cmp.visible() then cmp.select_prev_item() elseif vim.fn["vsnip#jumpable"](-1) == 1 then feedkey("<Plug>(vsnip-jump-prev)", "") end end, { "i", "s" }), -- ... Your other mappings ... } -- ... Your other configuration ... }Show config
local luasnip = require("luasnip") local cmp = require("cmp") cmp.setup({ -- ... Your other configuration ... mapping = { -- ... Your other mappings ... ['<CR>'] = cmp.mapping(function(fallback) if cmp.visible() then if luasnip.expandable() then luasnip.expand() else cmp.confirm({ select = true, }) end else fallback() end end), ["<Tab>"] = cmp.mapping(function(fallback) if cmp.visible() then cmp.select_next_item() elseif luasnip.locally_jumpable(1) then luasnip.jump(1) else fallback() end end, { "i", "s" }), ["<S-Tab>"] = 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" }), -- ... Your other mappings ... }, -- ... Your other configuration ... })Show config
local has_words_before = function() unpack = unpack or table.unpack 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 snippy = require("snippy") local cmp = require("cmp") cmp.setup({ -- ... Your other configuration ... mapping = { -- ... Your other mappings ... ["<Tab>"] = cmp.mapping(function(fallback) if cmp.visible() then cmp.select_next_item() elseif snippy.can_expand_or_advance() then snippy.expand_or_advance() elseif has_words_before() then cmp.complete() else fallback() end end, { "i", "s" }), ["<S-Tab>"] = cmp.mapping(function(fallback) if cmp.visible() then cmp.select_prev_item() elseif snippy.can_jump(-1) then snippy.previous() else fallback() end end, { "i", "s" }), -- ... Your other mappings ... }, -- ... Your other configuration ... })
i_(S-)Tab
when completion menu is visible insert next/prev entry, else jump to next/prev snippet tagc_(S-)Tab
when completion menu is visible insert next/prev entry, else starts completioni_CR
when completion menu is visible select completion or expand snippet, else <CR>
c_CR
when completion menu is visible select completion only, don't accept line, else <CR>
(accept line)i_CTRL_n/p
when completion menu is visible, select next/prev completion item, else <C-n>
/<C-p>
c_CTRL_n/p
when completion menu is visible, select next/prev completion item, else filter history (<Up>
, <Down>
)-- within packer init {{{ use {'SirVer/ultisnips', requires = {{'honza/vim-snippets', rtp = '.'}}, config = function() vim.g.UltiSnipsExpandTrigger = '<Plug>(ultisnips_expand)' vim.g.UltiSnipsJumpForwardTrigger = '<Plug>(ultisnips_jump_forward)' vim.g.UltiSnipsJumpBackwardTrigger = '<Plug>(ultisnips_jump_backward)' vim.g.UltiSnipsListSnippets = '<c-x><c-s>' vim.g.UltiSnipsRemoveSelectModeMappings = 0 end } -- }}} local t = function(str) return vim.api.nvim_replace_termcodes(str, true, true, true) end local cmp = require('cmp') cmp.setup { snippet = { expand = function(args) vim.fn["UltiSnips#Anon"](args.body) end }, -- ... Your other configuration ... mapping = { ["<Tab>"] = cmp.mapping({ c = function() if cmp.visible() then cmp.select_next_item({ behavior = cmp.SelectBehavior.Insert }) else cmp.complete() end end, i = function(fallback) if cmp.visible() then cmp.select_next_item({ behavior = cmp.SelectBehavior.Insert }) elseif vim.fn["UltiSnips#CanJumpForwards"]() == 1 then vim.api.nvim_feedkeys(t("<Plug>(ultisnips_jump_forward)"), 'm', true) else fallback() end end, s = function(fallback) if vim.fn["UltiSnips#CanJumpForwards"]() == 1 then vim.api.nvim_feedkeys(t("<Plug>(ultisnips_jump_forward)"), 'm', true) else fallback() end end }), ["<S-Tab>"] = cmp.mapping({ c = function() if cmp.visible() then cmp.select_prev_item({ behavior = cmp.SelectBehavior.Insert }) else cmp.complete() end end, i = function(fallback) if cmp.visible() then cmp.select_prev_item({ behavior = cmp.SelectBehavior.Insert }) elseif vim.fn["UltiSnips#CanJumpBackwards"]() == 1 then return vim.api.nvim_feedkeys( t("<Plug>(ultisnips_jump_backward)"), 'm', true) else fallback() end end, s = function(fallback) if vim.fn["UltiSnips#CanJumpBackwards"]() == 1 then return vim.api.nvim_feedkeys( t("<Plug>(ultisnips_jump_backward)"), 'm', true) else fallback() end end }), ['<Down>'] = cmp.mapping(cmp.mapping.select_next_item({ behavior = cmp.SelectBehavior.Select }), {'i'}), ['<Up>'] = cmp.mapping(cmp.mapping.select_prev_item({ behavior = cmp.SelectBehavior.Select }), {'i'}), ['<C-n>'] = cmp.mapping({ c = function() if cmp.visible() then cmp.select_next_item({ behavior = cmp.SelectBehavior.Select }) else vim.api.nvim_feedkeys(t('<Down>'), 'n', true) end end, i = function(fallback) if cmp.visible() then cmp.select_next_item({ behavior = cmp.SelectBehavior.Select }) else fallback() end end }), ['<C-p>'] = cmp.mapping({ c = function() if cmp.visible() then cmp.select_prev_item({ behavior = cmp.SelectBehavior.Select }) else vim.api.nvim_feedkeys(t('<Up>'), 'n', true) end end, i = function(fallback) if cmp.visible() then cmp.select_prev_item({ behavior = cmp.SelectBehavior.Select }) else fallback() end end }), ['<C-b>'] = cmp.mapping(cmp.mapping.scroll_docs(-4), {'i', 'c'}), ['<C-f>'] = cmp.mapping(cmp.mapping.scroll_docs(4), {'i', 'c'}), ['<C-Space>'] = cmp.mapping(cmp.mapping.complete(), {'i', 'c'}), ['<C-e>'] = cmp.mapping({ i = cmp.mapping.close(), c = cmp.mapping.close() }), ['<CR>'] = cmp.mapping({ i = cmp.mapping.confirm({ behavior = cmp.ConfirmBehavior.Replace, select = false }), c = function(fallback) if cmp.visible() then cmp.confirm({ behavior = cmp.ConfirmBehavior.Replace, select = false }) else fallback() end end }), -- ... Your other configuration ... }, -- ... Your other configuration ... } -- Use buffer source for `/`. cmp.setup.cmdline('/', { completion = { autocomplete = false }, sources = { -- { name = 'buffer' } { name = 'buffer', opts = { keyword_pattern = [=[[^[:blank:]].*]=] } } } }) -- Use cmdline & path source for ':'. cmp.setup.cmdline(':', { completion = { autocomplete = false }, sources = cmp.config.sources({ { name = 'path' } }, { { name = 'cmdline' } }) })
Snippets don't expand with <Tab>
in this config. Use <C-Space>
.
local has_words_before = function() unpack = unpack or table.unpack 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 cmp = require('cmp') cmp.setup { -- ... Your other configuration ... mapping = { -- ... Your other configuration ... ['<C-Space>'] = cmp.mapping.confirm { behavior = cmp.ConfirmBehavior.Insert, select = true, }, ['<Tab>'] = function(fallback) if not cmp.select_next_item() then if vim.bo.buftype ~= 'prompt' and has_words_before() then cmp.complete() else fallback() end end end, ['<S-Tab>'] = function(fallback) if not cmp.select_prev_item() then if vim.bo.buftype ~= 'prompt' and has_words_before() then cmp.complete() else fallback() end end end, }, snippet = { -- We recommend using *actual* snippet engine. -- It's a simple implementation so it might not work in some of the cases. expand = function(args) unpack = unpack or table.unpack local line_num, col = unpack(vim.api.nvim_win_get_cursor(0)) local line_text = vim.api.nvim_buf_get_lines(0, line_num - 1, line_num, true)[1] local indent = string.match(line_text, '^%s*') local replace = vim.split(args.body, '\n', true) local surround = string.match(line_text, '%S.*') or '' local surround_end = surround:sub(col) replace[1] = surround:sub(0, col - 1)..replace[1] replace[#replace] = replace[#replace]..(#surround_end > 1 and ' ' or '')..surround_end if indent ~= '' then for i, line in ipairs(replace) do replace[i] = indent..line end end vim.api.nvim_buf_set_lines(0, line_num - 1, line_num, true, replace) end, }, -- ... Your other configuration ... }
local cmp = require("cmp") cmp.setup({ mapping = { ... ["<Tab>"] = cmp.mapping(function(fallback) -- This little snippet will confirm with tab, and if no entry is selected, will confirm the first item if cmp.visible() then local entry = cmp.get_selected_entry() if not entry then cmp.select_next_item({ behavior = cmp.SelectBehavior.Select }) end cmp.confirm() else fallback() end end, {"i","s","c",}), ... } })Safely select entries with
<CR>
local cmp = require("cmp") cmp.setup({ mapping = { ... ["<CR>"] = 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 = true }), }), ... } })Confirm candidate on TAB immediately when there's only one completion entry
Insert mappings:
Show configlocal has_words_before = function() unpack = unpack or table.unpack 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 -- ... rest of your mappings ['<Tab>'] = cmp.mapping(function(fallback) if cmp.visible() then if #cmp.get_entries() == 1 then cmp.confirm({ select = true }) else cmp.select_next_item() end --[[ Replace with your snippet engine (see above sections on this page) elseif snippy.can_expand_or_advance() then snippy.expand_or_advance() ]] elseif has_words_before() then cmp.complete() if #cmp.get_entries() == 1 then cmp.confirm({ select = true }) end else fallback() end end, { "i", "s" }), -- ... rest of your mappings
Cmdline mappings:
Show config-- ... rest of your mappings ['<Tab>'] = { c = function(_) if cmp.visible() then if #cmp.get_entries() == 1 then cmp.confirm({ select = true }) else cmp.select_next_item() end else cmp.complete() if #cmp.get_entries() == 1 then cmp.confirm({ select = true }) end end end, } -- ... rest of your mappings
If you're lazy loading nvim-cmp
with Lazy.nvim, remember to include the Cmdline event.
{ "hrsh7th/nvim-cmp", event = { "InsertEnter", "CmdlineEnter" }, -- Rest of your plugin spec },
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4