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 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
- You have a basic understanding of Vim keybindings (e.g. you should know what
5j
,yy
means)
Table of Contents
- Navigation
- Keybindings
- Yanking
(Full Settings: settings.json
| keybindings.json
)
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)
To enable it, open settings.json
by pressing "Ctrl+Shift+P" and search for “Preferences: Open User Settings (JSON)”. Then, add the following item:
{
"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
in Vim.
Add the following item to settings.json
:
{
"editor.cursorSurroundingLines": 8
}
#3 - Word Separators
If you frequently work with CSS class names (e.g. Tailwind CSS), 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)
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:
Then, the editor treats border-red-100
as a single word and I can select it by pressing e
just once!
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
The <C-j>
and <C-p>
combination also works in the “Go to File” menu (i.e. the “Ctrl + P” menu):
If you have the File Explorer window in focus (e.g. by clicking the File Explorer window), you can navigate items via:
-
j
andk
- Move down and up -
h
- Move to parent folder -
o
- Open file or folder
We’ll soon look into more custom File Explorer keybindings in Tip #7.
#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 “go”) and followed by the first letter of the action. Some starts with gp
, meaning “go peek”.
(Legend: 🔥 = Most commonly used)
-
gd
- Go to Definition (🔥) -
gpd
- Peek Definition -
gh
- Show Hover (🔥) -
gi
- Go to Implementations (🔥) -
gpi
- Peek Implementations -
gq
- Quick fix (open the code action lightbulb menu) -
gr
- Go to References (🔥) -
gt
- Go to Type Definition (🔥) -
gpt
- Peek Type Definition
They can be set in settings.json
under vim.normalModeKeyBindings
:
{
"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, 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.
Make sure we’ve remapped gh
in settings.json
(this should be already done in Tip #5):
{
"vim.normalModeKeyBindings": [
// ...
{
"before": ["g", "h"],
"commands": ["editor.action.showDefinitionPreviewHover"]
}
]
}
Next, open keybindings.json
via “Ctrl + Shift + P” → “Preferences: Open Keyboard Shortcuts (JSON)” and append the following items:
[
{
"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 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, 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 (seevim.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:
- Open
settings.json
and add the<leader>e
keybinding to open File Explorer:
{
"vim.leader": "<space>",
"vim.normalModeKeyBindings": [
// ...
{
"before": ["<leader>", "e"],
"commands": ["workbench.view.explorer"]
}
]
}
- Open
keybindings.json
via “Ctrl + Shift + P” → “Preferences: Open Keyboard Shortcuts (JSON)” and append the following items:
[
{
"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 withf
→ New file witha
- Open File Explorer with
<leader>e
→ Cut a file withx
→ Paste the file withp
(Credits to v-iashin 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
- MacOS - Karabiner Elements
- Linux - Input Remapper
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:
In settings.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
:
{
"vim.useSystemClipboard": true
}
Last but not least, I highly recommend you to check out the 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 👇:
Thanks for reading! If you also have some VS Code Vim tips, feel free to share them in the comments 🙌.
Top comments (13)
Thanks a lot for sharing this. Apart from this I use FindItFaster extention in vscode. It's like telescope.nvim but within the terminal. Works really well. You can adjust the keybindings in
settings.json
like<leader>ff
to find files etc.Extra Tip
At this part of the article
#4 - Navigate Menus without Arrow Keys
you can remap the keys you use to go up and down in opened menus to be more intuitive by being close to the original Vim up and down motion j - k.
Steps
Preferences: Open Keyboard Shortcuts (JSON)
Now when any menu is opened, you're able to Move to the next item by using
Ctrl + j
and to the previous item by usingCtrl + k
!Great suggestion! ⚡️
Thanks! Very cool & useful tips.
May be useful setting for peek view:
"editor.peekWidgetDefaultFocus": "editor",
May be useful keybindings for switching occurences/code view in peek view:
"Bravo! Thanks for sharing this. At first, I was surprised and thought, 'How do you navigate between tabs if you're overwriting the switch tab functionality with 'gt'?' But then I saw the clever solution you provided in the second part, which includes a great mapping. Well done man!" Also, I can't even imagine how long it took you to develop this setup, again, thanks for sharing.
Hey this was very helpful for me. Especially
gpd
I needed this. Thank you very much. You're amazing!This was super helpful, I appreciate you taking the time to put this together!
Thank you so much :)
This was really helpful, I've been using this extension for months.
Based on the this article i can assume you know how to remap binding in correct way, I'd appreciated if you can help me out with this,
Please take a look at this.
github.com/VSCodeVim/Vim/discussio...
Glad to hear that you found this article helpful :)
As for your question, sorry that I don't know the answer. I also had the same question a while ago haha
Is there a way to navigate between open files?
Yes, I mapped
H
andL
to focus the previous and next opened file respectively. Try this insettings.json
:Please add a tip to change "change" and "delete" behaviour from cutting content into DELETING. Add a leader-c and leader-d to change-with-yank and delete-with-yank