10 VS Code Vim Tricks to Boost Your Productivity ⚡
Tags: vscode, vim, tutorial, productivity
Published: 2023-06-13 09:07:24

Learning Vim is one of the best things any aspiring software engineers can do to improve their productivity. I’ve been using the [VSCodeVim extension](https://marketplace.visualstudio.com/items?itemName=vscodevim.vim) in Visual Studio Code for the past few years, and this “VS Code × Vim” combo has greatly improved my coding speed.

In this article, I’ll share ten VS Code Vim tips to further boost your productivity so that you can code at lightning speeds ⚡.

**Prerequisites**:

- You’ve installed [VSCodeVim extension](https://marketplace.visualstudio.com/items?itemName=vscodevim.vim)
- You have a basic understanding of Vim keybindings (e.g. you should know what `5j`, `yy` means)

---

## Table of Contents

- Navigation
    - [#1 - Smart Relative Line](#1-smart-relative-line)
    - [#2 - Cursor Surrounding Lines](#2-cursor-surrounding-lines)
    - [#3 - Word Separators](#3-word-separators)
- Keybindings
    - [#4 - Navigate Menus without Arrow Keys](#4-navigate-menus-without-arrow-keys)
    - [#5 - LSP Keybindings](#5-lsp-keybindings)
    - [#6 - Scroll in Show Hover](#6-scroll-in-show-hover)
    - [#7 - File Explorer Keybindings](#7-file-explorer-keybindings)
    - [#8 - Mapping Caps Lock to Escape](#8-mapping-caps-lock-to-escape)
- Yanking
    - [#9 - Highlight Yanked Text](#9-highlight-yanked-text)
    - [#10 - Yank to System Clipboard](#10-yank-to-system-clipboard)

(Full Settings: [`settings.json`](https://gist.github.com/AnsonH/b08e12f1fbdd633b4bfd63a7722e2736) | [`keybindings.json`](https://gist.github.com/AnsonH/11c1bc55ad8db2fcf2d4f1f76a5e5b7d))

---

## Navigation

### #1 - Smart Relative Line

This cool feature displays absolute line numbers only in insert mode and relative line number otherwise.

In the demo below, note that the line number gutter at the **left** shows absolute numbers only in insert mode 👇

(💡 If the GIF is not playing, click on it)

![smart relative line](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vzrsuu90mtesmywtxlo0.gif)

To enable it, open `settings.json` by pressing "Ctrl+Shift+P" and search for  “Preferences: Open User Settings (JSON)”. Then, add the following item:

```json
{
  "vim.smartRelativeLine": true,
}
```

### #2 - Cursor Surrounding Lines

When scrolling through a large file, it can be annoying that the cursor may locate at the very top/bottom of the screen, so you’re not sure what lines are before/after the cursor.

The “Editor: Cursor Surrounding Lines” sets the minimal number of lines to keep above and below the cursor. For example, setting it to `8` means that there are **always ≥8 lines above** my cursor and **≥8 lines below** my cursor. It’s also known as [`scrolloff`](https://vimdoc.sourceforge.net/htmldoc/options.html#'scrolloff') in Vim.

Add the following item to `settings.json`:
```json
{
  "editor.cursorSurroundingLines": 8,
}
```

### #3 - Word Separators

If you frequently work with CSS class names (e.g. [Tailwind CSS](https://tailwindcss.com/)), you may find it annoying that Vim breaks down a `kebab-case` class name into multiple words. 

For instance, I need to press `e` (jump forward to end of word) **5 times** to select the word `border-red-600` because the editor treats the `-` symbol as a **word separator**. While I can definitely use `E` (jump forward to end of word, ignoring punctuation) to do the same thing, I like spamming `e` to move forward (don’t judge me 😥) and I want a quicker way to do that.

(💡 Again, click on the GIF if it's not playing)

![Navigating a CSS class - Before](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z2t5yht7ej9pn4qnbaof.gif)

The “Editor: Word Separators” setting controls what characters are used as word separators, which has the `-` character by default. In `settings.json`, if I remove the `-` character:

```json
{
  "editor.wordSeparators": "`~!@#$%^&*()=+[{]}\\|;:'\",.<>/?",
}
```

Then, the editor treats `border-red-100` as a **single** word and I can select it by pressing `e` just once!


![Navigating a CSS class - After](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tiws6frnyvkyxx07ewqt.gif)

([🔼 Table of Contents](#table-of-contents))

---

## Keybindings

### #4 - Navigate Menus without Arrow Keys

The VSCodeVim extension has several **built-in** keybindings to let you navigate different menus and lists without arrow keys.

If you’re in an auto-complete menu:

- Ctrl + J - Move to next item
- Ctrl + P - Move to previous item

![Autocomplete menu without arrow keys](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ottw89b7v7i0vox1fi2e.gif)

The `<C-j>` and `<C-p>` combination also works in the “Go to File” menu (i.e. the “Ctrl + P” menu):


![Go to File menu without arrow keys](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yub97yqkqn34s3yx0l1l.gif)


If you have the File Explorer window in focus (e.g. by clicking the File Explorer window), you can navigate items via:

- `j` and `k` - Move down and up
- `h` - Move to parent folder
- `o` - Open file or folder

![File explorer keybindings](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d88vq9vwy2z5ki1bt86k.gif)


We’ll soon look into more custom File Explorer keybindings in [Tip #7](#7-file-explorer-keybindings).

### #5 - LSP Keybindings

LSP (language server protocol) keybindings leverage the language server to let you quickly navigate through code, such as jumping to the variable/function definition and finding its usage.

All of my LSP keybindings start with `g` (means “**g**o”) and followed by the first letter of the action. Some starts with `gp`, meaning “**g**o **p**eek”. 

(Legend: 🔥 = Most commonly used)

- `gd` - Go to **D**efinition (🔥)
- `gpd` - **P**eek **D**efinition
- `gh` - Show **H**over (🔥)
- `gi` - Go to **I**mplementations (🔥)
- `gpi` - **P**eek **I**mplementations
- `gq` - **Q**uick fix (open the [code action lightbulb](https://code.visualstudio.com/docs/editor/refactoring#_code-actions-quick-fixes-and-refactorings) menu)
- `gr` - Go to **R**eferences (🔥)
- `gt` - Go to **T**ype Definition (🔥)
- `gpt` - **P**eek **T**ype Definition

They can be set in `settings.json` under `vim.normalModeKeyBindings`:

```json
{
  "vim.normalModeKeyBindings": [
    {
      "before": ["g", "p", "d"],
      "commands": ["editor.action.peekDefinition"]
    },
    {
      "before": ["g", "h"],
      "commands": ["editor.action.showDefinitionPreviewHover"]
    },
    {
      "before": ["g", "i"],
      "commands": ["editor.action.goToImplementation"]
    },
    {
      "before": ["g", "p", "i"],
      "commands": ["editor.action.peekImplementation"]
    },
    {
      "before": ["g", "q"],
      "commands": ["editor.action.quickFix"]
    },
    {
      "before": ["g", "r"],
      "commands": ["editor.action.referenceSearch.trigger"]
    },
    {
      "before": ["g", "t"],
      "commands": ["editor.action.goToTypeDefinition"]
    },
    {
      "before": ["g", "p", "t"],
      "commands": ["editor.action.peekTypeDefinition"]
    },
  ],
}
```
(Note: The `gd` (Go to Definition) keybinding is built-in so no need to re-specify in the above.)

### #6 - Scroll in Show Hover

Starting from VS Code [v1.77](https://code.visualstudio.com/updates/v1_77#_hover-control-navigation), it’s possible to **scroll** in a **hover window** (opened by `gh`) using keyboard shortcuts. With some hacks, we can use `h`, `j`, `k`, `l` keys to scroll in a hover window.

![Scroll in Show Hover](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kaqw2ck20ixgj68n9gwt.gif)


1. Make sure we’ve remapped `gh` in `settings.json` (this should be **already done** in [Tip #5](#5-lsp-keybindings)):
    
    ```json
    {
      "vim.normalModeKeyBindings": [
        // ...
        {
          "before": ["g", "h"],
          "commands": ["editor.action.showDefinitionPreviewHover"]
        },
      ]
    }
    ```
2. Open `keybindings.json` via “Ctrl + Shift + P” → “Preferences: Open Keyboard Shortcuts (JSON)” and append the following items:
    
    ```json
    [
      {
        "key": "h",
        "command": "editor.action.scrollLeftHover",
        "when": "editorHoverFocused"
      },
      {
        "key": "j",
        "command": "editor.action.scrollDownHover",
        "when": "editorHoverFocused"
      },
      {
        "key": "k",
        "command": "editor.action.scrollUpHover",
        "when": "editorHoverFocused"
      },
      {
        "key": "l",
        "command": "editor.action.scrollRightHover",
        "when": "editorHoverFocused"
      },
    ]
    ```

([Credits to EdRW](https://github.com/VSCodeVim/Vim/issues/3740#issuecomment-1497005857) for this hack)

### #7 - File Explorer Keybindings

While the VSCodeVim extension comes with several built-in File Explorer keybindings as seen in Tip #4, we can add custom keybindings to enrich the experience:

- `<leader>e` - Toggles (and focuses) the File Explorer view
  - 💡 `<leader>` stands for [Leader Key](https://stackoverflow.com/q/1764263/11067496), which is commonly used as a prefix for user-defined shortcuts. By default it's the backslash key (`\`), but we commonly map it to Space key (see `vim.leader` option below)
- Inside File Explorer:
    - `a` - New file
    - `f` - New folder
    - `r` - Rename item
    - `x` - Cut item
    - `y` - Copy item
    - `p` - Paste item

To set up the custom keybindings:

1. Open `settings.json` and add the `<leader>e` keybinding to open File Explorer:
    
    ```json
    {
      "vim.leader": "<space>",
      "vim.normalModeKeyBindings": [
        // ...
        {
          "before": ["<leader>", "e"],
          "commands": ["workbench.view.explorer"]
        },
      ]
    }
    ```
    
2. Open `keybindings.json` via “Ctrl + Shift + P” → “Preferences: Open Keyboard Shortcuts (JSON)” and append the following items:
    
    ```json
    [
      {
        "key": "space e",
        "command": "workbench.action.toggleSidebarVisibility",
        "when": "filesExplorerFocus && !inputFocus"
      },
      {
        "key": "a",
        "command": "explorer.newFile",
        "when": "explorerViewletVisible && filesExplorerFocus && !explorerResourceIsRoot && !explorerResourceReadonly && !inputFocus"
      },
      {
        "key": "f",
        "command": "explorer.newFolder",
        "when": "explorerViewletVisible && filesExplorerFocus && !explorerResourceIsRoot && !explorerResourceReadonly && !inputFocus"
      },
      {
        "key": "r",
        "command": "renameFile",
        "when": "explorerViewletVisible && filesExplorerFocus && !explorerResourceIsRoot && !explorerResourceReadonly && !inputFocus"
      },
      {
        "key": "x",
        "command": "filesExplorer.cut",
        "when": "explorerViewletVisible && filesExplorerFocus && !explorerResourceIsRoot && !explorerResourceReadonly && !inputFocus"
      },
      {
        "key": "y",
        "command": "filesExplorer.copy",
        "when": "explorerViewletVisible && filesExplorerFocus && !explorerResourceIsRoot && !inputFocus"
      },
      {
        "key": "p",
        "command": "filesExplorer.paste",
        "when": "explorerViewletVisible && filesExplorerFocus && !explorerResourceReadonly && !inputFocus"
      },
    ]
    ```
    
    The first item enables `<leader>e` to close the File Explorer when it’s on focus and the remaining items are keybindings for manipulating items.

Demo:
- Open File Explorer with `<leader>e` → New folder with `f` → New file with `a`
   ![file explorer demo 1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ob6sqcwln4lmwzzt5pji.gif)
- Open File Explorer with `<leader>e` → Cut a file with `x` → Paste the file with `p`
   ![file explorer demo 2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pjogttjrjiozdn8awgtr.gif)

([Credits to v-iashin](https://github.com/VSCodeVim/Vim/issues/7120#issue-1013082037) for this hack)

### #8 - Mapping Caps Lock to Escape

While the Escape key is such an important key for Vim, I hate how every keyboard places it at the top left corner, which makes it inconvenient to reach when your hands are at the home row. I strongly recommend remapping the **Caps Lock** key to **Escape** since the Caps Lock key is rarely used and it can be easily accessible via your pinky finger.

Remapping Caps Lock to Escape also eliminates a common Insert mode keybinding where `jj` (or `jk`) exits Insert mode. Your editor no longer awkwardly pauses whenever you type `j` in Insert mode to wait for you to complete the `jj` keybinding.

Performing the remap requires a 3rd party utility program:

- Windows - [PowerToys Keyboard Manager](https://learn.microsoft.com/en-us/windows/powertoys/keyboard-manager#remap-keys)
- MacOS - [Karabiner Elements](https://karabiner-elements.pqrs.org/docs/manual/configuration/configure-simple-modifications/)
- Linux - [Input Remapper](https://github.com/sezanzeb/input-remapper)

([🔼 Table of Contents](#table-of-contents))

---

## Yanking

### #9 - Highlight Yanked Text

You can enable highlighting when yanking, which is a great visual cue that shows what text you’ve yanked. Apart from the highlight duration, you can set a highlight color that matches your color scheme. For example, I used a green highlight color:


![highlight yanked text demo](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/riwxz5mx3fbc1fiqz6xb.gif)

In `settings.json`:

```json
{
  "vim.highlightedyank.enable": true,
  "vim.highlightedyank.color": "#a9dc7660",
  "vim.highlightedyank.duration": 250,
}
```

### #10 - Yank to System Clipboard

You can use the system clipboard register (`*`) as the default register. In other words, keybindings such as `yy` or `dd` will yank the text to your system clipboard. In `settings.json`:

```json
{
  "vim.useSystemClipboard": true,
}
```

([🔼 Table of Contents](#table-of-contents))

---
Last but not least, I highly recommend you to check out the [README](https://github.com/VSCodeVim/Vim#readme) of the VSCodeVim extension. You’ll definitely learn something new that’s not covered in this article 😁.

For the **full** settings code, they can be found below 👇:

- [`settings.json`](https://gist.github.com/AnsonH/b08e12f1fbdd633b4bfd63a7722e2736)
- [`keybindings.json`](https://gist.github.com/AnsonH/11c1bc55ad8db2fcf2d4f1f76a5e5b7d)

Thanks for reading! If you also have some VS Code Vim tips, feel free to share them in the comments 🙌.

- [My GitHub](https://github.com/AnsonH)
- [Personal website](https://www.ansonh.com)