Learn Practice Daily golf Reference
Guides · Vim in your editor

Vim in VS Code: VSCodeVim setup and settings

Install the Vim extension by VSCodeVim (vscodevim.vim) from the Extensions view and VS Code gets Normal, Insert and Visual modes straight away. Then set four things in settings.json: the system clipboard, your leader key, a jk (or jj) mapping for Escape, and which Ctrl keys stay with VS Code. If you want a real Neovim underneath instead of an emulation, use the vscode-neovim extension.

VSCodeVim settings that matter (names and defaults from its README)
SettingWhat it doesDefault
vim.useSystemClipboard Yank and put use the system clipboard (the * register) by default false
vim.useCtrlKeys Lets Vim take Ctrl keys that VS Code would use for copy, paste, find and so on true
vim.handleKeys Hands chosen keys back to VS Code, e.g. "<C-f>": false <C-d> Vim; <C-s>, <C-z> VS Code
vim.leader The key <leader> stands for in your mappings \
vim.insertModeKeyBindings Mappings for Insert mode, such as jk to Escape none
vim.normalModeKeyBindingsNonRecursive Normal mode mappings that don't remap, including ones that run VS Code commands none
vim.hlsearch Highlights every match of the last search false
vim.easymotion Turns on the EasyMotion emulation false
vim.surround vim-surround emulation (ys, cs, ds) true
vim.sneak vim-sneak emulation false
vim.highlightedyank.enable Briefly highlights what you yanked false

Install VSCodeVim

  • Open the Extensions view, search for Vim, and install the one published by vscodevim (ID vscodevim.vim). It is also on Open VSX for VSCodium.
  • The status bar shows the current mode. Press i to type, Esc to go back to Normal mode.
  • On a Mac, fix key repeat first. Holding j shows the accent picker instead of moving. Run this in Terminal, log out and back in, then restart VS Code:
  • defaults write com.microsoft.VSCode ApplePressAndHoldEnabled -bool false

The README also suggests raising Key Repeat and Delay Until Repeat in the keyboard settings. VS Code Insiders, VSCodium and Windsurf need the same command with their own app IDs, listed in the README.

A starting settings.json

Open the command palette, run Preferences: Open User Settings (JSON), and add:

  • "vim.useSystemClipboard": true,
  • "vim.leader": "<space>",
  • "vim.hlsearch": true,
  • "vim.insertModeKeyBindings": [{ "before": ["j", "k"], "after": ["<Esc>"] }],
  • "vim.normalModeKeyBindingsNonRecursive": [{ "before": ["<leader>", "h"], "commands": [":nohl"] }],
  • "vim.handleKeys": { "<C-a>": false, "<C-f>": false },

What each line buys you: y and p talk to the system clipboard, so copying between VS Code and a browser works; ␣ becomes your leader; typing j k quickly in Insert mode leaves it (the README's own example uses jj; pick a pair you never type in real words); ␣ h clears search highlighting; and Ctrl-a and Ctrl-f go back to VS Code's select-all and find.

Mappings can run VS Code commands as well as keys: put a command ID such as workbench.action.showCommands in "commands" instead of "after".

Ctrl keys that clash with VS Code

Like real Vim, VSCodeVim takes over your Ctrl keys, because vim.useCtrlKeys is on by default. Its README notes this under Windows: Ctrl-c, Ctrl-v, Ctrl-f and friends now do Vim things (Ctrl-v starts Visual block mode, for example). On a Mac, VS Code's copy, paste and find use Cmd, so the clash is much smaller.

Two ways to handle it:

  • Keep Vim's Ctrl keys and give a few back with vim.handleKeys, setting a key to false to let VS Code have it. By default VSCodeVim already leaves Ctrl-s and Ctrl-z to VS Code.
  • Give them all back with "vim.useCtrlKeys": false. Vim's own Ctrl commands, such as Ctrl-v for Visual block and Ctrl-r for redo, then stop reaching Vim, so giving back only the keys you miss is usually the better trade.

If a popup such as IntelliSense won't close with Esc, press Shift+Esc: the README's tip for closing all of those boxes.

Practise the keys

The Ctrl keys you would give up

With vim.useCtrlKeys on (the default), these reach Vim instead of VS Code. Type each from memory before you decide which to hand back.

Redo the change you just undid.
scroll here, then press the keys
1 of 5
Redo the change you just undid.

Built-in plugins and VS Code extras

VSCodeVim emulates several popular Vim plugins, so you don't install them separately: vim-surround (on by default), vim-commentary (gc and gcc work out of the box), vim-easymotion (vim.easymotion, then <leader><leader> w and similar), vim-sneak (vim.sneak), vim-indent-object, CamelCaseMotion, ReplaceWithRegister, vim-textobj-entire and vim-textobj-arguments.

It also maps a few VS Code features to Vim-style keys:

  • gd jumps to the definition.
  • gh shows the hover, the same as resting the mouse there: types and error messages.
  • gb adds a cursor at the next match of the word under the cursor, like VS Code's own add-next-occurrence.
  • af in Visual mode selects increasingly large blocks around the cursor.
  • gq on a selection reflows comments.
Try it here

Warm up: a text object, a comment, a delete

Keys you'll use in VS Code every day, all of which VSCodeVim handles: change the text inside the quotes with ci", comment out the log line with gcc (built in, no setting needed), and delete the stray debugger; with dd.

Stuck? Show the keysSurround works too (ysiw" wraps a word in quotes, cs"' swaps double quotes for single), but it is a plugin's keys rather than Vim's, so try it in VS Code itself.
1 of 3Change hello to hi there: ci", type, Esc
1const greeting = "hello";
1console.log(greeting);
2debugger;
NORMALLoading the editor…1/30.0s1:22

This editor needs a keyboard. Read on, and play it at your computer.

What doesn't work (or only partly)

VSCodeVim is an emulation, and its README is candid about the rough edges:

  • Your .vimrc is supported only experimentally and only for remaps (vim.vimrc.enable and vim.vimrc.path). Settings, functions and plugins in it are ignored.
  • Multi-cursor mode is experimental: most commands work, some don't.
  • Folds: moving with j and k over a fold opens it. vim.foldfix works around it, with side effects.
  • Ex commands cover the common ones but not all of Vim's command line. The optional Neovim integration (vim.enableNeovim, vim.neovimPath) runs some Ex commands through a real Neovim and is marked experimental.
  • Swapping Escape and Caps Lock with setxkbmap on Linux isn't respected; that is a VS Code issue.

The alternative: vscode-neovim

vscode-neovim (asvetliakov.vscode-neovim) takes the other approach: it runs a real, embedded Neovim and sends your Normal and Visual mode keys to it, so Normal mode commands, registers and macros behave as in Neovim. Its README promises feature-complete Vim integration except Insert mode and some Nvim UI plugins, and support for a custom init.lua and most Nvim plugins (it recommends starting from an empty config). Insert mode is left to VS Code, which keeps typing and completion native.

The costs: you need Neovim 0.10.0 or newer installed, the setup is a little more involved, and you must uninstall VSCodeVim, because the two conflict.

Pick VSCodeVim if you want something that works in two minutes with settings in settings.json. Pick vscode-neovim if you already use Neovim, or you keep hitting the edges of the emulation.

Either way, the motions are the same as in Vim, and the course teaches them in a real editor in the browser.

Questions

How do I map jk to Escape in VSCodeVim?
Add "vim.insertModeKeyBindings": [{ "before": ["j", "k"], "after": ["<Esc>"] }] to your user settings.json.
Why does copy and paste not work with VSCodeVim?
Vim yanks into its own register by default. Set "vim.useSystemClipboard": true so y and p use the system clipboard. On Windows and Linux, Ctrl+C and Ctrl+V are taken by Vim unless you hand them back with vim.handleKeys or turn off vim.useCtrlKeys.
Should I use VSCodeVim or vscode-neovim?
VSCodeVim is easier to set up and fine for most people. vscode-neovim uses a real Neovim, so it is more faithful and reads your Neovim config, but it needs Neovim 0.10.0 or newer installed.

Sources