Jay Taylor's notes

back to listing index

terryma/vim-multiple-cursors: True Sublime Text style multiple selections for Vim

[web search]
Original source (github.com)
Tags: vim sublime-text-2 editor plugins to-revisit-later github.com
Clipped on: 2020-02-05

Skip to content
Image (Asset 1/8) alt= You have unread notifications
True Sublime Text style multiple selections for Vim
Vim script Ruby
Branch: master
New pull request
Clone or download
Latest commit 6ab4dc7 on Nov 9, 2019
Type Name Latest commit message Commit time
assets Cleanup documentation 2 years ago
autoload Fix typing leading insert mode characters 11 months ago
doc FAQ: add entry about <i> hanging in visual mode 3 months ago
plugin Changing defaults to g:multi_cursor_exit_from_insert_mode = 0 8 months ago
spec Typo in the tests 7 months ago
.gitignore Don't track doc/tags 7 years ago
.rspec Add behavior tests using vimrunner. Set up travis-ci. 7 years ago
.travis.yml Update CI to use modern infrastructure 4 years ago
CHANGELOG.md Fix plugin break in PASTE mode. This fixesThis commit closes issue #44. #44. 7 years ago
CONTRIBUTING.md Rename ISSUES.md to CONTRIBUTING.md 4 years ago
Gemfile Add behavior tests using vimrunner. Set up travis-ci. 7 years ago
Gemfile.lock Cleanup tests a bit 4 years ago
MIT-LICENSE.txt Add Vim doc, update README, and add LICENSE 7 years ago
README.md FAQ: add entry about <i> hanging in visual mode 3 months ago
Rakefile Fix regression on out of sync cursors. 7 years ago

README.md

vim-multiple-cursors

Image (Asset 4/8) alt=Contents

About

There have been many attempts at bringing Sublime Text's awesome multiple selection feature into Vim, but none so far have been in my opinion a faithful port that is simplistic to use, yet powerful and intuitive enough for an existing Vim user. vim-multiple-cursors is yet another attempt at that.

It's great for quick refactoring

Image (Asset 5/8) alt=Add a cursor to each line of your visual selection

Image (Asset 6/8) alt=Match characters from visual selection

Image (Asset 7/8) alt=Use the command to match regexp

Image (Asset 8/8) alt=Installation

Install using Pathogen, Vundle, Neobundle, vim-plug, or your favorite Vim package manager.

Requires vim 7.4 or newer for full functionality.

vim-plug instructions

  1. Paste this block into the top of ~/.vimrc.
call plug#begin()

Plug 'terryma/vim-multiple-cursors'

call plug#end()
  1. Start vim and execute :PlugInstall.

Quick Start

normal mode / visual mode

  • start: <C-n> start multicursor and add a virtual cursor + selection on the match
    • next: <C-n> add a new virtual cursor + selection on the next match
    • skip: <C-x> skip the next match
    • prev: <C-p> remove current virtual cursor + selection and go back on previous match
  • select all: <A-n> start multicursor and directly select all matches

You can now change the virtual cursors + selection with visual mode commands. For instance: c, s, I, A work without any issues. You could also go to normal mode by pressing v and use normal commands there.

At any time, you can press <Esc> to exit back to regular Vim.

NOTE: start with g<C-n> to match without boundaries (behaves like g* instead of *)

visual mode when multiple lines are selected

  • start: <C-n> add virtual cursors on each line

You can now change the virtual cursors with normal mode commands. For instance: ciw.

command

The command MultipleCursorsFind accepts a range and a pattern (regexp), it creates a visual cursor at the end of each match. If no range is passed in, then it defaults to the entire buffer.

Mapping

If you don't like the plugin taking over your key bindings, you can turn it off and reassign them the way you want:

let g:multi_cursor_use_default_mapping=0

" Default mapping
let g:multi_cursor_start_word_key      = '<C-n>'
let g:multi_cursor_select_all_word_key = '<A-n>'
let g:multi_cursor_start_key           = 'g<C-n>'
let g:multi_cursor_select_all_key      = 'g<A-n>'
let g:multi_cursor_next_key            = '<C-n>'
let g:multi_cursor_prev_key            = '<C-p>'
let g:multi_cursor_skip_key            = '<C-x>'
let g:multi_cursor_quit_key            = '<Esc>'

NOTE: Please make sure to always map something to g:multi_cursor_quit_key, otherwise you'll have a tough time quitting from multicursor mode.

Settings

Currently there are four additional global settings one can tweak:

g:multi_cursor_exit_from_visual_mode (Default: 0)

If set to 1, then pressing g:multi_cursor_quit_key in Visual mode will quit and delete all existing cursors, just skipping normal mode with multiple cursors.

g:multi_cursor_exit_from_insert_mode (Default: 0)

If set to 1, then pressing g:multi_cursor_quit_key in Insert mode will quit and delete all existing cursors, just skipping normal mode with multiple cursors.

g:multi_cursor_normal_maps (Default: see below)

{'@': 1, 'F': 1, 'T': 1, '[': 1, '\': 1, ']': 1, '!': 1, '"': 1, 'c': 1, 'd': 1, 'f': 1, 'g': 1, 'm': 1, 'q': 1, 'r': 1, 't': 1, 'y': 1, 'z': 1, '<': 1, '=': 1, '>': 1}

Any key in this map (values are ignored) will cause multi-cursor Normal mode to pause for map completion just like normal vim. Otherwise keys mapped in normal mode will "fail to replay" when multiple cursors are active. For example: {'d':1} makes normal-mode command dw work in multi-cursor mode.

The default list contents should work for anybody, unless they have remapped a key from an operator-pending command to a non-operator-pending command or vice versa.

These keys must be manually listed because vim doesn't provide a way to automatically see which keys start mappings, and trying to run motion commands such as j as if they were operator-pending commands can break things.

g:multi_cursor_visual_maps (Default: see below)

{'T': 1, 'a': 1, 't': 1, 'F': 1, 'f': 1, 'i': 1}

Same principle as g:multi_cursor_normal_maps

Interactions with other plugins

Multiple_cursors_before/Multiple_cursors_after (Default: nothing)

Other plugins may be incompatible in insert mode. That is why we provide hooks to disable those plug-ins when vim-multiple-cursors is active:

For example, if you are using Neocomplete, add this to your vimrc to prevent conflict:

function! Multiple_cursors_before()
  if exists(':NeoCompleteLock')==2
    exe 'NeoCompleteLock'
  endif
endfunction

function! Multiple_cursors_after()
  if exists(':NeoCompleteUnlock')==2
    exe 'NeoCompleteUnlock'
  endif
endfunction

Plugins themselves can register User autocommands on MultipleCursorsPre and MultipleCursorsPost for automatic integration.

Highlight

The plugin uses the highlight group multiple_cursors_cursor and multiple_cursors_visual to highlight the virtual cursors and their visual selections respectively. You can customize them by putting something similar like the following in your vimrc:

" Default highlighting (see help :highlight and help :highlight-link)
highlight multiple_cursors_cursor term=reverse cterm=reverse gui=reverse
highlight link multiple_cursors_visual Visual

FAQ

Q Pressing i after selecting words with C-n makes the plugin hang, why?

A When selecting words with C-n, the plugin behaves like in visual mode. Once you pressed i, you can still press I to insert text.

Q ALT+n doesn't seem to work in VIM but works in gVIM, why?

A This is a well known terminal/Vim issue, different terminal have different ways to send Alt+key. Try adding this in your .vimrc and make sure to replace the string:

if !has('gui_running')
  map "in Insert mode, type Ctrl+v Alt+n here" <A-n>
endif

Or remap the following:

g:multi_cursor_start_key
g:multi_cursor_select_all_key

Q CTRL+n doesn't seem to work in gVIM?

A Try setting set selection=inclusive in your ~/.gvimrc

A Alternatively, you can just temporarily disable exclusive selection whenever the plugin is active:

augroup MultipleCursorsSelectionFix
    autocmd User MultipleCursorsPre  if &selection ==# 'exclusive' | let g:multi_cursor_save_selection = &selection | set selection=inclusive | endif
    autocmd User MultipleCursorsPost if exists('g:multi_cursor_save_selection') | let &selection = g:multi_cursor_save_selection | unlet g:multi_cursor_save_selection | endif
augroup END

Q deoplete insert giberrish, how to fix this?

A use the Multiple_cursors functions, add this in your vimrc:

    func! Multiple_cursors_before()
      if deoplete#is_enabled()
        call deoplete#disable()
        let g:deoplete_is_enable_before_multi_cursors = 1
      else
        let g:deoplete_is_enable_before_multi_cursors = 0
      endif
    endfunc
    func! Multiple_cursors_after()
      if g:deoplete_is_enable_before_multi_cursors
        call deoplete#enable()
      endif
    endfunc

Q is it also working on Mac?

A On Mac OS, MacVim is known to work.

Q How can I select n keywords with several keystrokes? 200<C-n> does not work.

A You can use :MultipleCursorsFind keyword. I have this binding in my vimrc:

nnoremap <silent> <M-j> :MultipleCursorsFind <C-R>/<CR>
vnoremap <silent> <M-j> :MultipleCursorsFind <C-R>/<CR>

This allows one to search for the keyword using * and turn search results into cursors with Alt-j.

Contributing

Patches and suggestions are always welcome! A list of open feature requests can be found here.

Issue Creation

Contributor's time is precious and limited. Please ensure it meets the requirements outlined in CONTRIBUTING.md.

Pull Requests

Running the test suite requires ruby and rake as well as vim of course. Before submitting PR, please ensure the checks are passing:

cd vim-multiple-cursors/spec/
bundle exec rake

Contributors

This is a community supported project. Here is the list of all the Contributors

Credit

Obviously inspired by Sublime Text's multiple selection feature, also encouraged by Emac's multiple cursors implementation by Magnar Sveen