LSP Features
Comprehensive breakdown of all Language Server Protocol features and capabilities in coc.nvim.
Workspace support
Workspace folders
Unlike VS Code, which prompts you to open folders, coc.nvim resolves workspace folders from the paths of attached documents. A list of file or folder names is used to find the workspace folder. The patterns can come from:
b:coc_root_patternsfor the current buffer.- The
rootPatternsfield of the language server used by the current buffer. rootPatternscontributed by coc.nvim extensions.- The
workspace.rootPatternssetting, which defaults to[".git", ".hg", ".projections.json"].
The workspace folder is resolved from Vim's current working directory first by default, then
from the top directory down to the parent directory of the current file. The
workspace.workspaceFolderCheckCwd, workspace.workspaceFolderFallbackCwd, and
workspace.bottomUpFiletypes settings control that behavior.
Use workspace.ignoredFiletypes and workspace.ignoredFolders to exclude filetypes or
folders. Ignored folder entries support environment variable expansion and
minimatch patterns.
To configure root patterns for a specific filetype, use an autocommand:
| 1 | autocmd FileType python let b:coc_root_patterns = ['.git', '.env'] |
For performance reasons, the user's home directory is never considered a workspace folder. Because workspace folders are resolved from opened files, open at least one file in each folder that you want to add to a multi-root workspace.
Manage workspace folders
Use :CocList folders to open the workspace folder list; its delete and edit actions
can update the current folders. Use :CocCommand workspace.workspaceFolders to echo them, or
:echo coc#util#root_patterns() to inspect the root patterns for the current buffer.
Persist workspace folders
coc.nvim stores workspace folders in g:WorkspaceFolders. To restore them with a Vim session,
add set sessionoptions+=globals to your vimrc.
Workspace edit ~
A workspace edit is used to apply changes to multiple buffers and/or files. The edit can contain document edits and file operations (including file creation, file/directory deletion, and file/directory renaming).
If the edit fails to apply, coc.nvim reverts the changes (including document edits and file operations) made previously.
Files that aren't loaded are loaded with the tab drop command, configured by
coc-config-workspace-openResourceCommand.
To undo and redo the workspace edit just applied, use the
:CocCommand workspace.undo and :CocCommand workspace.redo commands.
To inspect the previous workspace edit, use :CocCommand workspace.inspectEdit;
in the opened buffer, use <CR> to jump to the change position under the
cursor.
Rename current file ~
To move or rename the current file, it's recommended to use
:CocCommand workspace.renameCurrentFile, which makes Vim reload the current
buffer and sends the expected events to language servers.
Output channels ~
Output channels show logs for you to inspect. Use the workspace.showOutput
command to open an output channel.
Builtin channels:
watchmanshows watchman related logs.extensionsshows extension install and update related logs.
coc-languageserver and coc-extensions could contribute output channels.
File system watch
Watchman is used by coc.nvim to provide
file change detection to extensions and language servers. The watchman
command is detected from your $PATH; the feature silently fails when
watchman isn't working.
Watchman automatically watches coc-workspace-folders for file events by
default.
Use the following command to open the output channel of watchman:
| 1 | :CocCommand workspace.showOutput watchman |
Use configuration coc-config-fileSystemWatch to change the behavior of file
system watching.
Note: The default filesystem watch limit can be easily exceeded for many projects; check out Watchman system-specific preparation
LSP features
Most features of LSP 3.18 are supported. Check out the specification at Language Server Protocol specification
Features not supported
- Telemetry.
- Inline values for debugger.
- Notebook document.
LSP features only work with attached documents; see coc-document-attached.
To check the providers that exist for the current buffer, use the
:CocCommand document.checkBuffer command or the CocHasProvider() API.
For historical reasons, some features work automatically by default, while others don't.
Features automatically work by default
- Trigger completion after text insert
coc-completion. - Trigger inline completion
coc-inlineCompletion - Diagnostics refresh
coc-diagnostics. - Pull diagnostics
coc-pullDiagnostics. - Trigger signature help
coc-signature. - Inlay hints
coc-inlayHint
Most features can be toggled through coc-configuration and some Vim
variables.
To disable all features that automatically work, use configuration:
| 1 | "suggest.autoTrigger": "none", |
| 2 | "diagnostic.enable": false, |
| 3 | "pullDiagnostic.onChange": false, |
| 4 | "signature.enable": false, |
| 5 | "inlayHint.enable": false, |
Features that must be enabled by configuration
- Semantic highlights
coc-semantic-highlights. - Document color highlights
coc-document-colors. - Code lens,
coc-code-lens - Linked editing,
coc-linked-editing. - Format on type, enabled by
coc-preferences-formatOnType - Format on save, enabled by
coc-preferences-formatOnSave.
Features requested by user
- Location-related features (including definitions, references, etc.)
coc-locations - Invoke code action
coc-code-actions. - Show call hierarchy tree
coc-callHierarchy. - Show type hierarchy tree
coc-typeHierarchy - Format, range format, and format on type
coc-format. - Highlight same symbol ranges
coc-document-highlights. - Outline of document symbols
coc-outlineandcoc-list-symbols. - Show hover information
coc-hover. - Rename symbol under cursor
coc-rename. - Open link under cursor
coc-document-links. - Selection range
coc-selection-range - Create folding ranges
coc-fold.
For convenience, some actions have associated coc-key-mappings provided.
Prefer CocAction() for more options.
Features triggered by the language server
- Show message notification (use
coc-notification). - Show message request (use
coc-dialog-menu). - Log message notification (use
:CocCommand workspace.showOutputto show output). - Show document request (opened by Vim or your browser for URLs).
- Work done progress (use
coc-notification).
To make coc.nvim provide LSP features for your languages, check out Language server guide
To debug issues with a language server, check out Language server debugging guide
Document
An associated document is created when a buffer is created and disposed when the buffer is unloaded.
Attached document
An attached document means coc.nvim automatically synchronizes the lines of Vim's buffer with the associated document.
Only attached documents are synchronized with language servers and therefore LSP features can only be provided for the attached buffer.
A buffer may not be attached for the following reasons:
- The 'buftype' is neither <empty> nor 'acwrite' (this can be bypassed with
b:coc_force_attach). - Buffer variable
b:coc_enabledis0. - The byte length of the buffer exceeds
coc-preferences-maxFileSize. - The buffer is used for the command line window.
Use CocAction('ensureDocument') or :CocCommand document.checkBuffer to
check the attached state of the current buffer.
Filetype map
Some filetypes are mapped to others to match the languageId used by VSCode, including:
- javascript.jsx -> javascriptreact
- typescript.jsx -> typescriptreact
- typescript.tsx -> typescriptreact
- tex -> latex
Use g:coc_filetype_map to create additional filetype maps.
Use :CocCommand document.echoFiletype to echo mapped filetype of current
document.
Note: make sure to use mapped filetypes in configurations that expect filetypes.
Hover
The hover feature provides information at a given text document position, normally including type information and documentation for the current symbol.
Hover functions
CocAction('doHover')Show hover information at cursor position.CocAction('definitionHover')Show hover information with definition context at the cursor position.CocAction('getHover')Get hover documentation at the cursor position.
Hover key-mapping example
| 1 | nnoremap <silent> K :call ShowDocumentation()<CR> |
| 2 | " Show hover when provider exists, fallback to vim's builtin behavior. |
| 3 | function! ShowDocumentation() |
| 4 | if CocAction('hasProvider', 'hover') |
| 5 | call CocActionAsync('definitionHover') |
| 6 | else |
| 7 | call feedkeys('K', 'in') |
| 8 | endif |
| 9 | endfunction |
Completion
Vim's builtin completion is not used. The default completion works like completion in VSCode:
- Completion is automatically triggered by default.
- Selection is enabled by default, use
coc-config-suggest-noselectto disable default selection. - When selection is enabled and no preselect item exists, the first complete
item will be selected (depends on
coc-config-suggest-selection). - Snippet expansion and additional edits only work after confirming
completion with
coc#pum#confirm(). 'completeopt'is not used, and the APIs of the builtin popupmenu don't work.
Default Key-mappings
To make the new completion work like the builtin completion without any additional configuration, the following key-mappings are used when the {lhs} is not mapped:
<C-n>navigate to next complete item or inline complete item.<C-p>navigate to previous complete item or inline complete item.<down>navigate to next complete item (without word insert) or inline complete item.<up>navigate to previous complete item (without word insert) or inline complete item.<C-e>cancel the completion or inline completion.<C-y>confirm completion or accept current inline complete item.
Use <PageDown> and <PageUp> to scroll:
| 1 | inoremap <silent><expr> <PageDown> coc#pum#visible() ? coc#pum#scroll(1) : "\<PageDown>" |
| 2 | inoremap <silent><expr> <PageUp> coc#pum#visible() ? coc#pum#scroll(0) : "\<PageUp>" |
Note: <CR> and <Tab> are not remapped by coc.nvim.
Related variables
- Disable completion for buffer:
b:coc_suggest_disable - Disable specific sources for buffer:
b:coc_disabled_sources - Disable words for completion:
b:coc_suggest_blacklist - Add additional keyword characters:
b:coc_additional_keywords, the buffer keyword characters are used for filtering completion items instead of triggering completion, see'iskeyword'.
Related functions
- Trigger completion with options:
coc#start(). - Trigger completion refresh:
coc#refresh(). - Select and confirm completion:
coc#pum#select_confirm(). - Check if the custom popupmenu is visible:
coc#pum#visible(). - Select the next completion item:
coc#pum#next(). - Select the previous completion item:
coc#pum#prev(). - Cancel completion and reset trigger text:
coc#pum#cancel(). - Confirm completion:
coc#pum#confirm(). - Close the popupmenu only:
coc#pum#stop(). - Get information about the popupmenu:
coc#pum#info(). - Select specific completion item:
coc#pum#select(). - Insert word of selected item and finish completion:
coc#pum#insert(). - Insert one more character from current complete item:
coc#pum#one_more(). - Scroll popupmenu:
coc#pum#scroll().
Customize completion
Use coc-config-suggest to change the completion behavior.
Use 'pumwidth' to configure the minimal width of the popupmenu and
'pumheight' for its maximum height.
Related Highlight groups:
CocPum for highlight groups of customized pum.
CocSymbol for kind icons.
CocMenuSel for background highlight of selected item.
CocPumVirtualText for virtual text when enabled by
coc-config-suggest-virtualText.
Note: background, border, title and winblend are configured by
coc-config-suggest-floatConfig.
Example user key-mappings
Note: use the :verbose imap command to check the current insert key-mappings
when your key-mappings don't work.
Use <tab> and <S-tab> to navigate completion list:
| 1 | function! CheckBackspace() abort |
| 2 | let col = col('.') - 1 |
| 3 | return !col || getline('.')[col - 1] =~ '\s' |
| 4 | endfunction |
| 5 | |
| 6 | " Insert <tab> when previous text is space, refresh completion if not. |
| 7 | inoremap <silent><expr> <TAB> |
| 8 | \ coc#pum#visible() ? coc#pum#next(1): |
| 9 | \ CheckBackspace() ? "\<Tab>" : |
| 10 | \ coc#refresh() |
| 11 | inoremap <expr><S-TAB> coc#pum#visible() ? coc#pum#prev(1) : "\<C-h>" |
| 12 | |
| 13 | Use <c-space> to trigger completion: > |
| 14 | |
| 15 | if has('nvim') |
| 16 | inoremap <silent><expr> <c-space> coc#refresh() |
| 17 | else |
| 18 | inoremap <silent><expr> <c-@> coc#refresh() |
| 19 | endif |
Use <CR> to confirm completion, use:
| 1 | inoremap <expr> <cr> coc#pum#visible() ? coc#pum#select_confirm() : "\<CR>" |
To make <CR> confirm the selected completion item or notify coc.nvim to format on enter, use:
| 1 | inoremap <silent><expr> <CR> coc#pum#visible() ? coc#pum#select_confirm() |
| 2 | \: "\<C-g>u\<CR>\<c-r>=coc#on_enter()\<CR>" |
| 3 | |
| 4 | Map <tab> for triggering completion, confirming completion, accepting inline |
| 5 | completion, and expanding and jumping snippets like VSCode: > |
| 6 | |
| 7 | inoremap <silent><expr> <TAB> |
| 8 | \ coc#pum#visible() ? coc#pum#select_confirm() : |
| 9 | \ coc#inline#visible() ? coc#inline#accept() : |
| 10 | \ coc#expandableOrJumpable() ? |
| 11 | \ "\<C-r>=coc#rpc#request('doKeymap', ['snippets-expand-jump',''])\<CR>" : |
| 12 | \ CheckBackspace() ? "\<TAB>" : |
| 13 | \ coc#refresh() |
| 14 | |
| 15 | function! CheckBackspace() abort |
| 16 | let col = col('.') - 1 |
| 17 | return !col || getline('.')[col - 1] =~# '\s' |
| 18 | endfunction |
| 19 | |
| 20 | let g:coc_snippet_next = '<tab>' |
Note: the coc-snippets extension is required for this to work.
Highlights of coc.nvim's completion
- Full LSP completion support, especially snippet and
additionalTextEditfeatures. - Completion resolving on completion item change: completion items are resolved asynchronously as they change, and the detail and documentation are shown in a float window when possible.
- Asynchronous and parallel completion requests: unless you use vim sources, vim will never be blocked.
- Incomplete and cancellation request support: only incomplete completion requests are triggered when filtering completion items, and cancellation requests are sent to servers only when necessary.
- Real-time buffer keywords: buffer keywords are generated from only the changed lines on buffer change. In addition, the Locality bonus feature from VSCode is enabled by default.
- Filter completion items when possible: when you fuzzy-filter completion items, coc.nvim filters them when possible, which makes it much faster.
Trigger mode of completion
There are 3 different trigger modes:
always(the default): triggers completion when a letter is inserted or whentriggerCharacters(or a trigger pattern match) defined by the currently activated sources is found.trigger: only triggers completion when you typetriggerCharacters(or a trigger pattern match) defined by the completion sources.none: disables automatic completion triggering; you will have to trigger completion manually.
Much of the completion behavior can be changed via the configuration file; check out :h coc-config-suggest for details.
Completion sources
Use the :CocList sources command to get the current completion source list.
Bundled sources
| Name | Description |
|---|---|
around | Words of the current buffer. |
buffer | Words of other open buffers. |
file | Filename completion, auto-detected. |
The shortcut shown in the completion menu defaults to the first three characters of the source name; customize it with coc.source.{name}.shortcut.
Configuring sources
You can configure completion sources with coc-settings.json:
"coc.source.{name}.enable": controls whether the source is enabled."coc.source.{name}.shortcut": the shortcut shown in the completion menu."coc.source.{name}.priority": priority of the source; lower-priority sources are sorted after higher-priority sources when they have the same score."coc.source.{name}.disableSyntaxes": syntax names used to disable the source for completion, e.g.["comment", "string"]."coc.source.buffer.ignoreGitignore": ignore git-ignored files for buffer words; defaults totrue."coc.source.file.trimSameExts": filename extensions whose names are trimmed in file completion; defaults to[".ts", ".js"]."coc.source.file.ignoreHidden": ignore hidden files in completion; defaults totrue.coc.source.file.ignorePatterns: patterns ignored by the matcher module; defaults to[].
More sources
- coc-sources: includes some common completion source extensions.
- coc-neco: viml completion support.
- coc-snippets: snippet solution for coc.nvim.
- coc-vimtex: vimtex integration.
- coc-neoinclude: neoinclude integration.
- coc-lbdbq: email address completion.
- coc-browser: web browser word completion.
- coc-github-users: GitHub username completion.
- coc-db: Database completion.
- sphinx.nvim: Source for Sphinx's cross-referencing roles.
Inline completion
Inline completion is a smart, lightweight alternative to traditional IntelliSense, offering faster, context-aware suggestions without disrupting your workflow. Inline completion is automatically triggered after document contents synchronize in insert mode by default.
Use the :CocCommand document.checkInlineCompletion command to check the
inline completion feature of the current buffer.
Default Key-mappings
Inline completion and default completion share default key mappings for
navigation and finish actions; see coc-completion-default. To accept inline
completion when the popup menu is visible, finish the completion first or use
coc#inline#accept().
Related functions
- Trigger inline completion:
coc#inline#trigger(). - Check if inline completion visual text exists:
coc#inline#visible(). - Cancel inline completion:
coc#inline#cancel(). - Accept inline completion:
coc#inline#accept(). - Navigate to next:
coc#inline#next(). - Navigate to previous:
coc#inline#prev().
Customize completion
Use coc-config-inlineSuggest to change the inline completion behavior.
To disable inline completion for special buffers, use language overridable
configuration in coc-settings.json like:
| 1 | "[javascript][typescript]": { |
| 2 | "inlineSuggest.autoTrigger": false |
| 3 | } |
This only disables auto-trigger. Alternatively, use b:coc_inline_disable to
disable inline completion triggering completely.
Related Highlight groups:
CocInlineVirtualText for virtual text highlight.
CocInlineAnnotation for annotation highlight.
Next edit
Extensions can register a generic NextEditProvider with
languages.registerNextEditProvider(). Providers return versioned insertion,
replacement, or deletion candidates. Candidates are previewed without changing
the buffer; accepting an off-cursor candidate first jumps to it, and accepting
again applies it. A visible inline completion always has priority.
Functions
- Trigger:
coc#nextedit#trigger(). - Check availability:
coc#nextedit#available(). - Check preview visibility:
coc#nextedit#visible(). - Accept:
coc#nextedit#accept(). - Cancel:
coc#nextedit#cancel(). - Next/previous candidate:
coc#nextedit#next()andcoc#nextedit#prev().
No default mapping is installed. A priority-preserving Insert-mode example is:
| 1 | inoremap <silent><expr> <Tab> |
| 2 | \ coc#pum#visible() ? coc#pum#next(1) : |
| 3 | \ coc#inline#visible() ? coc#inline#accept() : |
| 4 | \ coc#nextedit#available() ? coc#nextedit#accept() : |
| 5 | \ "\<Tab>" |
Diagnostics support
Diagnostics of coc.nvim are automatically refreshed in the UI by default;
check out coc-config-diagnostic for available configurations.
Note: most language servers only send diagnostics for opened buffers for performance reasons; some lint tools can provide diagnostics for all files in the workspace.
See coc-highlights-diagnostics for diagnostic related highlight groups.
Changes on diagnostics refresh ~
- Add highlights for diagnostic ranges and virtual text (when enabled on
neovim or vim >= 9.0.0067), see
coc-highlights-diagnostics. - Add diagnostic signs to 'signcolumn', use
set signcolumn=yesto avoid unnecessary UI refresh. - Update variable
b:coc_diagnostic_info. - Refresh related
location-listwhich was opened by:CocDiagnostics.
Diagnostics are not refreshed when the buffer is hidden, and refresh in insert mode is disabled by default.
See coc-highlights-diagnostics for highlight groups used by diagnostics.
Enable and disable diagnostics ~
Use coc-config-diagnostic-enable to toggle diagnostics feature.
Use CocAction('diagnosticToggle') for enable/disable diagnostics feature.
Use CocAction('diagnosticToggleBuffer') for enable/disable diagnostics of
current buffer.
Show diagnostic messages ~
Diagnostic messages are automatically shown/hidden when the diagnostics under the cursor position change (using a float window/popup when possible) by default.
To manually refresh diagnostic messages, use <Plug>(coc-diagnostic-info)
and CocAction('diagnosticPreview').
Jump between diagnostics ~
Use key-mappings:
| 1 | [`<Plug>(coc-diagnostic-next)`](#plugcoc-diagnostic-next) jump to diagnostic after cursor position. |
| 2 | [`<Plug>(coc-diagnostic-prev)`](#plugcoc-diagnostic-prev) jump to diagnostic before cursor position. |
| 3 | [`<Plug>(coc-diagnostic-next-error)`](#plugcoc-diagnostic-next-error) jump to next error. |
| 4 | [`<Plug>(coc-diagnostic-prev-error)`](#plugcoc-diagnostic-prev-error) jump to previous error. |
A diagnostic may have a related location; to jump to it, use:
| 1 | :CocCommand workspace.diagnosticRelated |
Check diagnostics ~
Use coc-list-diagnostics to open coc-list with all available diagnostics.
Use the CocAction('diagnosticList') API to get a list of all diagnostics.
Use :CocDiagnostics to open vim's location list with diagnostics of current
buffer. To automatically close the location list window, use the
CocDiagnosticChange autocommand with CocAction('diagnosticList').
Pull diagnostics support
Diagnostics are pulled for visible documents when supported by the language server. Pull for workspace diagnostics is also enabled by default.
Document diagnostics are pulled on change by default, and can be configured to be pulled on save.
Check out coc-config-pullDiagnostic for related configurations.
Locations support
There are different kinds of locations, including "definitions", "declarations", "implementations", "typeDefinitions" and "references".
Key-mappings for invoke locations request ~
<Plug>(coc-definition)<Plug>(coc-declaration)<Plug>(coc-implementation)<Plug>(coc-type-definition)<Plug>(coc-references)<Plug>(coc-references-used)
An error is shown when the buffer isn't attached coc-document-attached.
A message is shown when no result is found.
Location jump behavior ~
When only one location is returned, it's opened with the command specified by
coc-preferences-jumpCommand ("edit" by default), and a context mark is added
with m', so you can jump back to the previous location with <C-o>.
When multiple locations are returned, coc-list-location is opened for
preview and further actions.
To use coc-list-location for a single location as well, use the APIs in
coc-locations-api instead of the key-mappings provided by coc.nvim.
To change the default options of coc-list-location or use another plugin for
the list of locations, see g:coc_enable_locationlist.
To use vim's quickfix for locations, use configuration
coc-preferences-useQuickfixForLocations.
To use vim's tag list for definitions, use CocTagFunc().
Related APIs ~
CocAction('jumpDefinition')Jump to definition locations.CocAction('jumpDeclaration')Jump to declaration locations.CocAction('jumpImplementation')Jump to implementation locations.CocAction('jumpTypeDefinition')Jump to type definition locations.CocAction('jumpReferences')Jump to references.CocAction('jumpUsed')Jump to references without declarations.CocAction('definitions')Get definition list.CocAction('declarations')Get declaration list.CocAction('implementations')Get implementation list.CocAction('typeDefinitions')Get type definition list.CocAction('references')Get reference list.
Send custom location requests to the language server:
Rename
Rename provides workspace-wide renaming of a symbol. A workspace edit
coc-workspace-edits is requested and applied to related buffers when
confirmed.
Check whether the current buffer has a rename provider with
:echo CocAction('hasProvider', 'rename').
Rename key-mappings
Rename functions
CocAction('rename')Rename the symbol under the cursor.CocAction('refactor')Open refactor buffer for all references (including definitions), recommended for function signature refactor.
Rename local variable
Use the :CocCommand document.renameCurrentWord command, which uses
coc-cursors to edit multiple locations at the same time and defaults to
word extraction when no rename provider exists.
Rename configuration
Use coc-preferences-renameFillCurrent to enable/disable populating prompt
window with current variable name.
Signature help
Signature help for functions is shown automatically when you type trigger characters defined by the provider; a floating window/popup shows the relevant documentation.
Use CocAction('showSignatureHelp') to trigger signature help manually.
Note: no error is thrown when a provider doesn't exist or the language server
returns nothing; use echo CocAction('hasProvider', 'signature') to check
whether a signature help provider exists.
Use coc-config-signature to change default signature help behavior.
CocFloatActive is used to highlight activated parameter part.
Inlay hint
Inlay hints are enabled for all filetypes by default and use Vim's virtual text feature. Vim9 or Neovim >= 0.10 is required to insert the virtual text at the correct position.
Note: you may need to configure an extension or language server for inlay hints to work.
To temporarily toggle inlay hints for a specific buffer, use the command:
| 1 | :CocCommand document.enableInlayHint {bufnr} |
| 2 | :CocCommand document.disableInlayHint {bufnr} |
| 3 | :CocCommand document.toggleInlayHint {bufnr} |
The current bufnr is used when {bufnr} isn't specified.
Change highlight group
Configure inlay hint support
Format
Some tools may reload the buffer from disk during formatting; coc.nvim only
applies TextEdit[] to the document.
Don't confuse this with Vim's indent feature; configure/fix the 'indentexpr'
of your buffer if the indent is wrong after character insert (coc-format-ontype
might help with the indent).
Format options
Buffer options that affect document format: 'eol', 'shiftwidth' and 'expandtab'.
b:coc_trim_trailing_whitespaceTrim trailing whitespace on a line.b:coc_trim_final_newlinesTrim all newlines after the final newline at the end of the file.
These options are converted to DocumentFormattingOptions and transferred to
the language server before formatting. Note: the language server may only
support some of these options.
Format full document
Choose "editor.action.formatDocument" from coc-list-commands.
Or use |CocAction('format')|, you can create a command like:
| 1 | command! -nargs=0 Format :call CocActionAsync('format') |
to format current buffer.
Format on type
Format on type can be enabled by coc-preferences-formatOnType.
Use :CocCommand document.checkBuffer to check whether a formatOnType
provider exists for the current buffer.
To format on <CR>, create key-mapping of <CR> that uses coc#on_enter().
If you don't like the behavior on typed bracket characters, configure
coc-preferences-bracketEnterImprove.
Format selected code
Use 'formatexpr' for specific filetypes:
| 1 | autocmd FileType typescript,json setl formatexpr=CocAction('formatSelected') |
So that gq works for formatting a range of lines.
Setup visual mode and operator key-mappings:
| 1 | xmap <leader>f <Plug>(coc-format-selected) |
| 2 | nmap <leader>f <Plug>(coc-format-selected) |
Format on save
To enable format on save, use configuration coc-preferences-formatOnSave.
Or create |BufWritePre| autocmd like:
| 1 | autocmd BufWritePre * call CocAction('format') |
Note: the operation must be synchronized; avoid using CocActionAsync().
To skip the autocommand, use :noa w to save the buffer.
The operation blocks Vim while running; to avoid blocking for too long, it's
canceled after 0.5s (configurable via coc-preferences-willSaveHandlerTimeout).
Code action
Code actions ask the language server to provide specific kinds of code changes.
Possible code action kinds:
quickfix— used for fixing diagnostics.refactor— used for code refactoring.source— code actions that apply to the entire file.organizeImport— organizes the import statements of the current document.
Key-mappings for code actions
<Plug>(coc-fix-current)Invoke quickfix action at current line if any.<Plug>(coc-codeaction-cursor)Choose code actions at cursor position.<Plug>(coc-codeaction-line)Choose code actions at current line.<Plug>(coc-codeaction)Choose code actions of current file.<Plug>(coc-codeaction-source)Choose source code action of current file.<Plug>(coc-codeaction-selected)Choose code actions from selected range.<Plug>(coc-codeaction-refactor)Choose refactor code action at cursor position.<Plug>(coc-codeaction-refactor-selected)Choose refactor code action with selected code.
Except for <Plug>(coc-fix-current), which invokes the code action directly,
coc-dialog-menu is shown to pick a specific code action.
To invoke the organize import action, use a command like:
| 1 | command! -nargs=0 OR :call CocAction('organizeImport') |
See |CocAction('organizeImport')| for details.
Related APIs ~
• |CocAction('codeActions')| • |CocAction('organizeImport')| • |CocAction('fixAll')| • |CocAction('quickfixes')| • |CocAction('doCodeAction')| • |CocAction('doQuickfix')| • |CocAction('codeActionRange')|
DOCUMENT HIGHLIGHTS
Document highlights are used to highlight the same symbols as the one under the cursor in the current document.
To enable highlight on CursorHold, create an autocmd like this:
| 1 | autocmd CursorHold * call CocActionAsync('highlight') |
See coc-config-documentHighlight for related configurations.
See coc-highlights-document for related highlight groups.
Note: no error is thrown when a provider doesn't exist or the language server
returns nothing with CocAction('highlight').
Install the coc-highlight extension if you want to highlight the same words
under the cursor without language server support.
To jump between previous/next symbol position, use
:CocCommand document.jumpToPrevSymbol and
:CocCommand document.jumpToNextSymbol
Document colors
Document colors add color highlights to Vim buffers. To enable document color
highlights, use coc-config-colors-enable.
Note: the highlights define GUI colors only, so make sure you have 'termguicolors' enabled (and that your terminal supports GUI colors) if you're using Vim in a terminal.
To pick a color from system color picker, use CocAction('pickColor') or
choose editor.action.pickColor from :CocCommand.
Note: pick color may not work on your system.
To change color presentation, use CocAction('colorPresentation') or choose
editor.action.colorPresentation from :CocCommand.
To toggle color highlight of current buffer, choose
document.toggleColors from :CocCommand
To highlights colors without languageservers, install github.com
Document links
Check whether the current buffer has a documentLink provider with
:echo CocAction('hasProvider', 'documentLink').
The highlight and tooltip of links can be configured via coc-config-links.
Use coc-list-links to manage list of links in current document.
Document link key-mappings
Document link functions
CocAction('openLink')Open link under cursor.CocAction('links')Get link list of current buffer.
Snippets support
coc.nvim's snippet engine supports both VSCode snippets and UltiSnips snippet formats.
Completion items with snippet format have labels ending with
coc-config-suggest-snippetIndicator (~ by default).
Confirm the completion with coc#pum#confirm() or coc#pum#select_confirm()
to expand the snippet and execute other possible actions of the selected
completion item.
Jump snippet placeholders
g:coc_snippet_next and g:coc_snippet_prev are used to jump between
placeholders in both select mode and insert mode, defaulting to <C-j> and
<C-k>. Buffer key-mappings are created when a snippet is activated and
removed when it's deactivated.
Deactivate snippet session
A snippet session is deactivated under the following conditions:
- The change affects the snippet and code outside.
- Autocmd
InsertEntertriggered outside snippet. - Jump to the final placeholder.
Use :CocOpenLog to check out the cancel reason.
Use CocAction('snippetCancel') to cancel a snippet session manually.
To load and expand custom snippets, install the coc-snippets extension with
the command:
| 1 | :CocInstall coc-snippets |
Nested snippets
Snippets can be nested; when you jump to a tabstop of the parent snippet, it's not possible to jump back again (this works like UltiSnips).
Related configurations
g:coc_snippet_prevg:coc_snippet_nextg:coc_selectmode_mappingcoc-config-suggest-snippetIndicatorcoc-config-suggest-preferCompleteThanJumpPlaceholdercoc-config-snippet-highlightcoc-config-snippet-statusTextcoc-config-snippet-nextPlaceholderOnDelete
Related functions
Related variables, highlights and autocmds: ~
g:coc_selected_textUsed for replace${VISUAL}and${TM_SELECTED_TEXT}placeholder of next expanded snippet.b:coc_snippet_activeCheck whether a snippet session is activated.CocJumpPlaceholderAutocmds triggered after placeholder jump.CocSnippetVisualFor highlight of current placeholders when the highlight is enabled.
Cursors support
Multiple cursor support is added to allow editing multiple locations at once.
A cursors session can be started in the following ways:
- Use command
:CocCommand document.renameCurrentWordto rename variable under cursor. - Use
<Plug>(coc-refactor)to opencoc-refactor-buffer. - Use
:CocSearchto open searched locations withcoc-refactor-buffer. - Use cursors related key-mappings to add text range, including
<Plug>(coc-cursors-operator),<Plug>(coc-cursors-word),<Plug>(coc-cursors-position)and<Plug>(coc-cursors-range) - Ranges can be added by the
editor.action.addRangescommand from coc extensions.
Default key-mappings when cursors are activated:
- <esc> Cancels the cursors session.
- <C-n> Jumps to the next cursors range.
- <C-p> Jumps to the previous cursors range.
Use coc-config-cursors to change cursors related key-mappings.
Use highlight group CocCursorRange to change default range highlight.
Use b:coc_cursors_activated to check if cursors session is activated.
A refactor buffer is a special buffer with coc-cursors enabled, normally
opened by CocAction('refactor') or :CocSearch. When the refactor buffer is
saved, related buffers and files are changed at once and workspace edits are
applied, which can be undone and redone; see coc-workspace-edits.
Check out coc-config-refactor for related configuration.
Use <CR> to open buffer at current position in split window. Use <Tab> to invoke the tab open or remove action for the current code chunk.
Symbols outline
Outline is a split window that renders the symbols of the current document as
a coc-tree.
To show and hide the outline of the current window, use
CocAction('showOutline') and
CocAction('hideOutline').
Outline view has w:cocViewId set to "OUTLINE".
The following outline features are supported:
- Start fuzzy filter by
coc-config-tree-key-activeFilter. - Automatic update after document change.
- Automatic reload when the buffer in the current window changes.
- Automatic cursor position tracking by default.
- Different filter modes that can be changed on the fly
coc-config-outline-switchSortKey. - Enable auto preview by
coc-config-outline-togglePreviewKey.
Outline tries to reload document symbols after 500ms when no provider is registered, which avoids the need to check for provider existence.
Check out coc-config-tree and coc-config-outline for available
configurations.
Check out CocTree and CocSymbol to customize highlights.
Use configuration "suggest.completionItemKindLabels" for custom icons.
To show outline for each tab automatically, use autocmd:
| 1 | autocmd VimEnter,Tabnew * |
| 2 | \ if empty(&buftype) | call CocActionAsync('showOutline', 1) | endif |
To close outline when it's the last window automatically, use
autocmd like:
| 1 | autocmd BufEnter * call CheckOutline() |
| 2 | function! CheckOutline() abort |
| 3 | if &filetype ==# 'coctree' && winnr('$') == 1 |
| 4 | if tabpagenr('$') != 1 |
| 5 | close |
| 6 | else |
| 7 | bdelete |
| 8 | endif |
| 9 | endif |
| 10 | endfunction |
Create a key-mapping to toggle outline, like:
| 1 | nnoremap <silent><nowait> <space>o :call ToggleOutline()<CR> |
| 2 | function! ToggleOutline() abort |
| 3 | let winid = coc#window#find('cocViewId', 'OUTLINE') |
| 4 | if winid == -1 |
| 5 | call CocActionAsync('showOutline', 1) |
| 6 | else |
| 7 | call coc#window#close(winid) |
| 8 | endif |
| 9 | endfunction |
Call hierarchy
A call hierarchy is a split coc-tree window with locations for the incoming
or outgoing calls of the function under the cursor position.
The call hierarchy window is opened by CocAction('showIncomingCalls') and
CocAction('showOutgoingCalls'). The tree view window has w:cocViewId set
to "CALLS".
Call hierarchy is configured by CocSymbol, coc-config-callHierarchy and
coc-config-tree.
Related ranges are highlighted with the CocSelectedRange highlight group in
the opened buffer.
coc-dialog-menu can be invoked with coc-config-tree-key-actions (defaults
to <tab>). Available actions:
- Dismiss.
- Open in new tab.
- Show Incoming Calls.
- Show Outgoing Calls.
Use <CR> in call hierarchy tree to open location in original window.
Type hierarchy
A type hierarchy is a split coc-tree window with locations for the super
types or sub types of the type at the current position.
The type hierarchy window is opened by CocAction('showSuperTypes') and
CocAction('showSubTypes'). The tree view window has w:cocViewId set to
"TYPES".
Type hierarchy is configured by CocSymbol, coc-config-typeHierarchy and
coc-config-tree.
Actions are the same as coc-callHierarchy.
Semantic highlights
Semantic tokens are used to add color information to a buffer based on language-specific symbol information.
Use coc-config-semanticTokens-enable to enable semantic tokens highlights.
Use :CocCommand semanticTokens.checkCurrent to check the semantic highlight
information of the current buffer.
To create custom highlights for symbol under cursor, follow these steps:
• Inspect semantic token by
| 1 | :CocCommand semanticTokens.inspect |
to check token type and token modifiers with current symbol.
• Create new highlight group by |highlight|, for example:
| 1 | :hi link CocSemDeclarationVariable MoreMsg |
• Refresh semantic highlight of current buffer by:
| 1 | :CocCommand semanticTokens.refreshCurrent |
• Clear semantic highlight by:
| 1 | " Clear semantic tokens highlight of current buffer |
| 2 | :CocCommand semanticTokens.clearCurrent |
| 3 | |
| 4 | " Clear semantic tokens highlight for all buffers |
| 5 | :CocCommand semanticTokens.clearAll |
See CocSem to customize semantic token highlight groups.
See coc-config-semanticTokens for related configurations.
Fold
Check whether the current buffer has a fold provider with
:echo CocAction('hasProvider', 'foldingRange').
Use CocAction('fold') to create folds by requesting the language server,
and create manual folds in the current window.
Selection range
Select the range forward or backward from the cursor position.
Check whether the current buffer has a selection range provider with
:echo CocAction('hasProvider', 'selectionRange').
Selection range key-mappings
<Plug>(coc-range-select)Select range forward.<Plug>(coc-range-select-backward)Select range backward.
Selection range function
CocAction('rangeSelect')Visual select previous or next selection range
Code lens
The code lens feature shows additional information above or after specific lines.
CodeLens isn't shown by default; use coc-config-codeLens-enable to enable
it. You may also need to enable the codeLens feature in the extension or
language server configuration.
Check whether the current buffer has a code lens provider with
:echo CocAction('hasProvider', 'codeLens').
To temporarily toggle codeLens of current buffer, use command
:CocCommand document.toggleCodeLens
To invoke command from codeLens, use <Plug>(coc-codelens-action).
Use CocCodeLens for the highlight of codeLens virtual text.
Code lenses are automatically requested on buffer create/change; check out
coc-config-codeLens for available configurations.
Linked editing
The linked editing feature enables editing multiple linked ranges at the same
time, for example HTML tags. Linked editing ranges are highlighted with
CocLinkedEditing when activated.
Check whether the current buffer has a linked editing provider with
:echo CocAction('hasProvider', 'linkedEditing').
Linked editing feature is disabled by default, use
coc-preferences-enableLinkedEditing to enable.