Chapter 18.Table of ContentsCheatsheet

Multiple Cursors

If you’re a hardcore Visual Studio Code user, chances are you use multiple cursors. VSCodeVim offers an experimental support for multiple cursors in Visual and Normal modes. Using this experimental feature (that is enabled by default), you can spawn multiple cursors and then use operators to unleash the power of Vim in multiple locations at once. WOW!

If you want to add multiple cursors based on word search you need to:

  1. Move the cursor on top of a word in your code.
  2. Type <CMD-D> (CTRL-D on Windows/Linux) or gb to add another cursor. This puts Vim into Visual mode and ready to operate on the word you have selected.
  3. Type <CMD-D> (CTRL-D on Windows/Linux) or gb to continue adding cursors until you’re done.
  4. Now you can perform an action in Visual mode (delete, change, etc) or,
  5. Go back to Normal mode with <ESC> and type any Normal mode command keeping the multiple cursors.

A possible use case for multiple cursors would be to rename something. Imagine that you have a function that renames things, like properties within objects in JavaScript. Let’s say that you have this beautiful object that represents me:

const jaime = {
  name: 'Jaime',
  attributes: ['handsome', 'smart', 'witty']
};

And some day you just get tired of all this self-adoration and narcissism and want vengeance. So you decide to rename my property attributes to lackingAttributes:

rename(jaime, 'attributes', 'lackingAttributes');

Such a function (that you must now promise never to write in any program ever) could look like this:

function rename(obj, name, newName){
  Object.defineProperty(obj, newName, { 
                  value: obj[name], 
                  enumerable: true,
                  writable: true,
                  configurable: true
  });
  delete obj[name];
}

The name property isn’t descriptive enough so we want to rename it to oldName because this example couldn’t be more meta than this. We can achieve this renaming using multiple cursors:

  1. Move your cursor on top of name with the search operator /name<Enter>,
  2. Type gb thrice to create three cursors on top of each name variable,
  3. You’re now in Visual mode with three separate selections,
  4. Type coldName<ESC> to change each occurrence of name for oldName.
  5. You still have three cursors and are now in Normal mode. You can continue tinkering around or remove all extra cursors typing <ESC> one more time.

Alternatively, you could have typed <ESC> on step 4 and then used the following Normal mode command: ciwoldName<ESC>. The difference being that Visual mode operates on the current text selection (the words) and Normal mode lets you operate on any text selection using arbitrary motions based on the position of the multiple cursors.

Add Multiple Cursors On Consecutive Lines

If you want to extend your cursors up or down in consecutive lines, then the best approach is to rely in Visual-block mode:

  1. Type <CTRL-V> to jupm into Visual-block mode.
  2. Use j, k to select a rectangle of text downwards or upwards respectively.
  3. Type I to insert or A to append, then type some text and press <ESC>.
  4. Alternatively, use any Normal mode commands to operate on the selected text in each line.

How can this be useful, you ask? Imagine a list of the things you would need to survive a zombie apocalypse:

towel
wrench
shotgun
axe
rusty broadsword
sausage
chain-saw

And now, because two heads are better than one, and you may have forgotten something important, you need to put that list on a website to share with other zombie apocalypse survivors to-be. Website means HTML, means semantic HTML elements, means that we need to wrap those items in the correct format. Each valuable object will be wrapped in a <li> (list item) element, and all of them will go inside a <ol> (ordered list) because order is important and, when push comes to shove, I’d much rather have a toweltowel than a chain-saw.

So, assuming the cursor is on top of the first letter of that list:

v
towel

You would type:

  1. CTRL-V to go into Visual-block mode,
  2. then j down until the end of the list,
  3. followed by I to go into Insert mode at the beginning of the block,
  4. and finally <li> and <ESC> to leave Insert mode

Resulting in the following:

<li>towel
<li>wrench
<li>shotgun
<li>axe
<li>rusty broadsword
<li>sausage
<li>chain-saw

Now repeat the process to add the closing tag:

  1. CTRL-V to go into Visual-block mode,
  2. then j down until the end of the list,
  3. now use the $ motion to move all the cursors to the end of each line,
  4. type A to go into Insert mode at the end of the block,
  5. and finally </li> and <ESC>
<li>towel</li>
<li>wrench</li>
<li>shotgun</li>
<li>axe</li>
<li>rusty broadsword</li>
<li>sausage</li>
<li>chain-saw</li>

  1. 42

Jaime González García

Written by Jaime González García , dad, husband, software engineer, ux designer, amateur pixel artist, tinkerer and master of the arcane arts. You can also find him on Twitter jabbering about random stuff.Jaime González García