Skip to content

Multiple cursors support

年糕小豆汤 edited this page Aug 17, 2019 · 17 revisions

With the multiple cursors feature, you can change many places of current document at one time.

Multiple cursors are actually multiple text ranges.

The ranges are highlighted by CocCursorRange highlight group (linked to Search by default). To override the highlight, use command like:

hi CocCursorRange guibg=#b16286 guifg=#ebdbb2

in your .vimrc

Start multiple cursors session

There're some key-mappings for start multiple cursors:

  • <Plug>(coc-cursors-position) add current character range to cursors.
  • <Plug>(coc-cursors-word) add current word range to cursors.
  • <Plug>(coc-cursors-range) add current visual selected range to cursors.
  • <Plug>(coc-cursors-operator) use operator for add range to cursors.

You can cancel the range under cursor by trigger one of those key-mappings.

Example usage:

nmap <silent> <C-c> <Plug>(coc-cursors-position)
nmap <silent> <C-d> <Plug>(coc-cursors-word)
xmap <silent> <C-d> <Plug>(coc-cursors-range)
" use normal command like `<leader>xi(`
nmap <leader>x  <Plug>(coc-cursors-operator)

or use the following to add current to selection and go to next:

nmap <silent> <C-d> <Plug>(coc-cursors-word)*
xmap <silent> <C-d> y/\V<C-r>=escape(@",'/\')<CR><CR>gN<Plug>(coc-cursors-range)gn

Or more vscode like behavier:

nmap <expr> <silent> <C-d> <SID>select_current_word()
function! s:select_current_word()
  if !get(g:, 'coc_cursors_activated', 0)
    return "\<Plug>(coc-cursors-word)"
  endif
  return "*\<Plug>(coc-cursors-word):nohlsearch\<CR>"
endfunc

Or use internal command API to add ranges, like:

import {commands} from 'coc.nvim'
// hlRanges is a list of LSP Range
await commands.executeCommand('editor.action.addRanges', hlRanges)

Use vim script like:

call CocAction('runCommand', 'editor.action.addRanges', hlRanges)

Rename current variable

One common task is rename the variable name under cursor.

Use command :CocCommand document.renameCurrentWord to start cursors session with ranges contain current word.

Note: the word ranges are extracted from language server when possible, when language server not available, strict match of words in current buffer is used.

Make changes for cursors

When cursors session is activated, you can change one placeholder to reflect changes for all cursor ranges.

  • You can change the text any way you want to, like normal command or insert text.
  • You can change around the text by command like ysiw" (with tpope/vim-surround installed).
  • You can undo & redo the changes.
  • You can't insert new line, it would cancel cursors session.

Jump between ranges of cursors

  • Use "cursors.nextKey" to jump to next position of cursors range, default to <C-n>.
  • Use "cursors.previousKey" to jump to previous position of cursors range, default to <C-p>.

The key-mappings would be created when cursors session activated, and removed when session cancelled.

Cancel cursors session

Use "cursors.cancelKey" to cancel cursors session, default to <Esc>.

The session would also be canceled when buffer change can't be applied for ranges or the cursor jump to another window.

Use refactor action

Use <Plug>(coc-refactor) for create a refactor window of current symbol.

Note: it requires rename feature of language server to work.

When the window get opened, related ranges would be added to a new cursors session, you can:

  • Change the placeholder for rename.
  • Save the buffer for synchronize changes to related buffers.
  • Add or remove lines.
  • Press <CR> to open line under cursor in right split window.
  • Change content of related buffers, the changes would be synchronized to refactor buffer.
  • Fold the ranges by commands like zi.
Screen Shot 2019-07-26 at 7 11 52 PM

Available configurations for refactor:

  • refactor.openCommand: Open command for refactor window, default to vsplit.
  • refactor.beforeContext: Print num lines of leading context before each match, default to 3.
  • refactor.afterContext: Print num lines of trailing context after each match., default to 3.

Use CocSearch command

For rename variable across files in current cwd, use :CocSearch command which requires ripgrep to work.

Each range of lines would be added to refactor window asynchronously and matched ranges would be added to cursors session for rename.

Screen Shot 2019-07-26 at 7 25 53 PM

Tips:

  • Don't change the buffer when search is not finished.
  • Use <tab> to get available options after type :CocSearch command.
  • Use :CocSearch -w [word] for word match.

REPL

Clone this wiki locally