Improve README.md
This commit is contained in:
721
README.md
721
README.md
@@ -11,25 +11,18 @@ Readme!
|
||||
1. nvim-cmp's breaking changes are documented [here](https://github.com/hrsh7th/nvim-cmp/issues/231).
|
||||
2. This is my hobby project. You can support me via GitHub sponsors.
|
||||
3. Bug reports are welcome, but I might not fix if you don't provide a minimal reproduction configuration and steps.
|
||||
4. The nvim-cmp documents is [here](./doc/cmp.txt).
|
||||
|
||||
|
||||
|
||||
Concept
|
||||
====================
|
||||
|
||||
- Full support for LSP completion related capabilities
|
||||
- Powerful customizability via Lua functions
|
||||
- Smart handling of key mapping
|
||||
- No flicker
|
||||
- Works properly
|
||||
- Fully customizable via Lua functions
|
||||
- Fully supports LSP's completion capabilities
|
||||
- Snippets
|
||||
- CommitCharacters
|
||||
- TriggerCharacters
|
||||
- TextEdit and InsertReplaceTextEdit
|
||||
- AdditionalTextEdits
|
||||
- Markdown documentation
|
||||
- Execute commands (Some LSP server needs it to auto-importing. e.g. `sumneko_lua` or `purescript-language-server`)
|
||||
- Preselect
|
||||
- CompletionItemTags
|
||||
- Support pairs-wise plugin automatically
|
||||
|
||||
|
||||
|
||||
Setup
|
||||
@@ -78,8 +71,8 @@ lua <<EOF
|
||||
expand = function(args)
|
||||
vim.fn["vsnip#anonymous"](args.body) -- For `vsnip` users.
|
||||
-- require('luasnip').lsp_expand(args.body) -- For `luasnip` users.
|
||||
-- require('snippy').expand_snippet(args.body) -- For `snippy` users.
|
||||
-- vim.fn["UltiSnips#Anon"](args.body) -- For `ultisnips` users.
|
||||
-- require'snippy'.expand_snippet(args.body) -- For `snippy` users.
|
||||
end,
|
||||
},
|
||||
mapping = {
|
||||
@@ -91,9 +84,7 @@ lua <<EOF
|
||||
i = cmp.mapping.abort(),
|
||||
c = cmp.mapping.close(),
|
||||
}),
|
||||
-- Accept currently selected item. If none selected, `select` first item.
|
||||
-- Set `select` to `false` to only confirm explicitly selected items.
|
||||
['<CR>'] = cmp.mapping.confirm({ select = true }),
|
||||
['<CR>'] = cmp.mapping.confirm({ select = true }), -- Accept currently selected item. Set `select` to `false` to only confirm explicitly selected items.
|
||||
},
|
||||
sources = cmp.config.sources({
|
||||
{ name = 'nvim_lsp' },
|
||||
@@ -130,7 +121,6 @@ lua <<EOF
|
||||
}
|
||||
EOF
|
||||
```
|
||||
Also, checkout [mappings](https://github.com/hrsh7th/nvim-cmp/wiki/Example-mappings) section in the [wiki](https://github.com/hrsh7th/nvim-cmp/wiki) for example `<Tab>` mappings and integration with snippets.
|
||||
|
||||
### Where can I find more completion sources?
|
||||
|
||||
@@ -140,662 +130,77 @@ You can search for various completion sources [here](https://github.com/topics/n
|
||||
|
||||
Please see the corresponding [FAQ](#how-to-show-name-of-item-kind-and-source-like-compe) section or [Wiki pages](https://github.com/hrsh7th/nvim-cmp/wiki).
|
||||
|
||||
Configuration options
|
||||
|
||||
Advanced configuration example
|
||||
====================
|
||||
|
||||
You can specify the following configuration options via `cmp.setup { ... }`.
|
||||
### Use nvim-cmp as smart omnifunc handler.
|
||||
|
||||
The configuration options will be merged with the [default config](./lua/cmp/config/default.lua).
|
||||
|
||||
If you want to remove a default option, set it to `false`.
|
||||
|
||||
|
||||
#### mapping (type: table<string, fun(fallback: function)>)
|
||||
|
||||
Defines the action of each key mapping. The following lists all the built-in actions:
|
||||
|
||||
- `cmp.mapping.select_prev_item({ cmp.SelectBehavior.{Insert,Select} })`
|
||||
- `cmp.mapping.select_next_item({ cmp.SelectBehavior.{Insert,Select} })`
|
||||
- `cmp.mapping.scroll_docs(number)`
|
||||
- `cmp.mapping.complete({ reason = cmp.ContextReason.{Manual,Auto} })`
|
||||
- `cmp.mapping.close()`
|
||||
- `cmp.mapping.abort()`
|
||||
- `cmp.mapping.confirm({ select = bool, behavior = cmp.ConfirmBehavior.{Insert,Replace} })`: If `select` is true and you haven't select any item, automatically selects the first item.
|
||||
|
||||
You can configure `nvim-cmp` to use these `cmp.mapping` like this:
|
||||
nvim-cmp can be used as flexible omnifunc manager.
|
||||
|
||||
```lua
|
||||
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-b>'] = 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 with the help of `cmp.mapping(...)`. The default is the insert mode (i) if not specified.
|
||||
|
||||
```lua
|
||||
mapping = {
|
||||
...
|
||||
['<Tab>'] = cmp.mapping(cmp.mapping.select_next_item(), { 'i', 's' })
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
The mapping mode can also be specified using a table. This is particularly useful to set different actions for each mode.
|
||||
|
||||
```lua
|
||||
mapping = {
|
||||
['<CR>'] = cmp.mapping({
|
||||
i = cmp.mapping.confirm({ select = true }),
|
||||
c = cmp.mapping.confirm({ select = false }),
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
You can also provide a custom function as the action.
|
||||
|
||||
```lua
|
||||
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,
|
||||
}
|
||||
```
|
||||
|
||||
#### enabled (type: fun(): boolean|boolean)
|
||||
|
||||
A boolean value, or a function returning a boolean, that specifies whether to enable nvim-cmp's features or not.
|
||||
|
||||
Default:
|
||||
|
||||
```lua
|
||||
function()
|
||||
return vim.api.nvim_buf_get_option(0, 'buftype') ~= 'prompt'
|
||||
end
|
||||
```
|
||||
|
||||
#### sources (type: table<cmp.SourceConfig>)
|
||||
|
||||
Lists all the global completion sources that will be enabled in all buffers.
|
||||
The order of the list defines the priority of each source. See the
|
||||
*sorting.priority_weight* option below.
|
||||
|
||||
It is possible to set up different sources for different filetypes using
|
||||
`FileType` autocommand and `cmp.setup.buffer` to override the global
|
||||
configuration.
|
||||
|
||||
```viml
|
||||
" 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](https://github.com/hrsh7th/cmp-buffer) source README
|
||||
which defines the source name as `buffer`.
|
||||
|
||||
#### sources[number].name (type: string)
|
||||
|
||||
The source name.
|
||||
|
||||
#### sources[number].option (type: table)
|
||||
|
||||
The source customization options. It is defined by each source.
|
||||
|
||||
#### sources[number].priority (type: number|nil)
|
||||
|
||||
The priority of the source. If you don't specify it, the source priority will
|
||||
be determined by the default algorithm (see `sorting.priority_weight`).
|
||||
|
||||
#### sources[number].trigger_characters (type: string[])
|
||||
|
||||
The source specific triggerCharacters for override.
|
||||
|
||||
#### sources[number].keyword_pattern (type: string)
|
||||
|
||||
The source specific keyword_pattern for override.
|
||||
|
||||
#### sources[number].keyword_length (type: number)
|
||||
|
||||
The source specific keyword_length for override.
|
||||
|
||||
#### sources[number].max_item_count (type: number)
|
||||
|
||||
The source specific maximum item count.
|
||||
|
||||
#### sources[number].group_index (type: number)
|
||||
|
||||
The source group index.
|
||||
|
||||
You can call built-in utility like `cmp.config.sources({ { name = 'a' } }, { { name = 'b' } })`.
|
||||
|
||||
#### preselect (type: cmp.PreselectMode)
|
||||
|
||||
Specify preselect mode. The following modes are available.
|
||||
|
||||
- `cmp.PreselectMode.Item`
|
||||
- If the item has `preselect = true`, `nvim-cmp` will preselect it.
|
||||
- `cmp.PreselectMode.None`
|
||||
- Disable preselect feature.
|
||||
|
||||
Default: `cmp.PreselectMode.Item`
|
||||
|
||||
#### completion.autocomplete (type: cmp.TriggerEvent[])
|
||||
|
||||
Which events should trigger `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).
|
||||
|
||||
Default: `{ types.cmp.TriggerEvent.TextChanged }`
|
||||
|
||||
#### completion.keyword_pattern (type: string)
|
||||
|
||||
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*\)*\)]]`
|
||||
|
||||
#### completion.keyword_length (type: number)
|
||||
|
||||
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`.
|
||||
|
||||
Default: `1`
|
||||
|
||||
#### completion.get_trigger_characters (type: fun(trigger_characters: string[]): string[])
|
||||
|
||||
The function to resolve trigger_characters.
|
||||
|
||||
Default: `function(trigger_characters) return trigger_characters end`
|
||||
|
||||
#### completion.completeopt (type: string)
|
||||
|
||||
vim's `completeopt` setting. Warning: Be careful when changing this value.
|
||||
|
||||
Default: `menu,menuone,noselect`
|
||||
|
||||
#### confirmation.default_behavior (type: cmp.ConfirmBehavior)
|
||||
|
||||
A default `cmp.ConfirmBehavior` value when to use confirmed by commitCharacters
|
||||
|
||||
Default: `cmp.ConfirmBehavior.Insert`
|
||||
|
||||
#### confirmation.get_commit_characters (type: fun(commit_characters: string[]): string[])
|
||||
|
||||
The function to resolve commit_characters.
|
||||
|
||||
#### sorting.priority_weight (type: number)
|
||||
|
||||
The score multiplier of source when calculating the items' priorities.
|
||||
Specifically, each item's original priority (given by its corresponding source)
|
||||
will be increased by `#sources - (source_index - 1)` multiplied by
|
||||
`priority_weight`. That is, the final priority is calculated by the following formula:
|
||||
|
||||
`final_score = orig_score + ((#sources - (source_index - 1)) * sorting.priority_weight)`
|
||||
|
||||
Default: `2`
|
||||
|
||||
#### sorting.comparators (type: function[])
|
||||
|
||||
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.
|
||||
|
||||
Each function must return `boolean|nil`.
|
||||
|
||||
You can use the preset functions from `cmp.config.compare.*`.
|
||||
|
||||
Default:
|
||||
```lua
|
||||
{
|
||||
cmp.config.compare.offset,
|
||||
cmp.config.compare.exact,
|
||||
cmp.config.compare.score,
|
||||
cmp.config.compare.recently_used,
|
||||
cmp.config.compare.kind,
|
||||
cmp.config.compare.sort_text,
|
||||
cmp.config.compare.length,
|
||||
cmp.config.compare.order,
|
||||
}
|
||||
```
|
||||
|
||||
#### documentation (type: false | cmp.DocumentationConfig)
|
||||
|
||||
If set to `false`, the documentation of each item will not be shown.
|
||||
Else, a table representing documentation configuration should be provided.
|
||||
The following are the possible options:
|
||||
|
||||
#### documentation.border (type: string[])
|
||||
|
||||
Border characters used for documentation window.
|
||||
|
||||
#### documentation.winhighlight (type: string)
|
||||
|
||||
A neovim's `winhighlight` option for documentation window.
|
||||
|
||||
#### documentation.maxwidth (type: number)
|
||||
|
||||
The documentation window's max width.
|
||||
|
||||
#### documentation.maxheight (type: number)
|
||||
|
||||
The documentation window's max height.
|
||||
|
||||
#### documentation.zindex (type: number)
|
||||
|
||||
The documentation window's zindex.
|
||||
|
||||
#### formatting.fields (type: cmp.ItemField[])
|
||||
|
||||
The order of item's fields for completion menu.
|
||||
|
||||
#### formatting.format (type: fun(entry: cmp.Entry, vim_item: vim.CompletedItem): vim.CompletedItem)
|
||||
|
||||
A function to customize completion menu.
|
||||
The return value is defined by vim. See `:help complete-items`.
|
||||
|
||||
You can display the fancy icons to completion-menu with [lspkind-nvim](https://github.com/onsails/lspkind-nvim).
|
||||
|
||||
Please see [FAQ](#how-to-show-name-of-item-kind-and-source-like-compe) if you would like to show symbol-text (e.g. function) and source (e.g. LSP) like compe.
|
||||
|
||||
```lua
|
||||
local lspkind = require('lspkind')
|
||||
local cmp = require('cmp')
|
||||
cmp.setup {
|
||||
formatting = {
|
||||
format = lspkind.cmp_format(),
|
||||
completion = {
|
||||
autocomplete = false, -- disable auto-completion.
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
See the [wiki](https://github.com/hrsh7th/nvim-cmp/wiki/Menu-Appearance#basic-customisations) for more info on customizing menu appearance.
|
||||
|
||||
#### experimental.native_menu (type: boolean)
|
||||
|
||||
Use vim's native completion menu instead of custom floating menu.
|
||||
|
||||
Default: `false`
|
||||
|
||||
#### experimental.ghost_text (type: cmp.GhostTextConfig | false)
|
||||
|
||||
Specify whether to display ghost text.
|
||||
|
||||
Default: `false`
|
||||
|
||||
Commands
|
||||
====================
|
||||
|
||||
#### `CmpStatus`
|
||||
|
||||
Show the source statuses
|
||||
|
||||
Autocmds
|
||||
====================
|
||||
|
||||
#### `cmp#ready`
|
||||
|
||||
Invoke after nvim-cmp setup.
|
||||
|
||||
Highlights
|
||||
====================
|
||||
|
||||
#### `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.
|
||||
|
||||
#### `CmpItemKind%KIND_NAME%`
|
||||
|
||||
The specific kind highlights.
|
||||
You can see the name on [lsp.lua#L108](./lua/cmp/types/lsp.lua#L108).
|
||||
|
||||
For example, You can change the highlight like this if you want to override only the `Method` kind.
|
||||
|
||||
```
|
||||
highlight! CmpItemKindMethod guibg=NONE guifg=LightYellow
|
||||
```
|
||||
|
||||
|
||||
#### `CmpItemMenu`
|
||||
|
||||
The menu field.
|
||||
|
||||
Programatic API
|
||||
====================
|
||||
|
||||
You can use the following APIs.
|
||||
|
||||
#### `cmp.event:on(name: string, callback: string)`
|
||||
|
||||
Subscribes to the following events.
|
||||
|
||||
- `confirm_done`
|
||||
|
||||
#### `cmp.get_config()`
|
||||
|
||||
Returns the current configuration.
|
||||
|
||||
#### `cmp.visible()`
|
||||
|
||||
Returns the completion menu is visible or not.
|
||||
|
||||
NOTE: This method returns true if the native popup menu is visible, for the convenience of defining mappings.
|
||||
|
||||
#### `cmp.get_selected_entry()`
|
||||
|
||||
Returns the selected entry.
|
||||
|
||||
#### `cmp.get_active_entry()`
|
||||
|
||||
Returns the active entry.
|
||||
|
||||
NOTE: The `preselected` entry does not returned from this method.
|
||||
|
||||
#### `cmp.confirm({ select = boolean, behavior = cmp.ConfirmBehavior.{Insert,Replace} }, callback)`
|
||||
|
||||
Confirms the current selected item, if possible. If `select` is true and no item has been selected, selects the first item.
|
||||
|
||||
#### `cmp.complete({ reason = cmp.ContextReason.{Manual,Auto} })`
|
||||
|
||||
Invokes manual completion.
|
||||
|
||||
NOTE: manual completion overrules some checks autocompletion does like `keyword_length`.
|
||||
To make it behave like autocompletion instead, you can overwrite the reason in the argument.
|
||||
|
||||
#### `cmp.close()`
|
||||
|
||||
Closes the current completion menu.
|
||||
|
||||
#### `cmp.abort()`
|
||||
|
||||
Closes the current completion menu and restore the current line (similar to native `<C-e>` behavior).
|
||||
|
||||
#### `cmp.select_next_item({ cmp.SelectBehavior.{Insert,Select} })`
|
||||
|
||||
Selects the next completion item if possible.
|
||||
|
||||
#### `cmp.select_prev_item({ cmp.SelectBehavior.{Insert,Select} })`
|
||||
|
||||
Selects the previous completion item if possible.
|
||||
|
||||
#### `cmp.scroll_docs(delta)`
|
||||
|
||||
Scrolls the documentation window by `delta` lines, if possible.
|
||||
|
||||
|
||||
FAQ
|
||||
====================
|
||||
|
||||
#### I can't get the specific source working.
|
||||
|
||||
Check the output of command `:CmpStatus`. It is likely that you specify the source name incorrectly.
|
||||
|
||||
NOTE: `nvim_lsp` will be sourced on `InsertEnter` event. It will show as `unknown source`, but this isn't a problem.
|
||||
|
||||
|
||||
#### What is the `pair-wise plugin automatically supported`?
|
||||
|
||||
Some pair-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.
|
||||
|
||||
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
|
||||
|
||||
1. If the completion-item is selected, will be working as `cmp.mapping.confirm`.
|
||||
2. If the completion-item isn't selected, will be working as vim-endwise feature.
|
||||
|
||||
```lua
|
||||
mapping = {
|
||||
['<CR>'] = cmp.mapping.confirm()
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
#### What is the equivalence of nvim-compe's `preselect = 'always'`?
|
||||
|
||||
You can use the following configuration.
|
||||
|
||||
```lua
|
||||
cmp.setup {
|
||||
completion = {
|
||||
completeopt = 'menu,menuone,noinsert',
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### I don't use a snippet plugin.
|
||||
|
||||
At the moment, nvim-cmp requires a snippet engine to function correctly.
|
||||
You need to specify one in `snippet`.
|
||||
|
||||
```lua
|
||||
snippet = {
|
||||
-- REQUIRED - you must specify a snippet engine
|
||||
expand = function(args)
|
||||
vim.fn["vsnip#anonymous"](args.body) -- For `vsnip` users.
|
||||
-- require('luasnip').lsp_expand(args.body) -- For `luasnip` users.
|
||||
-- vim.fn["UltiSnips#Anon"](args.body) -- For `ultisnips` users.
|
||||
-- require'snippy'.expand_snippet(args.body) -- For `snippy` users.
|
||||
end,
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
#### I dislike auto-completion
|
||||
|
||||
You can use `nvim-cmp` without auto-completion like this.
|
||||
|
||||
```lua
|
||||
cmp.setup {
|
||||
completion = {
|
||||
autocomplete = false
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
#### How to disable nvim-cmp on the specific buffer?
|
||||
|
||||
You can specify `enabled = false` like this.
|
||||
|
||||
```vim
|
||||
autocmd FileType TelescopePrompt lua require('cmp').setup.buffer { enabled = false }
|
||||
```
|
||||
|
||||
|
||||
#### nvim-cmp is slow.
|
||||
|
||||
I've optimized `nvim-cmp` as much as possible, but there are currently some known / unfixable issues.
|
||||
|
||||
**`cmp-buffer` source and too large 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).
|
||||
|
||||
|
||||
#### How to show name of item kind and source (like compe)?
|
||||
|
||||
```lua
|
||||
formatting = {
|
||||
format = require("lspkind").cmp_format({with_text = true, menu = ({
|
||||
buffer = "[Buffer]",
|
||||
nvim_lsp = "[LSP]",
|
||||
luasnip = "[LuaSnip]",
|
||||
nvim_lua = "[Lua]",
|
||||
latex_symbols = "[Latex]",
|
||||
})}),
|
||||
},
|
||||
```
|
||||
See [Menu appearance](https://github.com/hrsh7th/nvim-cmp/wiki/Menu-Appearance) section from the [wiki](https://github.com/hrsh7th/nvim-cmp/wiki) for more information.
|
||||
|
||||
#### How to set up mappings?
|
||||
|
||||
You can find all the mapping examples in [Example mappings](https://github.com/hrsh7th/nvim-cmp/wiki/Example-mappings).
|
||||
|
||||
|
||||
Create a Custom Source
|
||||
====================
|
||||
|
||||
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](/lua/cmp/types) and [LSP spec](https://microsoft.github.io/language-server-protocol/specifications/specification-current/) to create sources.
|
||||
|
||||
- The `complete` function is required. Others can be omitted.
|
||||
- The `callback` argument must always be called.
|
||||
- The custom source should only use `require('cmp')`.
|
||||
- The custom source can specify `word` property to CompletionItem. (It isn't an LSP specification but supported as a special case.)
|
||||
|
||||
Here is an example of a custom source.
|
||||
|
||||
```lua
|
||||
local source = {}
|
||||
|
||||
---Source constructor.
|
||||
source.new = function()
|
||||
local self = setmetatable({}, { __index = source })
|
||||
self.your_awesome_variable = 1
|
||||
return self
|
||||
_G.vimrc = _G.vimrc or {}
|
||||
_G.vimrc.cmp = _G.vimrc.cmp or {}
|
||||
_G.vimrc.cmp.lsp = function()
|
||||
cmp.complete({
|
||||
config = {
|
||||
sources = {
|
||||
{ name = 'nvim_lsp' }
|
||||
}
|
||||
}
|
||||
})
|
||||
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' },
|
||||
_G.vimrc.cmp.snippet = function()
|
||||
cmp.complete({
|
||||
config = {
|
||||
sources = {
|
||||
{ name = 'vsnip' }
|
||||
}
|
||||
}
|
||||
})
|
||||
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())
|
||||
vim.cmd([[
|
||||
inoremap <C-x><C-o> <Cmd>lua vimrc.cmp.lsp()<CR>
|
||||
inoremap <C-x><C-s> <Cmd>lua vimrc.cmp.snippet()<CR>
|
||||
]])
|
||||
```
|
||||
|
||||
You can also create a source by Vim script like this (This is useful to support callback style plugins).
|
||||
### Full managed completion behavior.
|
||||
|
||||
- If you want to return `boolean`, you must return `v:true`/`v:false` instead of `0`/`1`.
|
||||
```lua
|
||||
local cmp = require('cmp')
|
||||
|
||||
```vim
|
||||
let s:source = {}
|
||||
cmp.setup {
|
||||
completion = {
|
||||
autocomplete = false, -- disable auto-completion.
|
||||
}
|
||||
}
|
||||
|
||||
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())
|
||||
_G.vimrc = _G.vimrc or {}
|
||||
_G.vimrc.cmp = _G.vimrc.cmp or {}
|
||||
_G.vimrc.cmp.on_text_changed = function()
|
||||
local cursor = vim.api.nvim_win_get_cursor(0)
|
||||
local line = vim.api.nvim_get_current_line()
|
||||
local before = string.sub(line, 1, cursor[2] + 1)
|
||||
if before:match('%s*$') then
|
||||
cmp.complete() -- Trigger completion only if the cursor is placed at the end of line.
|
||||
end
|
||||
end
|
||||
vim.cmd([[
|
||||
augroup vimrc
|
||||
autocmd
|
||||
autocmd TextChanged,TextChangedI,TextChangedP * call luaeval('vimrc.cmp.on_text_changed()')
|
||||
augroup END
|
||||
]])
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
122
doc/cmp.txt
122
doc/cmp.txt
@@ -14,6 +14,7 @@ Command |cmp-command|
|
||||
Highlight |cmp-highlight|
|
||||
Autocmd |cmp-autocmd|
|
||||
Config |cmp-config|
|
||||
Develop |cmp-develop|
|
||||
FAQ |cmp-faq|
|
||||
|
||||
|
||||
@@ -25,6 +26,8 @@ This is nvim-cmp's document.
|
||||
|
||||
1. This docs uses the type definition notation like `{lsp,cmp,vim}.*`
|
||||
- You can find it `../lua/cmp/types/init.lua`.
|
||||
2. The advanced configuration is noted in wiki.
|
||||
- https://github.com/hrsh7th/nvim-cmp/wiki
|
||||
|
||||
|
||||
|
||||
@@ -34,6 +37,7 @@ Concept *cmp-concept*
|
||||
- Full support for LSP completion related capabilities
|
||||
- Powerful customizability via Lua functions
|
||||
- Smart handling of key mapping
|
||||
- No flicker
|
||||
|
||||
|
||||
|
||||
@@ -475,9 +479,127 @@ experimental.native_menu~
|
||||
|
||||
|
||||
|
||||
==============================================================================
|
||||
Develop *cmp-develop*
|
||||
|
||||
Create custom source~
|
||||
|
||||
NOTE:
|
||||
1. The `complete` method is required. Others can be ommited.
|
||||
2. The `callback` argument must always be called.
|
||||
3. You can use only `require('cmp')` in custom source.
|
||||
4. If the LSP spec was changed, nvim-cmp will follow it without any announcement.
|
||||
5. You should read ./lua/cmp/types and https://microsoft.github.io/language-server-protocol/specifications/specification-current
|
||||
6. Please add the `nvim-cmp` topic for github repo.
|
||||
|
||||
You can create custom source like the following example.
|
||||
|
||||
>
|
||||
local source = {}
|
||||
|
||||
---Return this source is available in current context or not. (Optional)
|
||||
---@return boolean
|
||||
function source:is_available()
|
||||
return true
|
||||
end
|
||||
|
||||
---Return the debug name of this source. (Optional)
|
||||
---@return string
|
||||
function source:get_debug_name()
|
||||
return 'debug name'
|
||||
end
|
||||
|
||||
---Return keyword pattern for triggering completion. (Optional)
|
||||
---If this is ommited, nvim-cmp will use default keyword pattern. See |cmp-config.completion.keyword_pattern|
|
||||
---@return string
|
||||
function source:get_keyword_pattern()
|
||||
return [[\k\+]]
|
||||
end
|
||||
|
||||
---Return trigger characters for triggering completion. (Optional)
|
||||
function source:get_trigger_characters()
|
||||
return { '.' }
|
||||
end
|
||||
|
||||
---Invoke completion. (Required)
|
||||
---@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. (Optional)
|
||||
---@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 after item was accepted.
|
||||
---@param completion_item lsp.CompletionItem
|
||||
---@param callback fun(completion_item: lsp.CompletionItem|nil)
|
||||
function source:execute(completion_item, callback)
|
||||
callback(completion_item)
|
||||
end
|
||||
|
||||
---Register custom source to nvim-cmp.
|
||||
require('cmp').register_source('month', source.new())
|
||||
<
|
||||
|
||||
|
||||
==============================================================================
|
||||
FAQ *cmp-faq*
|
||||
|
||||
How to disable auto-completion?~
|
||||
How to use nvim-cmp as like omnifunc?~
|
||||
|
||||
You can disable auto-completion like this.
|
||||
>
|
||||
cmp.setup {
|
||||
...
|
||||
completion = {
|
||||
autocomplete = false
|
||||
}
|
||||
...
|
||||
}
|
||||
<
|
||||
And you can invoke completion manually.
|
||||
>
|
||||
inoremap <C-x><C-o> <Cmd>lua require('cmp').complete()<CR>
|
||||
<
|
||||
|
||||
How to disable nvim-cmp on the specific buffer?~
|
||||
How to setup on the specific buffer?~
|
||||
|
||||
You can setup buffer specific configuration like this.
|
||||
>
|
||||
autocmd FileType markdown * lua require('cmp').setup.buffer {
|
||||
\ sources = {
|
||||
\ { name = 'path' },
|
||||
\ { name = 'buffer' },
|
||||
\ }
|
||||
\ }
|
||||
<
|
||||
|
||||
How to customize menu appearance?~
|
||||
|
||||
You can see the nvim-cmp wiki (https://github.com/hrsh7th/nvim-cmp/wiki).
|
||||
|
||||
|
||||
|
||||
==============================================================================
|
||||
vim:tw=78:ts=4:et:ft=help:norl:
|
||||
|
||||
|
||||
Reference in New Issue
Block a user