Practical Vim command workflow


In Vim, there’s a variety of commands that let you accomplish tasks in different ways. This can be overwhelming for beginners trying to figure out the most efficient keystrokes for editing. In this tutorial, I’ll share my approach to using Vim commands and offer some real life examples to help you improve your workflow.

Guidelines

Here are some general rules of my workflow:

  1. Don’t use mouse and arrow keys (unless you have a custom keyboard layout with arrows near the home row).
  2. Use relative jump (eg: 5k 12j) for vertical movement inside screen.
  3. Use CTRL-U CTRL-D CTRL-B CTRL-F gg G for vertical movement outside screen.
  4. Use word-motion (w W b B e E ge gE) for short distance horizontal movement.
  5. Use f F t T 0 ^ $ , ; for mid long distance horizontal movement.
  6. Use operator + motion/text-object (eg: ci{ d5j) whenever possible.

If you are not familiar with some of the commands and concepts, you can learn about them in Essential Vim commands for efficient text editing.

Examples

Here are 4 real situations I faced when creating a todo list website with javascript. I recommend you to think about how you would achieve the editing goal first and then see my approach.

Notes:

  • ^ or v points to the position of the cursor.
  • There are line number and relative line number on the left.

Situation 1

Goal: Change activeList to this and add a ; at the end of the line.

// current mode: Normal
  2 if (this.sortMethod === 'Name') {
  1   activeList.uncheckedTodo.sort(sortWithName)
189 }
    ^

My approach: -cwthis<ESC>A;

  • -: Go 1 line upward, on the first non-blank character
  • cwthis: Change the word and type this.
  • <ESC>: Leave insert mode.
  • A;: Jump to the end of the line and type ;.

situation 1

Situation 2

Goal: Change i-s+1 to d and add new before Date(y, m, d).

// current mode: Normal
454 console.log(Date(y, m, i-s+1));
                        ^

My approach: Wct)d<C-o>FDnew (<C-o> means CTRL-O)

  • W: Go one word forward, ignore symbol.
  • ct)d: Change till before the occurrence of ) to the right and type d.
  • <C-o>: Execute one command in Normal mode and then return to Insert mode.
  • FD: Go to the occurrence of D to the left.
  • new : Type new .

situation 2

Situation 3

Goal: Add a line activeList.sortMethod = 'Date'; below document.querySelector('.sort-date')....

// current mode: Insert
  1 document.querySelector('.sort-name').addEventListener('click', () => {
343   activeList.sortMethod = 'Name'; 
  1   activeList.update();           ^
  2 })
  3 
  4 document.querySelector('.sort-date').addEventListener('click', () => {
  5   activeList.update();
  6 })

My approach: <ESC>yy4jpci'Date

  • <ESC>: Leave insert mode.
  • yy: Yank current line.
  • 4j: Go down 4 line.
  • p: Paste the line we just yanked.
  • ci'Date: Change the content inside single quote and type Date.

situation 3

Situation 4

Goal: Move the whole block of //sort to the beginning of update() function.

// current mode: Normal
  8 update() {
  7   this.checkedTodo.forEach((todo) => {
  6     this.element.insertBefore(todo.element, todoCreator.nextSibling);
  5   });
  4   this.uncheckedTodo.forEach((todo) => {
  3     this.element.insertBefore(todo.element, todoCreator.nextSibling);
  2   });
  1         v
200   // sort
  1   if(this.sortMethod === 'Name') {
  2     this.uncheckedTodo.sort(sortWithName);
  3   }
  4   else if(this.sortMethod === 'Date') {
  5     this.uncheckedTodo.sort(sortWithDate);
  6   }
  7
  8   createCalendar(currentYear, currentMonth, this);
  9 }

My approach: dap8kp

  • dap: Delete around the paragraph.
  • 8k: Go up 8 lines.
  • p: Paste the paragraph we just deleted.

situation 4

Final Words

If you just start learning Vim operators, motions, it may take some times to think of what commands to use for each situation. However, If you keep practicing and using them, you’ll become faster and faster. After a while, you’ll develop muscle memory for using these commands.

If you are using Neovim, I recommend you to try out hardtime.nvim. It’s a plugin to help you establish good command workflow and display hints for better commands!


If you like this kind of content and want to see more of it in the future, consider following my X (Twitter) to get notified when I post new content!