Vim emulation for Visual Studio Code VSCodeVim is a Vim emulator for Visual Studio Code.
Table of Contents (click to expand)💾 InstallationVSCodeVim is automatically enabled following installation and reloading of VSCode. Vim CompatibilityVimscript is not supported, therefore we are not able to load your Mac SetupTo enable key-repeating execute the following in your Terminal and restart VS Code.
We also recommend increasing Key Repeat and Delay Until Repeat settings in System Preferences -> Keyboard. Windows SetupLike real vim, VSCodeVim will take over your control keys. This behaviour can be adjusted with the Linux SetupIf you have configured
⚙️ SettingsThe settings documented here are a subset of the supported settings; the full list is described in the Quick ExampleBelow is an example of a settings.json file with settings relevant to VSCodeVim:
VSCodeVim settingsThese settings are specific to VSCodeVim.
Neovim Integration
To leverage neovim for Ex-commands,
Here's some ideas on what you can do with neovim integration:
Key RemappingCustom remappings are defined on a per-mode basis.
|
Setting | Description | Type | Default Value |
---|---|---|---|
vim.autoindent | Copy indent from current line when starting a new line | Boolean | true |
vim.hlsearch | Highlights all text matching current search | Boolean | false |
vim.ignorecase | Ignore case in search patterns | Boolean | true |
vim.incsearch | Show the next match while entering a search | Boolean | true |
vim.leader | Defines key for <leader> to be used in key remappings |
String | \ |
vim.showcmd | Show (partial) command in status bar | Boolean | true |
vim.showmodename | Show name of current mode in status bar | Boolean | true |
vim.smartcase | Override the 'ignorecase' setting if search pattern contains uppercase characters | Boolean | true |
vim.textwidth | Width to word-wrap when using gq |
Number | 80 |
vim.timeout | Timeout in milliseconds for remapped commands | Number | 1000 |
vim.whichwrap | Controls wrapping at beginning and end of line. Comma-separated set of keys that should wrap to next/previous line. Arrow keys are represented by [ and ] in insert mode, < and > in normal and visual mode. To wrap "everything", set this to h,l,<,>,[,] . |
String | `` |
🖱️ Multi-Cursor Mode
:warning: Multi-Cursor mode is experimental. Please report issues in our feedback thread.
Enter multi-cursor mode by:
- On OSX,
cmd-d
. On Windows,ctrl-d
. gb
, a new shortcut we added which is equivalent tocmd-d
(OSX) orctrl-d
(Windows). It adds another cursor at the next word that matches the word the cursor is currently on.- Running "Add Cursor Above/Below" or the shortcut on any platform.
Once you have multiple cursors, you should be able to use Vim commands as you see fit. Most should work; some are unsupported (ref PR#587).
- Each cursor has its own clipboard.
- Pressing Escape in Multi-Cursor Visual Mode will bring you to Multi-Cursor Normal mode. Pressing it again will return you to Normal mode.
🔌 Emulated Plugins
vim-airline
:warning: Experimental feature. Due to VSCode API limitations, this function modifies settings.json in the workspace resulting in latency and a constant changing diff in your working directory (see issue#2124).
Change the color of the status bar based on the current mode. Once enabled, configure "vim.statusBarColors"
. Colors can be defined for each mode either as string
(background only), or string[]
(background, foreground).
"vim.statusBarColorControl": true,
"vim.statusBarColors.normal": ["#8FBCBB", "#434C5E"],
"vim.statusBarColors.insert": "#BF616A",
"vim.statusBarColors.visual": "#B48EAD",
"vim.statusBarColors.visualline": "#B48EAD",
"vim.statusBarColors.visualblock": "#A3BE8C",
"vim.statusBarColors.replace": "#D08770"
vim-easymotion
Based on vim-easymotion. To activate easymotion, you need to make sure that easymotion
is set to true
in settings.json (default is false
).
Once easymotion is active, initiate motions using the following commands. After you initiate the motion, text decorators/markers will be displayed and you can press the keys displayed to jump to that position. leader
is configurable and is \
by default.
Motion Command | Description |
---|---|
<leader><leader> s <char> |
Search character |
<leader><leader> f <char> |
Find character forwards |
<leader><leader> F <char> |
Find character backwards |
<leader><leader> t <char> |
Til character forwards |
<leader><leader> T <char> |
Til character backwards |
<leader><leader> w |
Start of word forwards |
<leader><leader> b |
Start of word backwards |
<leader><leader> l |
matches beginning & ending of word, camelCase, after _ and after # forwards |
<leader><leader> h |
matches beginning & ending of word, camelCase, after _ and after # backwards |
<leader><leader> e |
End of word forwards |
<leader><leader> ge |
End of word backwards |
<leader><leader> j |
Start of line forwards |
<leader><leader> k |
Start of line backwards |
<leader><leader> / <char>... <CR> |
Search n-character |
<leader><leader><leader> bdt |
Til character |
<leader><leader><leader> bdw |
Start of word |
<leader><leader><leader> bde |
End of word |
<leader><leader><leader> bdjk |
Start of line |
<leader><leader><leader> j |
JumpToAnywhere motion; default behavior matches beginning & ending of word, camelCase, after _ and after # |
<leader><leader> (2s|2f|2F|2t|2T) <char><char>
and <leader><leader><leader> bd2t <char>char>
are also available.
The difference is character count required for search.
For example, <leader><leader> 2s <char><char>
requires two characters, and search by two characters.
This mapping is not a standard mapping, so it is recommended to use your custom mapping.
You can customize the appearance of easymotion markers (the boxes with letters) using the following settings:
Setting | Description | |||||||
---|---|---|---|---|---|---|---|---|
vim.easymotionMarkerBackgroundColor |
The background color of the marker box. | |||||||
vim.easymotionMarkerForegroundColorOneChar |
The font color for one-character markers. | |||||||
vim.easymotionMarkerForegroundColorTwoChar |
The font color for two-character markers, used to differentiate from one-character markers. | |||||||
vim.easymotionMarkerWidthPerChar |
The width in pixels allotted to each character. | |||||||
vim.easymotionMarkerHeight |
The height of the marker. | |||||||
vim.easymotionMarkerFontFamily |
The font family used for the marker text. | |||||||
vim.easymotionMarkerFontSize |
The font size used for the marker text. | |||||||
vim.easymotionMarkerFontWeight |
The font weight used for the marker text. | |||||||
vim.easymotionMarkerYOffset |
The distance between the top of the marker and the text (will typically need some adjusting if height or font size have been changed). | |||||||
vim.easymotionKeys |
The characters used for jump marker name | |||||||
vim.easymotionJumpToAnywhereRegex |
Custom regex to match for JumpToAnywhere motion (analogous to Easymotion_re_anywhere ). Example setting (which also matches start & end of line, as well as Javascript comments in addition to the regular behavior (note the double escaping required): ^\s*. |
\b[A-Za-z0-9] | [A-Za-z0-9]\b | _. | \#. | [a-z][a-z] | // | .$" |
vim-surround
Based on surround.vim, the plugin is used to work with surrounding characters like parenthesis, brackets, quotes, and XML tags.
t
or <
as <desired char>
or <existing char>
will do tags and enter tag entry mode. Using <CR>
instead of >
to finish changing a tag will preserve any existing attributes.
Surround is enabled by default, but can be disabled by setting "vim.surround": false
.
Surround Command | Description |
---|---|
d s <existing char> |
Delete existing surround |
c s <existing char> <desired char> |
Change surround existing to desired |
y s <motion> <desired char> |
Surround something with something using motion (as in "you surround") |
S <desired char> |
Surround when in visual modes (surrounds full selection) |
Some examples:
"test"
with cursor inside quotes type cs"' to end up with'test'
"test"
with cursor inside quotes type ds" to end up withtest
"test"
with cursor inside quotes type cs"t and enter 123> to end up with<123>test</123>
test
with cursor on word test type ysaw) to end up with(test)
vim-commentary
Similar to vim-commentary, but uses the VSCode native "Toggle Line Comment" and "Toggle Block Comment" features.
Usage examples:
gc
- toggles line comment. For examplegcc
to toggle line comment for current line andgc2j
to toggle line comments for the current line and the next two lines.gC
- toggles block comment. For examplegCi)
to comment out everything within parenthesis.
vim-indent-object
Based on vim-indent-object, it allows for treating blocks of code at the current indentation level as text objects. Useful in languages that don't use braces around statements (e.g. Python).
Provided there is a new line between the opening and closing braces / tag, it can be considered an agnostic cib
/ci{
/ci[
/cit
.
Command | Description |
---|---|
<operator>ii |
This indentation level |
<operator>ai |
This indentation level and the line above (think if statements in Python) |
<operator>aI |
This indentation level, the line above, and the line after (think if statements in C/C++/Java/etc) |
vim-sneak
Based on vim-sneak. To activate sneak, you need to make sure that sneak
is set to true
in settings.json (default is false
).
"vim.sneakUseIgnorecaseAndSmartcase": true
can be set if desired to allow for respecting vim.ignorecase
and vim.smartcase
while sneaking (default is false
)
Once sneak is active, initiate motions using the following commands. For operators sneak uses z
instead of s
because s
is already taken by the surround plugin.
Motion Command | Description |
---|---|
s<char><char> |
Move forward to the first occurence of <char><char> |
S<char><char> |
Move backward to the first occurence of <char><char> |
<operator>z<char><char> |
Perform <operator> forward to the first occurence of <char><char> |
<operator>Z<char><char> |
Perform <operator> backward to the first occurence of <char><char> |
Input Method
Disable input method when exiting Insert Mode.
Setting | Description |
---|---|
vim.autoSwitchInputMethod.enable |
Boolean denoting whether autoSwitchInputMethod is on/off. |
vim.autoSwitchInputMethod.defaultIM |
Default input method. |
vim.autoSwitchInputMethod.obtainIMCmd |
The full path to command to retrieve the current input method key. |
vim.autoSwitchInputMethod.switchIMCmd |
The full path to command to switch input method, with {im} a placeholder for input method key. |
You can use any third-party program to switch input methods. We recommend im-select, and the following will walkthrough installation and configuration for im-select.
Install im-select
Follow the installation guide to install im-select
Find your default input method key
MacOS:
Switch your input method to English, and run the following in your terminal:
$ /usr/local/bin/im-select
the program will output your default input method (eg.
com.apple.keylayout.US
). The table below is a list of common English key layouts for MacOS.Key Description com.apple.keylayout.US U.S. com.apple.keylayout.ABC ABC com.apple.keylayout.British British com.apple.keylayout.Irish Irish com.apple.keylayout.Australian Australian com.apple.keylayout.Dvorak Dvorak com.apple.keylayout.Colemak Colemak
Configure
vim.autoSwitchInputMethod
.MacOS:
Given default input method key of
com.apple.keylayout.US
andim-select
saved to the default location. The configuration is:"vim.autoSwitchInputMethod.enable": true, "vim.autoSwitchInputMethod.defaultIM": "com.apple.keylayout.US", "vim.autoSwitchInputMethod.obtainIMCmd": "/usr/local/bin/im-select", "vim.autoSwitchInputMethod.switchIMCmd": "/usr/local/bin/im-select {im}"
Windows:
Given default input method key of
1033
(en_US) and yourim-select.exe
is located atD:/bin
. The configuration is:"vim.autoSwitchInputMethod.enable": true, "vim.autoSwitchInputMethod.defaultIM": "1033", "vim.autoSwitchInputMethod.obtainIMCmd": "D:\\bin\\im-select.exe", "vim.autoSwitchInputMethod.switchIMCmd": "D:\\bin\\im-select.exe {im}"
If using an alternative program to switch input methods and it requires a command-line options to switch or get the input method, you should add the options to the configuration. For example, if your program's usage is my-program -s imKey
to switch input method, your vim.autoSwitchInputMethod.switchIMCmd
should be /path/to/my-program -s {im}
.
🎩 VSCodeVim tricks!
Vim has a lot of nifty tricks and we try to preserve some of them:
gd
- jump to definition.gq
- on a visual selection reflow and wordwrap blocks of text, preserving commenting style. Great for formatting documentation comments.gb
- adds another cursor on the next word it finds which is the same as the word under the cursor.af
- visual mode command which selects increasingly large blocks of text. For example, if you had "blah (foo [bar 'ba|z'])" then it would select 'baz' first. If you pressedaf
again, it'd then select [bar 'baz'], and if you did it a third time it would select "(foo [bar 'baz'])".gh
- equivalent to hovering your mouse over wherever the cursor is. Handy for seeing types and error messages without reaching for the mouse!
📚 F.A.Q.
None of the native Visual Studio Code ctrl
(e.g. ctrl+f
, ctrl+v
) commands work
Set the useCtrlKeys
setting to false
.
Moving j
/k
over folds opens up the folds
Try setting vim.foldfix
to true
. This is a hack; it works fine, but there are side effects (see issue#22276).
Key repeat doesn't work
Are you on a Mac? Did you go through our mac-setup instructions?
There are annoying intellisense/notifications/popups that I can't close with <esc>
! Or I'm in a snippet and I want to close intellisense
Press shift+<esc>
to close all of those boxes.
How can I use the commandline when in Zen mode or when the status bar is disabled?
This extension exposes a remappable command to show a vscode style quick-pick, limited functionality, version of the commandline. This can be remapped as follows in visual studio keybindings.json settings file.
{
"key": "shift+;",
"command": "vim.showQuickpickCmdLine",
"when": "editorTextFocus && vim.mode != 'Insert'"
}
Or for Zen mode only:
{
"key": "shift+;",
"command": "vim.showQuickpickCmdLine",
"when": "inZenMode && vim.mode != 'Insert'"
}
❤️ Contributing
This project is maintained by a group of awesome people and contributions are extremely welcome :heart:. For a quick tutorial on how you can help, see our contributing guide.
Special shoutouts to cool contributors
- Thanks to @xconverge for making over 100 commits to the repo. If you're wondering why your least favorite bug packed up and left, it was probably him.
- Thanks to @Metamist for implementing EasyMotion!
- Thanks to @sectioneight for implementing text objects!
- Special props to Kevin Coleman, who created our awesome logo!
- Shoutout to @chillee aka Horace He for his contributions and hard work.