I only want to manually trigger completion, since I don't like having to hit <ENTER> twice (once to select the completion and another to execute) if I know what command I want. However, when I use <TAB> to do the completion, it just completes to the next word (which I believe is default vim behavior) and does not show a menu. I would expect that hitting <TAB> would pop the menu. When autocomplete is enabled, <TAB> works as expected. Thanks for your help!
# init.vim
call plug#begin(stdpath('data') . '/plugged')
Plug 'neovim/nvim-lspconfig'
Plug 'hrsh7th/cmp-nvim-lsp'
Plug 'hrsh7th/cmp-buffer'
Plug 'hrsh7th/cmp-path'
Plug 'hrsh7th/cmp-cmdline'
Plug 'hrsh7th/nvim-cmp'
Plug 'f3fora/cmp-spell'
Plug 'hrsh7th/cmp-calc'
Plug 'lukas-reineke/cmp-rg'
Plug 'hrsh7th/cmp-=nvim-lsp-signature-help'
" For luasnip users.
" Plug 'L3MON4D3/LuaSnip'
" Plug 'saadparwaiz1/cmp_luasnip'
call plug#end()
# cmp.lua
local has_words_before = function()
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 luasnip = require("luasnip")
local cmp = require("cmp")
local lspkind = require("lspkind")
local function snippetCompleteNext(fallback)
if cmp.visible() then
cmp.select_next_item()
elseif luasnip.expand_or_jumpable() then
luasnip.expand_or_jump()
elseif has_words_before() then
cmp.complete()
cmp.close()
else
fallback()
end
end
local function snippetCompletePrev(fallback)
if cmp.visible() then
cmp.select_prev_item()
elseif luasnip.jumpable(-1) then
luasnip.jump(-1)
else
fallback()
end
end
cmp.setup({
formatting = {
format = lspkind.cmp_format({
with_text = false,
maxwidth = 50,
mode = "symbol",
menu = {
buffer = "BUF",
rg = "RG",
nvim_lsp = "LSP",
path = "PATH",
luasnip = "SNIP",
calc = "CALC",
spell = "SPELL",
},
}),
},
snippet = {
expand = function(args)
require("luasnip").lsp_expand(args.body)
end,
},
mapping = {
["<Tab>"] = cmp.mapping({
i = snippetCompleteNext,
s = snippetCompleteNext,
c = function(fallback)
if cmp.visible() then
cmp.select_next_item()
elseif has_words_before() then
cmp.complete()
cmp.close()
else
fallback()
end
end,
}),
["<S-Tab>"] = cmp.mapping({
i = snippetCompletePrev,
s = snippetCompletePrev,
c = function(fallback)
if cmp.visible() then
cmp.select_prev_item()
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-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 = true }),
c = function(fallback)
if cmp.visible() then
cmp.confirm({ behavior = cmp.ConfirmBehavior.Insert, select = false })
cmp.close()
else
fallback()
end
end,
}),
},
sources = {
{ name = "nvim_lsp" },
{ name = "nvim_lsp_signature_help" },
{ name = "buffer", keyword_length = 5 },
{ name = "luasnip" },
{ name = "calc" },
{ name = "spell", keyword_length = 5 },
{ name = "path" },
{ name = "rg", keyword_length = 5 },
{ name = "orgmode" },
},
})
-- Use buffer source for `/` (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(),
completion = {
-- autocomplete = { "TextChanged" },
autocomplete = false,
},
sources = cmp.config.sources({
{ name = "path" },
}, {
{ name = "cmdline", keyword_length = 4 },
}),
})
I only want to manually trigger completion, since I don't like having to hit
<ENTER>
twice (once to select the completion and another to execute) if I know what command I want. However, when I use<TAB>
to do the completion, it just completes to the next word (which I believe is default vim behavior) and does not show a menu. I would expect that hitting<TAB>
would pop the menu. When autocomplete is enabled,<TAB>
works as expected. Thanks for your help!