Warning
nvim-compe is now deprecated. Please use nvim-cmp the successor of nvim-compe.
nvim-compe still works but new feature and bugfixes will be stopped.
nvim-compe
Auto completion plugin for nvim.
Table Of Contents
Concept
- Simple core
- No flicker
- Lua source & Vim source
- Better matching algorithm
- Support LSP completion features (trigger character, isIncomplete, expansion)
- Respect VSCode/LSP API design
Features
- VSCode compatible expansion handling
- rust-analyzer's Magic completion
- vscode-html-languageserver-bin's closing tag completion
- Other complex expansion are supported
- Flexible Custom Source API
- The source can support
documentation
/resolve
/confirm
- The source can support
- Better fuzzy matching algorithm
gu
can be matchedget_user
fmodify
can be matchedfnamemodify
- See matcher.lua for implementation details
- Buffer source carefully crafted
- The buffer source will index buffer words by filetype specific regular expression if needed
Usage
Detailed docs in here or :help compe
.
Prerequisite
Neovim version 0.5.0 or above.
You must set completeopt
to menuone,noselect
which can be easily done
as follows.
Using Vim script
set completeopt=menuone,noselect
Using Lua
vim.o.completeopt = "menuone,noselect"
The source
option is required if you want to enable but others can be omitted.
Vim script Config
let g:compe = {}
let g:compe.enabled = v:true
let g:compe.autocomplete = v:true
let g:compe.debug = v:false
let g:compe.min_length = 1
let g:compe.preselect = 'enable'
let g:compe.throttle_time = 80
let g:compe.source_timeout = 200
let g:compe.resolve_timeout = 800
let g:compe.incomplete_delay = 400
let g:compe.max_abbr_width = 100
let g:compe.max_kind_width = 100
let g:compe.max_menu_width = 100
let g:compe.documentation = v:true
let g:compe.source = {}
let g:compe.source.path = v:true
let g:compe.source.buffer = v:true
let g:compe.source.calc = v:true
let g:compe.source.nvim_lsp = v:true
let g:compe.source.nvim_lua = v:true
let g:compe.source.vsnip = v:true
let g:compe.source.ultisnips = v:true
let g:compe.source.luasnip = v:true
let g:compe.source.emoji = v:true
Lua Config
require'compe'.setup {
enabled = true;
autocomplete = true;
debug = false;
min_length = 1;
preselect = 'enable';
throttle_time = 80;
source_timeout = 200;
resolve_timeout = 800;
incomplete_delay = 400;
max_abbr_width = 100;
max_kind_width = 100;
max_menu_width = 100;
documentation = {
border = { '', '' ,'', ' ', '', '', '', ' ' }, -- the border option is the same as `|help nvim_open_win|`
winhighlight = "NormalFloat:CompeDocumentation,FloatBorder:CompeDocumentationBorder",
max_width = 120,
min_width = 60,
max_height = math.floor(vim.o.lines * 0.3),
min_height = 1,
};
source = {
path = true;
buffer = true;
calc = true;
nvim_lsp = true;
nvim_lua = true;
vsnip = true;
ultisnips = true;
luasnip = true;
};
}
Mappings
inoremap <silent><expr> <C-Space> compe#complete()
inoremap <silent><expr> <CR> compe#confirm('<CR>')
inoremap <silent><expr> <C-e> compe#close('<C-e>')
inoremap <silent><expr> <C-f> compe#scroll({ 'delta': +4 })
inoremap <silent><expr> <C-d> compe#scroll({ 'delta': -4 })
If you use cohama/lexima.vim
" NOTE: Order is important. You can't lazy loading lexima.vim.
let g:lexima_no_default_rules = v:true
call lexima#set_default_rules()
inoremap <silent><expr> <C-Space> compe#complete()
inoremap <silent><expr> <CR> compe#confirm(lexima#expand('<LT>CR>', 'i'))
inoremap <silent><expr> <C-e> compe#close('<C-e>')
inoremap <silent><expr> <C-f> compe#scroll({ 'delta': +4 })
inoremap <silent><expr> <C-d> compe#scroll({ 'delta': -4 })
If you use Raimondi/delimitMate
inoremap <silent><expr> <C-Space> compe#complete()
inoremap <silent><expr> <CR> compe#confirm({ 'keys': "\<Plug>delimitMateCR", 'mode': '' })
inoremap <silent><expr> <C-e> compe#close('<C-e>')
inoremap <silent><expr> <C-f> compe#scroll({ 'delta': +4 })
inoremap <silent><expr> <C-d> compe#scroll({ 'delta': -4 })
If you use windwp/nvim-autopairs
inoremap <silent><expr> <C-Space> compe#complete()
inoremap <silent><expr> <CR> compe#confirm(luaeval("require 'nvim-autopairs'.autopairs_cr()"))
inoremap <silent><expr> <C-e> compe#close('<C-e>')
inoremap <silent><expr> <C-f> compe#scroll({ 'delta': +4 })
inoremap <silent><expr> <C-d> compe#scroll({ 'delta': -4 })
Highlight
You can change documentation window's highlight group via following.
highlight link CompeDocumentation NormalFloat
Built-in sources
Common
- buffer
- path
- tags
- spell
- calc
- omni (Warning: It has a lot of side-effect.)
Neovim-specific
- nvim_lsp
- nvim_lua
External-plugin
- vim_lsp
- vim_lsc
- vim-vsnip
- ultisnips
- snippets.nvim
- luasnip
- nvim-treesitter (Warning: it sometimes really slow.)
External sources
Known issues
You can see the known issues in here.
Note: The next-version means nvim-cmp now.
FAQ
Can't get it work.
If you are enabling the omni
source, please try to disable it.
Incredibly lagging.
If you are enabling the treesitter
source, please try to disable it.
Does not work function signature window.
The signature help is out of scope of compe. It should be another plugin e.g. lsp_signature.nvim
If you are enabling the treesitter
source, please try to disable it.
Pattern not found
?
How to remove You can set set shortmess+=c
in your vimrc.
How to use LSP snippet?
-
Set
snippetSupport=true
for LSP capabilities.local capabilities = vim.lsp.protocol.make_client_capabilities() capabilities.textDocument.completion.completionItem.snippetSupport = true capabilities.textDocument.completion.completionItem.resolveSupport = { properties = { 'documentation', 'detail', 'additionalTextEdits', } } require'lspconfig'.rust_analyzer.setup { capabilities = capabilities, }
-
Install
vim-vsnip
Plug 'hrsh7th/vim-vsnip'
or
snippets.nvim
Plug 'norcalli/snippets.nvim'
or
UltiSnips
Plug 'SirVer/ultisnips'
or
LuaSnip
Plug 'L3MON4D3/LuaSnip'
How to use tab to navigate completion menu?
Tab
and S-Tab
keys need to be mapped to <C-n>
and <C-p>
when completion
menu is visible. Following example will use Tab
and S-Tab
(shift+tab) to
navigate completion menu and jump between
vim-vsnip placeholders when possible:
local t = function(str)
return vim.api.nvim_replace_termcodes(str, true, true, true)
end
local check_back_space = function()
local col = vim.fn.col('.') - 1
return col == 0 or vim.fn.getline('.'):sub(col, col):match('%s') ~= nil
end
-- Use (s-)tab to:
--- move to prev/next item in completion menuone
--- jump to prev/next snippet's placeholder
_G.tab_complete = function()
if vim.fn.pumvisible() == 1 then
return t "<C-n>"
elseif vim.fn['vsnip#available'](1) == 1 then
return t "<Plug>(vsnip-expand-or-jump)"
elseif check_back_space() then
return t "<Tab>"
else
return vim.fn['compe#complete']()
end
end
_G.s_tab_complete = function()
if vim.fn.pumvisible() == 1 then
return t "<C-p>"
elseif vim.fn['vsnip#jumpable'](-1) == 1 then
return t "<Plug>(vsnip-jump-prev)"
else
-- If <S-Tab> is not working in your terminal, change it to <C-h>
return t "<S-Tab>"
end
end
vim.api.nvim_set_keymap("i", "<Tab>", "v:lua.tab_complete()", {expr = true})
vim.api.nvim_set_keymap("s", "<Tab>", "v:lua.tab_complete()", {expr = true})
vim.api.nvim_set_keymap("i", "<S-Tab>", "v:lua.s_tab_complete()", {expr = true})
vim.api.nvim_set_keymap("s", "<S-Tab>", "v:lua.s_tab_complete()", {expr = true})
How to expand snippets from completion menu?
Use compe#confirm()
mapping, as described in section Mappings.
How to automatically select the first match?
compe#confirm()
with the select option set to true will select the first item when none has been manually selected. For example:
vim.api.nvim_set_keymap("i", "<CR>", "compe#confirm({ 'keys': '<CR>', 'select': v:true })", { expr = true })
ESC does not close the completion menu
Another plugin might be interfering with it. vim-autoclose
does this. You can check the mapping of <ESC>
by running
imap <ESC>
vim-autoclose
's function looks similar to this:
<Esc> *@pumvisible() ? '<C-E>' : '<C-R>=<SNR>110_FlushBuffer()<CR><Esc>'
In the particular case of vim-autoclose
, the problem can be fixed by adding this setting:
let g:AutoClosePumvisible = {"ENTER": "<C-Y>", "ESC": "<ESC>"}
Other plugins might need other custom settings.