If you have any questions or feedback, pleasefill out this form
This post is translated by ChatGPT and originally written in Mandarin, so there may be some inaccuracies or mistakes.
Around early 2021, I started using Vim for VSCode.
The reason is simple: after switching to the HHKB keyboard, there are no arrow keys (my pinky has to press the fn key), so naturally, I wanted to minimize the use of arrow keys while editing text. Additionally, the control key on the HHKB is conveniently located above the Caps Lock key, making it easier to press control. Influenced by these external factors, I began learning Vim and found it quite useful in combination with VSCode. Here, I’d like to share some insights and tips for those who might be interested. If you want to learn more about the HHKB keyboard, feel free to check out my previous article - HHKB Hybrid Type-S User Review.
VSCodeVim
VSCodeVim is an extension for VSCode that allows developers to use Vim keybindings and commands within the editor. Using just Vim requires a lot of time spent on configuration, and I prefer not to step outside the VSCode ecosystem, so integrating it with VSCode feels much more natural. This is also why I don’t recommend using Vim in isolation—while tools are just aids, the navigation, terminal integration, extensions, and auto-completion that VSCode offers significantly enhance development efficiency.
The integration of this extension with VSCode is excellent; you can set custom keybindings to map VSCode functionalities. Below, I’ll share some of my commonly used settings. Rather than a tutorial on Vim, it’s more of a sharing of how I use this extension in conjunction with other features.
Additionally, this article is simply a recommendation for using Vim with VSCodeVim; I am not here to push Vim onto anyone or insist that every developer must use Vim.
(Note: This article contains a lot of GIFs, and currently, there is no image zoom feature. If the images are too small, please open them in a new tab.)
Go to Definition
When tracing source code, I often need to look at a function while also reviewing its implementation. With the gd
and gf
bindings, I can follow the implementation without moving my mouse while in normal mode, or I can preview the type directly, which is very convenient.
Merge Conflict
When merging a Pull Request and a conflict occurs, a few options will appear in the upper right corner to help resolve the conflict, allowing you to choose incoming, current, or both. Similarly, to keep everything keyboard-centric, I have set up additional shortcuts.
Copying a File's URL from GitHub
If I find a specific file implementation in VSCode that I want to share with other team members, it would be cumbersome to navigate through GitHub manually. Fortunately, the gitlens extension already integrates this functionality (gitlens.copyRemoteFileUrlFrom
), so I can bind it to a shortcut. You can also directly open your browser to jump straight to the GitHub tab.
Quickly Prettify Code
I have bound the format document action to ff
in normal mode, so with just two presses of f
, I can instantly prettify my file, which is quite handy. Of course, you can also enable format on save.
Git Blame
While GitHub offers a convenient Blame feature, it’s even better to have it available right in VSCode. This functionality is already provided by gitlens, so we just need to bind a shortcut. This way, I can use the keyboard to trace specific code, slowly blaming until I find the culprit. (I used my own project as an example; it would be even more efficient in a collaborative project.)
Open File in Finder (revealFileInOS)
Sometimes it's really convenient to jump directly to a file's path for adjustments, so I’ve also bound this to a Vim shortcut.
Split Two Tabs Side by Side (or Top and Bottom)
If you have a 27-inch external monitor, it can be quite helpful to have separate tabs for writing HTML and CSS side by side to make viewing easier; switching between them is also more convenient. In VSCodeVim, you can use :vs
or :sp
for this. Additionally, you can switch between split views using <C-w> + arrow key
.
If you're interested, you can refer to the following JSON file. Everyone has their preferred key mappings, so feel free to modify it according to your needs.
"vim.normalModeKeyBindings": [
{
"before": [
"g", "l"
],
"commands": [
"cmake.build"
]
},
{
"before": [
"<leader>",
"q"
],
"commands": [
"workbench.action.openRecent"
]
},
{
"before": [
"g",
"f"
],
"commands": [
"editor.action.peekDefinition"
]
},
{
"before": [
"g",
"n"
],
"commands": [
"cmake.build"
]
},
{
"before": [
"<leader>",
"<leader>",
"c"
],
"commands": [
"merge-conflict.accept.current"
]
},
{
"before": [
"<leader>",
"o"
],
"commands": [
"gitlens.openFileOnRemoteFrom"
]
},
{
"before": [
"<leader>",
"<leader>",
"i"
],
"commands": [
"merge-conflict.accept.incoming"
]
},
{
"before": [
"<leader>",
"<leader>",
"b"
],
"commands": [
"merge-conflict.accept.both"
]
},
{
"before": [
"<leader>",
"s"
],
"commands": [
"workbench.action.quickOpenTerm"
]
},
{
"before": [
"<leader>",
"c"
],
"commands": [
"gitlens.copyRemoteFileUrlFrom"
]
},
{
"before": [
"<leader>",
"b"
],
"commands": [
"gitlens.toggleFileBlame"
]
},
{
"before": [
"<leader>",
"p"
],
"commands": [
"gitlens.openBlamePriorToChange"
]
},
{
"before": [
"<leader>",
"a"
],
"commands": [
"workbench.view.explorer"
]
},
{
"before": [
"<leader>",
"<leader>",
"r"
],
"commands": [
"revealFileInOS"
]
},
{
"before": [
"f",
"f"
],
"commands": [
"editor.action.formatDocument"
]
},
{
"before": [
"+",
"+"
],
"commands": [
"workbench.action.increaseViewSize"
]
},
{
"before": [
"-",
"-"
],
"commands": [
"workbench.action.decreaseViewSize"
]
}
]
Other Useful Tips
vit
vat
to select all tag blocks: This allows you to directly select blocks wrapped in tags, such as those enclosed by<div>
.- This extends to commands like
cit
anddit
, corresponding to modifying and deleting content, respectively.
- This extends to commands like
dst
to remove the outer tag: It’s common to encounter a wrapper div that you suddenly want to remove; this command takes care of that.cstt
to change a tag, for example, from p to div: This is one of my favorite commands, as it’s incredibly fast..
: Repeat the last action.yssb
: Wrap a text block with()
.yiw
ciw
: Delete a single word.cs"'
: Replace"
with'
.dgn
: Delete to the searched character.
There are many more Vim tricks, but I’ll leave it at that for now. Also, VSCodeVim supports recording
, so when you encounter more complex operations, you can record your actions and then execute them to reduce keystrokes.
If you found this article helpful, please consider buying me a coffee ☕ It'll make my ordinary day shine ✨
☕Buy me a coffee