A completion engine plugin for neovim written in Lua. Completion sources are installed from external repositories and "sourced".
sumneko_lua
purescript-language-server
This example configuration is using vim-plug.
vim-plug
call plug#begin(s:plug_dir) Plug 'neovim/nvim-lspconfig' Plug 'hrsh7th/cmp-nvim-lsp' Plug 'hrsh7th/cmp-buffer' Plug 'hrsh7th/nvim-cmp' " For vsnip user. Plug 'hrsh7th/cmp-vsnip' Plug 'hrsh7th/vim-vsnip' " For luasnip user. " Plug 'L3MON4D3/LuaSnip' " Plug 'saadparwaiz1/cmp_luasnip' " For ultisnips user. " Plug 'SirVer/ultisnips' " Plug 'quangnguyen30192/cmp-nvim-ultisnips' call plug#end() set completeopt=menu,menuone,noselect lua <<EOF -- Setup nvim-cmp. local cmp = require'cmp' cmp.setup({ snippet = { expand = function(args) -- For `vsnip` user. vim.fn["vsnip#anonymous"](args.body) -- For `luasnip` user. -- require('luasnip').lsp_expand(args.body) -- For `ultisnips` user. -- vim.fn["UltiSnips#Anon"](args.body) end, }, mapping = { ['<C-d>'] = cmp.mapping.scroll_docs(-4), ['<C-f>'] = cmp.mapping.scroll_docs(4), ['<C-Space>'] = cmp.mapping.complete(), ['<C-e>'] = cmp.mapping.close(), ['<CR>'] = cmp.mapping.confirm({ select = true }), }, sources = { { name = 'nvim_lsp' }, -- For vsnip user. { name = 'vsnip' }, -- For luasnip user. -- { name = 'luasnip' }, -- For ultisnips user. -- { name = 'ultisnips' }, { name = 'buffer' }, } }) -- Setup lspconfig. require('lspconfig')[%YOUR_LSP_SERVER%].setup { capabilities = require('cmp_nvim_lsp').update_capabilities(vim.lsp.protocol.make_client_capabilities()) } EOF
You can see the all of nvim-cmp sources here.
nvim-cmp
You can specify the following configuration options via cmp.setup { ... }.
cmp.setup { ... }
The configuration options will be merged with the default config.
If you want to remove an option, you can set it to false instead.
false
Built in helper cmd.mappings are:
cmd.mappings
You can configure nvim-cmp to use these cmd.mappings like this:
mapping = { ['<C-n>'] = cmp.mapping.select_next_item({ behavior = cmp.SelectBehavior.Insert }), ['<C-p>'] = cmp.mapping.select_prev_item({ behavior = cmp.SelectBehavior.Insert }), ['<Down>'] = cmp.mapping.select_next_item({ behavior = cmp.SelectBehavior.Select }), ['<Up>'] = cmp.mapping.select_prev_item({ behavior = cmp.SelectBehavior.Select }), ['<C-d>'] = cmp.mapping.scroll_docs(-4), ['<C-f>'] = cmp.mapping.scroll_docs(4), ['<C-Space>'] = cmp.mapping.complete(), ['<C-e>'] = cmp.mapping.close(), ['<CR>'] = cmp.mapping.confirm({ behavior = cmp.ConfirmBehavior.Replace, select = true, }) }
In addition, the mapping mode can be specified. The default is insert mode (i).
mapping = { ... ['<Tab>'] = cmp.mapping(cmp.mapping.select_next_item(), { 'i', 's' }) ... }
You can specify your own custom mapping function.
mapping = { ['<Tab>'] = function(fallback) if ...some_condition... then vim.api.nvim_feedkeys(vim.api.nvim_replace_termcodes('...', true, true, true), 'n', true) else fallback() -- The fallback function is treated as original mapped key. In this case, it might be `<Tab>`. end end, }
The function or boolean value to specify all cmp's features enabled or not.
Default:
function() return vim.api.nvim_buf_get_option(0, 'buftype') ~= 'prompt' end
Global source lists are listed in the source table. These are applied to all buffers. The order of the sources list helps define the source priority, see the sorting.priority_weight options below.
source
It is possible to setup different source lists for different filetypes, this is an example using the FileType autocommand to setup different sources for the lua filetype.
FileType
" Setup buffer configuration (nvim-lua source only enables in Lua filetype). autocmd FileType lua lua require'cmp'.setup.buffer { \ sources = { \ { name = 'nvim_lua' }, \ { name = 'buffer' }, \ }, \ }
Note that the source name isn't necessarily the source repository name. Source names are defined in the source repository README files. For example look at the hrsh7th/cmp-buffer source README which defines the source name as buffer.
buffer
The source name.
The source customization options. It is defined by each source.
The manually specified source priority. If you don't specify it, the source priority will be determined by the default algorithm (see sorting.priority_weight).
sorting.priority_weight
The source specific keyword_pattern for override.
The source specific keyword_length for override.
The source specific maximum item count.
Specify preselect mode. The following modes are available.
cmp.PreselectMode.Item
preselect = true
cmp.PreselectMode.None
Default: cmp.PreselectMode.Item
Which events should trigger autocompletion.
autocompletion
If you set this to false, nvim-cmp will not perform completion automatically. You can still use manual completion though (like omni-completion via the cmp.mapping.complete function).
cmp.mapping.complete
Default: { types.cmp.TriggerEvent.TextChanged }
{ types.cmp.TriggerEvent.TextChanged }
The default keyword pattern. This value will be used if a source does not set a source specific pattern.
Default: [[\%(-\?\d\+\%(\.\d\+\)\?\|\h\w*\%(-\w*\)*\)]]
[[\%(-\?\d\+\%(\.\d\+\)\?\|\h\w*\%(-\w*\)*\)]]
The minimum length of a word to complete on; e.g., do not try to complete when the length of the word to the left of the cursor is less than keyword_length.
keyword_length
Default: 1
1
The function to resolve trigger_characters.
Default: function(trigger_characters) return trigger_characters end
function(trigger_characters) return trigger_characters end
vim's completeopt setting. Warning: Be careful when changing this value.
completeopt
Default: menu,menuone,noselect
menu,menuone,noselect
A default cmp.ConfirmBehavior value when to use confirmed by commitCharacters
cmp.ConfirmBehavior
Default: cmp.ConfirmBehavior.Insert
cmp.ConfirmBehavior.Insert
The function to resolve commit_characters.
When sorting completion items before displaying them, boost each item's score based on the originating source. Each source gets a base priority of #sources - (source_index - 1), and we then multiply this by priority_weight:
#sources - (source_index - 1)
priority_weight
score = score + ((#sources - (source_index - 1)) * sorting.priority_weight)
Default: 2
2
When sorting completion items, the sort logic tries each function in sorting.comparators consecutively when comparing two items. The first function to return something other than nil takes precedence.
sorting.comparators
nil
Each function must return boolean|nil.
boolean|nil
You can use the preset functions from cmp.config.compare.*.
cmp.config.compare.*
{ cmp.config.compare.offset, cmp.config.compare.exact, cmp.config.compare.score, cmp.config.compare.kind, cmp.config.compare.sort_text, cmp.config.compare.length, cmp.config.compare.order, }
A documentation configuration or false to disable feature.
Border characters used for documentation window.
A neovim's winhighlight option for documentation window.
winhighlight
The documentation window's max width.
The documentation window's max height.
A function to customize completion menu.
The return value is defined by vim. See :help complete-items.
:help complete-items
You can display the fancy icons to completion-menu with lspkind-nvim.
Please see FAQ if you would like to show symbol-text (e.g. function) and source (e.g. LSP) like compe.
local lspkind = require('lspkind') cmp.setup { formatting = { format = lspkind.cmp_format(), }, }
A callback function called when the item is confirmed.
Use vim's native completion menu instead of custom floating menu.
Default: false
Specify whether to display ghost text.
CmpStatus
Show the source statuses
cmp#ready
Invoke after nvim-cmp setup.
CmpItemAbbr
The abbr field.
CmpItemAbbrDeprecated
The deprecated item's abbr field.
CmpItemAbbrMatch
The matched characters highlight.
CmpItemAbbrMatchFuzzy
The fuzzy matched characters highlight.
CmpItemKind
The kind field.
CmpItemMenu
The menu field.
You can use the following APIs.
cmp.visible()
Return the completion menu is visible or not.
NOTE: This method returns true if the native popup menu is visible. For convenience to define mappings.
cmp.confirm({ select = boolean, behavior = cmp.ConfirmBehavior.{Insert,Replace} })
Confirm current selected item if possible.
cmp.complete()
Invoke manual completion.
cmp.close()
Close current completion menu.
cmp.abort()
Close current completion menu and restore current line (similar to native <C-e> behavior).
<C-e>
cmp.select_next_item({ cmp.SelectBehavior.{Insert,Select} })
Select next completion item if possible.
cmp.select_prev_item({ cmp.SelectBehavior.{Insert,Select} })
Select previous completion item if possible.
cmp.scroll_docs(delta)
Scroll documentation window if possible.
You should check :CmpStatus command's output. Probably, your specified source name is wrong.
:CmpStatus
NOTE: nvim_lsp will be sourced on InsertEnter event. It will show as unknown source but it isn't problem.
nvim_lsp
unknown source
pairs-wise plugin automatically supported
Some pairs-wise plugin set up the mapping automatically. For example, vim-endwise will map <CR> even if you don't do any mapping instructions for the plugin.
vim-endwise
<CR>
But I think the user want to override <CR> mapping only when the mapping item is selected.
The nvim-cmp does it automatically.
The following configuration will be working as
cmp.mapping.confirm
mapping = { ['<CR>'] = cmp.mapping.confirm() }
preselect = 'always'
You can use the following configuration.
cmp.setup { completion = { completeopt = 'menu,menuone,noinsert', } }
You can use nvim-cmp without auto-completion like this.
cmp.setup { completion = { autocomplete = false } }
You can specify enabled = false like this.
enabled = false
autocmd FileType TelescopePrompt lua require('cmp').setup.buffer { enabled = false }
I've optimized nvim-cmp as much as possible, but there are currently some known / unfixable issues.
cmp-buffer source and too large buffer
cmp-buffer
The cmp-buffer source makes an index of the current buffer so if the current buffer is too large, it will slowdown the main UI thread.
vim.lsp.set_log_level
This setting will cause the filesystem operation for each LSP payload. This will greatly slow down nvim-cmp (and other LSP related features).
formatting = { format = require("lspkind").cmp_format({with_text = true, menu = ({ buffer = "[Buffer]", nvim_lsp = "[LSP]", luasnip = "[LuaSnip]", nvim_lua = "[Lua]", latex_symbols = "[Latex]", })}), },
You can find all the mapping solutions in Example mappings.
Warning: If the LSP spec is changed, nvim-cmp will keep up to it without an announcement.
If you publish nvim-cmp source to GitHub, please add nvim-cmp topic for the repo.
You should read cmp types and LSP spec to create sources.
complete
callback
require('cmp')
word
local source = {} ---Source constructor. source.new = function() local self = setmetatable({}, { __index = source }) self.your_awesome_variable = 1 return self end ---Return the source is available or not. ---@return boolean function source:is_available() return true end ---Return the source name for some information. function source:get_debug_name() return 'example' end ---Return keyword pattern which will be used... --- 1. Trigger keyword completion --- 2. Detect menu start offset --- 3. Reset completion state ---@param params cmp.SourceBaseApiParams ---@return string function source:get_keyword_pattern(params) return '???' end ---Return trigger characters. ---@param params cmp.SourceBaseApiParams ---@return string[] function source:get_trigger_characters(params) return { ??? } end ---Invoke completion (required). --- If you want to abort completion, just call the callback without arguments. ---@param params cmp.SourceCompletionApiParams ---@param callback fun(response: lsp.CompletionResponse|nil) function source:complete(params, callback) callback({ { label = 'January' }, { label = 'February' }, { label = 'March' }, { label = 'April' }, { label = 'May' }, { label = 'June' }, { label = 'July' }, { label = 'August' }, { label = 'September' }, { label = 'October' }, { label = 'November' }, { label = 'December' }, }) end ---Resolve completion item that will be called when the item selected or before the item confirmation. ---@param completion_item lsp.CompletionItem ---@param callback fun(completion_item: lsp.CompletionItem|nil) function source:resolve(completion_item, callback) callback(completion_item) end ---Execute command that will be called when after the item confirmation. ---@param completion_item lsp.CompletionItem ---@param callback fun(completion_item: lsp.CompletionItem|nil) function source:execute(completion_item, callback) callback(completion_item) end require('cmp').register_source(source.new())
You can also create source by Vim script like this (This is useful to support callback style plugins).
boolean
v:true
v:false
0
let s:source = {} function! s:source.new() abort return extend(deepcopy(s:source)) endfunction " The other APIs are also available. function! s:source.complete(params, callback) abort call a:callback({ \ { 'label': 'January' }, \ { 'label': 'February' }, \ { 'label': 'March' }, \ { 'label': 'April' }, \ { 'label': 'May' }, \ { 'label': 'June' }, \ { 'label': 'July' }, \ { 'label': 'August' }, \ { 'label': 'September' }, \ { 'label': 'October' }, \ { 'label': 'November' }, \ { 'label': 'December' }, \ }) endfunction call cmp#register_source('month', s:source.new())