Convert Figma logo to code with AI

VSCodeVim logoVim

:star: Vim for Visual Studio Code

14,637
1,380
14,637
1,793

Top Related Projects

89,018

Vim-fork focused on extensibility and usability

38,023

The official Vim repository

7,850

Native, lightweight modal code editor

9,796

IdeaVim – A Vim engine for JetBrains IDEs

26,050

Blazing fast Neovim framework providing solid defaults and a beautiful UI, enhancing your neovim experience.

18,785

🌙 LunarVim is an IDE layer for Neovim. Completely free and community driven.

Quick Overview

VSCodeVim/Vim is a Vim emulator extension for Visual Studio Code. It brings the power and efficiency of Vim's modal editing to the modern VS Code environment, allowing users to leverage their Vim skills while benefiting from VS Code's features and ecosystem.

Pros

  • Seamless integration of Vim keybindings and commands within VS Code
  • Extensive customization options to tailor the Vim experience
  • Regular updates and active community support
  • Compatibility with many VS Code features and other extensions

Cons

  • May have occasional performance issues, especially with large files
  • Some advanced Vim features or plugins may not be fully supported
  • Learning curve for users new to Vim or transitioning from other Vim emulators
  • Potential conflicts with default VS Code keybindings

Getting Started

  1. Install Visual Studio Code
  2. Open the Extensions view (Ctrl+Shift+X)
  3. Search for "Vim" and install the "Vim" extension by vscodevim
  4. Reload VS Code after installation
  5. Start using Vim commands in your editor

To enable some popular Vim features, add the following to your settings.json:

{
  "vim.useSystemClipboard": true,
  "vim.hlsearch": true,
  "vim.incsearch": true,
  "vim.easymotion": true,
  "vim.surround": true
}

For more advanced configuration, refer to the VSCodeVim documentation.

Competitor Comparisons

89,018

Vim-fork focused on extensibility and usability

Pros of Neovim

  • Full-fledged text editor with extensive plugin ecosystem
  • Better performance and lower resource usage
  • Supports asynchronous plugins and job control

Cons of Neovim

  • Steeper learning curve for new users
  • Requires more setup and configuration
  • Limited GUI options compared to VSCode integration

Code Comparison

Neovim configuration (init.vim):

set number
set relativenumber
set expandtab
set tabstop=2
set shiftwidth=2

VSCodeVim configuration (settings.json):

"vim.insertModeKeyBindings": [
  {
    "before": ["j", "j"],
    "after": ["<Esc>"]
  }
],
"vim.useSystemClipboard": true

Neovim offers more flexibility in configuration and scripting, while VSCodeVim provides easier integration with VSCode's features and extensions. Neovim is a standalone editor, whereas VSCodeVim brings Vim-like editing to the VSCode environment. Neovim is better suited for users who want a highly customizable, terminal-based editing experience, while VSCodeVim is ideal for those who prefer VSCode's ecosystem with Vim keybindings.

38,023

The official Vim repository

Pros of vim

  • Native Vim implementation with full feature set
  • Highly customizable and extensible through Vimscript
  • Faster performance, especially for large files

Cons of vim

  • Steeper learning curve for new users
  • Requires separate installation and configuration
  • Limited integration with modern IDE features

Code Comparison

vim:

:set number
:syntax on
:set autoindent
:set tabstop=4
:set shiftwidth=4

VSCodeVim:

"vim.useSystemClipboard": true,
"vim.hlsearch": true,
"vim.insertModeKeyBindings": [
  {"before": ["j", "j"], "after": ["<Esc>"]}
]

The vim code snippet shows basic configuration in a .vimrc file, while the VSCodeVim example demonstrates settings in VSCode's settings.json file. VSCodeVim aims to replicate Vim functionality within VSCode, offering a more accessible entry point for users familiar with modern IDEs. However, it may not provide the full depth of features and customization available in native Vim. VSCodeVim benefits from VSCode's extensive ecosystem and user-friendly interface, making it easier for newcomers to adopt Vim-like editing. Ultimately, the choice between vim and VSCodeVim depends on the user's preferences, workflow, and desired level of Vim integration.

7,850

Native, lightweight modal code editor

Pros of Oni2

  • Native performance and lower resource usage
  • Seamless integration of modal editing with modern IDE features
  • Cross-platform support (Windows, macOS, Linux)

Cons of Oni2

  • Smaller community and ecosystem compared to VSCodeVim
  • Less frequent updates and potentially slower bug fixes
  • Steeper learning curve for users new to modal editing

Code Comparison

Oni2 configuration (in OCaml):

open Oni_Core
open Oni_Model

let configuration = Configuration.create()
  |> Configuration.add("editor.fontSize", Json.of_int 14)
  |> Configuration.add("editor.lineNumbers", Json.of_string "relative")

VSCodeVim configuration (in JSON):

{
  "vim.useSystemClipboard": true,
  "vim.hlsearch": true,
  "vim.insertModeKeyBindings": [
    { "before": ["j", "j"], "after": ["<Esc>"] }
  ]
}

Oni2 offers a more programmatic approach to configuration using OCaml, while VSCodeVim relies on JSON for settings. This reflects Oni2's nature as a standalone application versus VSCodeVim's integration into VS Code's existing ecosystem.

9,796

IdeaVim – A Vim engine for JetBrains IDEs

Pros of IdeaVim

  • Seamless integration with JetBrains IDEs, providing a more native Vim experience
  • Supports a wider range of Vim plugins and custom mappings
  • Better performance and stability within the JetBrains ecosystem

Cons of IdeaVim

  • Limited to JetBrains IDEs, not available for other editors
  • May have a steeper learning curve for users new to JetBrains products
  • Some advanced Vim features may not be fully implemented

Code Comparison

IdeaVim:

set surround
set multiple-cursors
set commentary
set argtextobj
set textobj-entire

VSCodeVim:

"vim.useSystemClipboard": true,
"vim.handleKeys": {
  "<C-d>": true,
  "<C-s>": false,
  "<C-z>": false
}

The code snippets show configuration examples for each extension. IdeaVim uses Vim-style settings, while VSCodeVim uses JSON configuration in VS Code's settings.json file. IdeaVim's configuration is more concise and familiar to Vim users, while VSCodeVim requires adapting to VS Code's configuration style.

26,050

Blazing fast Neovim framework providing solid defaults and a beautiful UI, enhancing your neovim experience.

Pros of NvChad

  • Full-fledged Neovim configuration with a modern, aesthetically pleasing UI
  • Extensive plugin ecosystem and customization options out of the box
  • Faster startup time and better performance for large files

Cons of NvChad

  • Steeper learning curve for users new to Neovim
  • Requires separate installation and setup outside of VSCode
  • May have compatibility issues with some VSCode extensions

Code Comparison

NvChad (init.lua):

local custom_init_path = vim.api.nvim_get_runtime_file("lua/custom/init.lua", false)[1]

if custom_init_path then
  dofile(custom_init_path)
end

Vim (extension.ts):

export async function activate(context: vscode.ExtensionContext) {
  const vimImpl = new Vim();
  await vimImpl.activate(context);
  return vimImpl;
}

The code snippets show the initialization process for each project. NvChad uses Lua for configuration, while Vim uses TypeScript for VSCode integration. NvChad's approach allows for more direct customization of Neovim, while Vim focuses on emulating Vim functionality within VSCode's environment.

18,785

🌙 LunarVim is an IDE layer for Neovim. Completely free and community driven.

Pros of LunarVim

  • Comprehensive Neovim configuration with built-in LSP support
  • Extensive plugin ecosystem and customization options
  • Active community and regular updates

Cons of LunarVim

  • Steeper learning curve for users new to Vim/Neovim
  • Requires more system resources compared to VSCodeVim

Code Comparison

LunarVim configuration example:

-- LunarVim custom configuration
lvim.format_on_save = true
lvim.leader = "space"
lvim.builtin.terminal.active = true
lvim.builtin.nvimtree.setup.view.side = "left"
lvim.builtin.nvimtree.setup.renderer.icons.show.git = false

VSCodeVim configuration example:

// VSCodeVim settings in settings.json
"vim.useSystemClipboard": true,
"vim.hlsearch": true,
"vim.insertModeKeyBindings": [
  { "before": ["j", "j"], "after": ["<Esc>"] }
]

LunarVim offers a more comprehensive Neovim experience with built-in LSP support and extensive customization options. However, it has a steeper learning curve and requires more system resources. VSCodeVim provides a simpler Vim emulation within VSCode, making it easier for beginners but with fewer advanced features. The code examples showcase the different configuration approaches, with LunarVim using Lua and VSCodeVim using JSON in VSCode's settings.

Convert Figma logo designs to code with AI

Visual Copilot

Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot

README


VSCodeVim

Vim emulation for Visual Studio Code

VSCodeVim is a Vim emulator for Visual Studio Code.

  • 📃 Our change log outlines the breaking/major/minor updates between releases.
  • Report missing features/bugs on GitHub.
Table of Contents (click to expand)

💾 Installation

VSCodeVim can be installed via the VS Code Marketplace.

Mac

To enable key-repeating, execute the following in your Terminal, log out and back in, and then restart VS Code:

defaults write com.microsoft.VSCode ApplePressAndHoldEnabled -bool false              # For VS Code
defaults write com.microsoft.VSCodeInsiders ApplePressAndHoldEnabled -bool false      # For VS Code Insider
defaults write com.vscodium ApplePressAndHoldEnabled -bool false                      # For VS Codium
defaults write com.microsoft.VSCodeExploration ApplePressAndHoldEnabled -bool false   # For VS Codium Exploration users
defaults delete -g ApplePressAndHoldEnabled                                           # If necessary, reset global default

We also recommend increasing Key Repeat and Delay Until Repeat settings in System Settings/Preferences -> Keyboard.

Windows

Like real vim, VSCodeVim will take over your control keys. This behavior can be adjusted with the useCtrlKeys and handleKeys settings.

⚙️ Settings

The settings documented here are a subset of the supported settings; the full list is described in the FEATURES -> Settings tab of VSCodeVim's extension details page, which can be found in the extensions view of VS Code.

Quick Example

Below is an example of a settings.json file with settings relevant to VSCodeVim:

{
  "vim.easymotion": true,
  "vim.incsearch": true,
  "vim.useSystemClipboard": true,
  "vim.useCtrlKeys": true,
  "vim.hlsearch": true,
  "vim.insertModeKeyBindings": [
    {
      "before": ["j", "j"],
      "after": ["<Esc>"]
    }
  ],
  "vim.normalModeKeyBindingsNonRecursive": [
    {
      "before": ["<leader>", "d"],
      "after": ["d", "d"]
    },
    {
      "before": ["<C-n>"],
      "commands": [":nohl"]
    },
    {
      "before": ["K"],
      "commands": ["lineBreakInsert"],
      "silent": true
    }
  ],
  "vim.leader": "<space>",
  "vim.handleKeys": {
    "<C-a>": false,
    "<C-f>": false
  },
  // To improve performance
  "extensions.experimental.affinity": {
    "vscodevim.vim": 1
  }
}

VSCodeVim settings

These settings are specific to VSCodeVim.

SettingDescriptionTypeDefault Value
vim.changeWordIncludesWhitespaceInclude trailing whitespace when changing word. This configures the cw action to act consistently as its siblings (yw and dw) instead of acting as ce.Booleanfalse
vim.cursorStylePerMode.{Mode}Configure a specific cursor style for {Mode}. Omitted modes will use default cursor type Supported cursors: line, block, underline, line-thin, block-outline, and underline-thin.StringNone
vim.digraphs.{shorthand}Set custom digraph shorthands that can override the default ones. Entries should map a two-character shorthand to a descriptive string and one or more UTF16 code points. Example: "R!": ["🚀", [55357, 56960]]Object{"R!": ["🚀", [0xD83D, 0xDE80]]
vim.disableExtensionDisable VSCodeVim extension. This setting can also be toggled using toggleVim command in the Command PaletteBooleanfalse
vim.handleKeysDelegate configured keys to be handled by VS Code instead of by the VSCodeVim extension. Any key in keybindings section of the package.json that has a vim.use<C-...> in the when argument can be delegated back to VS Code by setting "<C-...>": false. Example: to use ctrl+f for find (native VS Code behavior): "vim.handleKeys": { "<C-f>": false }.String"<C-d>": true
"<C-s>": false
"<C-z>": false
vim.overrideCopyOverride VS Code's copy command with our own, which works correctly with VSCodeVim. If cmd-c/ctrl-c is giving you issues, set this to false and complain here.Booleanfalse
vim.useSystemClipboardUse the system clipboard register (*) as the default registerBooleanfalse
vim.searchHighlightColorBackground color of non-current search matchesStringfindMatchHighlightBackground ThemeColor
vim.searchHighlightTextColorForeground color of non-current search matchesStringNone
vim.searchMatchColorBackground color of current search matchStringfindMatchBackground ThemeColor
vim.searchMatchTextColorForeground color of current search matchStringNone
vim.substitutionColorBackground color of substitution text when vim.inccommand is enabledString"#50f01080"
vim.substitutionTextColorForeground color of substitution text when vim.inccommand is enabledStringNone
vim.startInInsertModeStart in Insert mode instead of Normal ModeBooleanfalse
vim.useCtrlKeysEnable Vim ctrl keys overriding common VS Code operations such as copy, paste, find, etc.Booleantrue
vim.visualstarIn visual mode, start a search with * or # using the current selectionBooleanfalse
vim.highlightedyank.enableEnable highlighting when yankingBooleanfalse
vim.highlightedyank.colorSet the color of yank highlightsStringrgba(250, 240, 170, 0.5)
vim.highlightedyank.durationSet the duration of yank highlightsNumber200

Neovim Integration

:warning: Experimental feature. Please leave feedback on neovim integration here.

To leverage neovim for Ex-commands,

  1. Install neovim
  2. Modify the following configurations:
SettingDescriptionTypeDefault Value
vim.enableNeovimEnable NeovimBooleanfalse
vim.neovimPathFull path to neovim executable. If left empty, PATH environment variable will be automatically checked for neovim path.String
vim.neovimUseConfigFileIf true, Neovim will load a config file specified by vim.neovimConfigPath. This is necessary if you want Neovim to be able to use its own plugins.Booleanfalse
vim.neovimConfigPathPath that Neovim will load as config file. If left blank, Neovim will search in its default location.String

Here's some ideas on what you can do with neovim integration:

Key Remapping

Custom remappings are defined on a per-mode basis.

"vim.insertModeKeyBindings"/"vim.normalModeKeyBindings"/"vim.visualModeKeyBindings"/"vim.operatorPendingModeKeyBindings"

  • Keybinding overrides to use for insert, normal, operatorPending and visual modes.
  • Keybinding overrides can include "before", "after", "commands", and "silent".
  • Bind jj to <Esc> in insert mode:
    "vim.insertModeKeyBindings": [
        {
            "before": ["j", "j"],
            "after": ["<Esc>"]
        }
    ]
  • Bind £ to goto previous whole word under cursor:
    "vim.normalModeKeyBindings": [
        {
            "before": ["£"],
            "after": ["#"]
        }
    ]
  • Bind : to show the command palette, and don't show the message on the status bar:
    "vim.normalModeKeyBindings": [
        {
            "before": [":"],
            "commands": [
                "workbench.action.showCommands",
            ],
            "silent": true
        }
    ]
  • Bind <leader>m to add a bookmark and <leader>b to open the list of all bookmarks (using the Bookmarks extension):
    "vim.normalModeKeyBindings": [
        {
            "before": ["<leader>", "m"],
            "commands": [
                "bookmarks.toggle"
            ]
        },
        {
            "before": ["<leader>", "b"],
            "commands": [
                "bookmarks.list"
            ]
        }
    ]
  • Bind ctrl+n to turn off search highlighting and <leader>w to save the current file:
    "vim.normalModeKeyBindings": [
        {
            "before":["<C-n>"],
            "commands": [
                ":nohl",
            ]
        },
        {
            "before": ["leader", "w"],
            "commands": [
                "workbench.action.files.save",
            ]
        }
    ]
  • Bind { to w in operator pending mode makes y{ and d{ work like yw and dw respectively:
    "vim.operatorPendingModeKeyBindings": [
        {
            "before": ["{"],
            "after": ["w"]
        }
    ]
  • Bind L to $ and H to ^ in operator pending mode makes yL and dH work like y$ and d^ respectively:
    "vim.operatorPendingModeKeyBindings": [
        {
            "before": ["L"],
            "after": ["$"]
        },
        {
            "before": ["H"],
            "after": ["^"]
        }
    ]
  • Bind > and < in visual mode to indent/outdent lines (repeatable):
    "vim.visualModeKeyBindings": [
        {
            "before": [
                ">"
            ],
            "commands": [
                "editor.action.indentLines"
            ]
        },
        {
            "before": [
                "<"
            ],
            "commands": [
                "editor.action.outdentLines"
            ]
        },
    ]
  • Bind <leader>vim to clone this repository to the selected location:
    "vim.visualModeKeyBindings": [
        {
            "before": [
                "<leader>", "v", "i", "m"
            ],
            "commands": [
                {
                    "command": "git.clone",
                    "args": [ "https://github.com/VSCodeVim/Vim.git" ]
                }
            ]
        }
    ]

"vim.insertModeKeyBindingsNonRecursive"/"normalModeKeyBindingsNonRecursive"/"visualModeKeyBindingsNonRecursive"/"operatorPendingModeKeyBindingsNonRecursive"

  • Non-recursive keybinding overrides to use for insert, normal, and visual modes
  • Example: Exchange the meaning of two keys like j to k and k to j to exchange the cursor up and down commands. Notice that if you attempted this binding normally, the j would be replaced with k and the k would be replaced with j, on and on forever. When this happens 'maxmapdepth' times (default 1000) the error message 'E223 Recursive Mapping' will be thrown. Stop this recursive expansion using the NonRecursive variation of the keybindings:
    "vim.normalModeKeyBindingsNonRecursive": [
        {
            "before": ["j"],
            "after": ["k"]
        },
        {
            "before": ["k"],
            "after": ["j"]
        }
    ]
  • Bind ( to 'i(' in operator pending mode makes 'y(' and 'c(' work like 'yi(' and 'ci(' respectively:
    "vim.operatorPendingModeKeyBindingsNonRecursive": [
        {
            "before": ["("],
            "after": ["i("]
        }
    ]
  • Bind p in visual mode to paste without overriding the current register:
    "vim.visualModeKeyBindingsNonRecursive": [
        {
            "before": [
                "p",
            ],
            "after": [
                "p",
                "g",
                "v",
                "y"
            ]
        }
    ],

Debugging Remappings

  1. Adjust the extension's logging level to 'debug' and open the Output window:

    1. Run Developer: Set Log Level from the command palette.
    2. Select Vim, then Debug
    3. Run Developer: Reload window
    4. In the bottom panel, open the Output tab and select Vim from the dropdown selection.
  2. Are your configurations correct?

    As each remapped configuration is loaded, it is logged to the Vim Output panel. Do you see any errors?

    debug: Remapper: normalModeKeyBindingsNonRecursive. before=0. after=^.
    debug: Remapper: insertModeKeyBindings. before=j,j. after=<Esc>.
    error: Remapper: insertModeKeyBindings. Invalid configuration. Missing 'after' key or 'commands'. before=j,k.
    

    Misconfigured configurations are ignored.

  3. Does the extension handle the keys you are trying to remap?

    VSCodeVim explicitly instructs VS Code which key events we care about through the package.json. If the key you are trying to remap is a key in which vim/vscodevim generally does not handle, then it's most likely that this extension does not receive those key events from VS Code. In the Vim Output panel, you should see:

    debug: ModeHandler: handling key=A.
    debug: ModeHandler: handling key=l.
    debug: ModeHandler: handling key=<BS>.
    debug: ModeHandler: handling key=<C-a>.
    

    As you press the key that you are trying to remap, do you see it outputted here? If not, it means we don't subscribe to those key events. It is still possible to remap those keys by using VSCode's keybindings.json (see next section: Remapping more complex key combinations).

Remapping more complex key combinations

It is highly recommended to remap keys using vim commands like "vim.normalModeKeyBindings" (see here). But sometimes the usual remapping commands are not enough as they do not support every key combinations possible (for example Alt+key or Ctrl+Shift+key). In this case it is possible to create new keybindings inside keybindings.json. To do so: open up keybindings.json in VSCode using CTRL+SHIFT+P and select Open keyboard shortcuts (JSON).

You can then add a new entry to the keybindings like so:

{
  "key": "YOUR_KEY_COMBINATION",
  "command": "vim.remap",
  "when": "inputFocus && vim.mode == 'VIM_MODE_YOU_WANT_TO_REBIND'",
  "args": {
    "after": ["YOUR_VIM_ACTION"]
  }
}

For example, to rebind ctrl+shift+y to VSCodeVim's yy (yank line) in normal mode, add this to your keybindings.json:

{
  "key": "ctrl+shift+y",
  "command": "vim.remap",
  "when": "inputFocus && vim.mode == 'Normal'",
  "args": {
    "after": ["y", "y"]
  }
}

If keybindings.json is empty the first time you open it, make sure to add opening [ and closing ] square brackets to the file as the keybindings should be inside a JSON Array.

Vim modes

Here are all the modes used by VSCodeVim:

Mode
Normal
Insert
Visual
VisualBlock
VisualLine
SearchInProgressMode
CommandlineInProgress
Replace
EasyMotionMode
EasyMotionInputMode
SurroundInputMode
OperatorPendingMode
Disabled

When rebinding keys in keybindings.json using "when clause context", it can be useful to know in which mode vim currently is. For example to write a "when clause" that checks if vim is currently in normal mode or visual mode it is possible to write the following:

"when": "vim.mode == 'Normal' || vim.mode == 'Visual'",

Vim settings

Configuration settings that have been copied from vim. Vim settings are loaded in the following sequence:

  1. :set {setting}
  2. vim.{setting} from user/workspace settings.
  3. VS Code settings
  4. VSCodeVim default values
SettingDescriptionTypeDefault Value
vim.autoindentCopy indent from current line when starting a new lineBooleantrue
vim.gdefaultWhen on, the :substitute flag g is default on. This means that all matches in a line are substituted instead of one. When a g flag is given to a :substitute command, this will toggle the substitution of all or one match.Booleanfalse
vim.hlsearchHighlights all text matching current searchBooleanfalse
vim.ignorecaseIgnore case in search patternsBooleantrue
vim.incsearchShow the next match while entering a searchBooleantrue
vim.inccommandShow the effects of the :substitute command while typingStringreplace
vim.joinspacesAdd two spaces after '.', '?', and '!' when joining or reformattingBooleantrue
vim.leaderDefines key for <leader> to be used in key remappingsString\
vim.maxmapdepthMaximum number of times a mapping is done without resulting in a character to be used. This normally catches endless mappings, like ":map x y" with ":map y x". It still does not catch ":map g wg", because the 'w' is used before the next mapping is done.Number1000
vim.reportThreshold for reporting number of lines changed.Number2
vim.shellPath to the shell to use for ! and :! commands.String/bin/sh on Unix, %COMSPEC% environment variable on Windows
vim.showcmdShow (partial) command in status barBooleantrue
vim.showmodenameShow name of current mode in status barBooleantrue
vim.smartcaseOverride the 'ignorecase' setting if search pattern contains uppercase charactersBooleantrue
vim.textwidthWidth to word-wrap when using gqNumber80
vim.timeoutTimeout in milliseconds for remapped commandsNumber1000
vim.whichwrapAllow specified keys that move the cursor left/right to move to the previous/next line when the cursor is on the first/last character in the line. See :help whichwrap.Stringb,s

.vimrc support

:warning: .vimrc support is currently experimental. Only remaps are supported, and you may experience bugs. Please report them!

Set vim.vimrc.enable to true and set vim.vimrc.path appropriately.

🖱️ 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 to cmd-d (OSX) or ctrl-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: There are performance implications to using this plugin. In order to change the status bar, we override the configurations in your workspace settings.json which results in increased 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.statusBarColors.commandlineinprogress": "#007ACC",
    "vim.statusBarColors.searchinprogressmode": "#007ACC",
    "vim.statusBarColors.easymotionmode": "#007ACC",
    "vim.statusBarColors.easymotioninputmode": "#007ACC",
    "vim.statusBarColors.surroundinputmode": "#007ACC",

vim-easymotion

Based on vim-easymotion and configured through the following settings:

SettingDescriptionTypeDefault Value
vim.easymotionEnable/disable easymotion pluginBooleanfalse
vim.easymotionMarkerBackgroundColorThe background color of the marker box.String'#0000'
vim.easymotionMarkerForegroundColorOneCharThe font color for one-character markers.String'#ff0000'
vim.easymotionMarkerForegroundColorTwoCharFirstThe font color for the first of two-character markers, used to differentiate from one-character markers.String'#ffb400'
vim.easymotionMarkerForegroundColorTwoCharSecondThe font color for the second of two-character markers, used to differentiate consecutive markers.String'#b98300'
vim.easymotionIncSearchForegroundColorThe font color for the search n-character command, used to highlight the matches.String'#7fbf00'
vim.easymotionDimColorThe font color for the dimmed characters, used when #vim.easymotionDimBackground# is set to true.String'#777777'
vim.easymotionDimBackgroundWhether to dim other text while markers are visible.Booleantrue
vim.easymotionMarkerFontWeightThe font weight used for the marker text.String'bold'
vim.easymotionKeysThe characters used for jump marker nameString'hklyuiopnm,qwertzxcvbasdgjf;'
vim.easymotionJumpToAnywhereRegexCustom regex to match for JumpToAnywhere motion (analogous to Easymotion_re_anywhere)String\b[A-Za-z0-9]|[A-Za-z0-9]\b|_.|#.|[a-z][A-Z]

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 CommandDescription
<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> wStart of word forwards
<leader><leader> bStart of word backwards
<leader><leader> lMatches beginning & ending of word, camelCase, after _, and after # forwards
<leader><leader> hMatches beginning & ending of word, camelCase, after _, and after # backwards
<leader><leader> eEnd of word forwards
<leader><leader> geEnd of word backwards
<leader><leader> jStart of line forwards
<leader><leader> kStart of line backwards
<leader><leader> / <char>... <CR>Search n-character
<leader><leader><leader> bdtTil character
<leader><leader><leader> bdwStart of word
<leader><leader><leader> bdeEnd of word
<leader><leader><leader> bdjkStart of line
<leader><leader><leader> jJumpToAnywhere 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.

vim-surround

Based on surround.vim, the plugin is used to work with surrounding characters like parentheses, brackets, quotes, and XML tags.

SettingDescriptionTypeDefault Value
vim.surroundEnable/disable vim-surroundBooleantrue

t or < as <desired> or <existing> will enter tag entry mode. Using <CR> instead of > to finish changing a tag will preserve any existing attributes.

Surround CommandDescription
y s <motion> <desired>Add desired surround around text defined by <motion>
d s <existing>Delete existing surround
c s <existing> <desired>Change existing surround to desired
S <desired>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 with test
  • "test" with cursor inside quotes type cs"t and enter 123> to end up with <123>test</123>

vim-commentary

Similar to vim-commentary, but uses the VS Code native Toggle Line Comment and Toggle Block Comment features.

Usage examples:

  • gc - toggles line comment. For example gcc to toggle line comment for current line and gc2j to toggle line comments for the current line and the next two lines.
  • gC - toggles block comment. For example gCi) to comment out everything within parentheses.

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.

CommandDescription
<operator>iiThis indentation level
<operator>aiThis indentation level and the line above (think if statements in Python)
<operator>aIThis indentation level, the line above, and the line after (think if statements in C/C++/Java/etc)

vim-sneak

Based on vim-sneak, it allows for jumping to any location specified by two characters.

SettingDescriptionTypeDefault Value
vim.sneakEnable/disable vim-sneakBooleanfalse
vim.sneakUseIgnorecaseAndSmartcaseRespect vim.ignorecase and vim.smartcase while sneakingBooleanfalse

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 CommandDescription
s<char><char>Move forward to the first occurrence of <char><char>
S<char><char>Move backward to the first occurrence of <char><char>
<operator>z<char><char>Perform <operator> forward to the first occurrence of <char><char>
<operator>Z<char><char>Perform <operator> backward to the first occurrence of <char><char>

CamelCaseMotion

Based on CamelCaseMotion, though not an exact emulation. This plugin provides an easier way to move through camelCase and snake_case words.

SettingDescriptionTypeDefault Value
vim.camelCaseMotion.enableEnable/disable CamelCaseMotionBooleanfalse

Once CamelCaseMotion is enabled, the following motions are available:

Motion CommandDescription
<leader>wMove forward to the start of the next camelCase or snake_case word segment
<leader>eMove forward to the next end of a camelCase or snake_case word segment
<leader>bMove back to the prior beginning of a camelCase or snake_case word segment
<operator>i<leader>wSelect/change/delete/etc. the current camelCase or snake_case word segment

By default, <leader> is mapped to \, so for example, d2i\w would delete the current and next camelCase word segment.

Input Method

Disable input method when exiting Insert Mode.

SettingDescription
vim.autoSwitchInputMethod.enableBoolean denoting whether autoSwitchInputMethod is on/off.
vim.autoSwitchInputMethod.defaultIMDefault input method.
vim.autoSwitchInputMethod.obtainIMCmdThe full path to command to retrieve the current input method key.
vim.autoSwitchInputMethod.switchIMCmdThe full path to command to switch input method, with {im} a placeholder for input method key.

Any third-party program can be used to switch input methods. The following will walkthrough the configuration using im-select.

  1. Install im-select (see installation guide)

  2. Find your default input method key

    • Mac:

      Switch your input method to English, and run the following in your terminal: /<path-to-im-select-installation>/im-select to output your default input method. The table below lists the common English key layouts for MacOS.

      KeyDescription
      com.apple.keylayout.USU.S.
      com.apple.keylayout.ABCABC
      com.apple.keylayout.BritishBritish
      com.apple.keylayout.IrishIrish
      com.apple.keylayout.AustralianAustralian
      com.apple.keylayout.DvorakDvorak
      com.apple.keylayout.ColemakColemak
    • Windows:

      Refer to the im-select guide on how to discover your input method key. Generally, if your keyboard layout is en_US the input method key is 1033 (the locale ID of en_US). You can also find your locale ID from this page, where the LCID Decimal column is the locale ID.

  3. Configure vim.autoSwitchInputMethod.

    • MacOS:

      Given the input method key of com.apple.keylayout.US and im-select located at /usr/local/bin. 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 the input method key of 1033 (en_US) and im-select.exe located at D:/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}"
      

The {im} argument above is a command-line option that will be passed to im-select denoting the input method to switch to. If using an alternative program to switch input methods, you should add a similar option to the configuration. For example, if the program's usage is my-program -s imKey to switch input method, the vim.autoSwitchInputMethod.switchIMCmd should be /path/to/my-program -s {im}.

ReplaceWithRegister

Based on ReplaceWithRegister, an easy way to replace existing text with the contents of a register.

SettingDescriptionTypeDefault Value
vim.replaceWithRegisterEnable/disable ReplaceWithRegisterBooleanfalse

Once active, type gr (say "go replace") followed by a motion to describe the text you want replaced by the contents of the register.

Motion CommandDescription
[count]["a]gr<motion>Replace the text described by the motion with the contents of the specified register
[count]["a]grrReplace the [count] lines or current line with the contents of the specified register
{Visual}["a]grReplace the selection with the contents of the specified register

vim-textobj-entire

Similar to vim-textobj-entire.

Adds two useful text-objects:

  • ae which represents the entire content of a buffer.
  • ie which represents the entire content of a buffer without the leading and trailing spaces.

Usage examples:

  • dae - delete the whole buffer content.
  • yie - will yank the buffer content except leading and trailing blank lines.
  • gUae - transform the whole buffer to uppercase.

vim-textobj-arguments

Similar to the argument text object in targets.vim. It is an easy way to deal with arguments inside functions in most programming languages.

Motion CommandDescription
<operator>iaThe argument excluding separators.
<operator>aaThe argument including separators.

Usage examples:

  • cia - change the argument under the cursor while preserving separators like comma ,.
  • daa - will delete the whole argument under the cursor and the separators if applicable.
SettingDescriptionTypeDefault Value
vim.argumentObjectOpeningDelimitersA list of opening delimitersString list["(", "["]
vim.argumentObjectClosingDelimitersA list of closing delimitersString list[")", "]"]
vim.argumentObjectSeparatorsA list of object separatorsString list[","]

🎩 VSCodeVim tricks!

VS Code 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 pressed af 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 VS Code style quick-pick version of the commandline, with more limited functionality. This can be remapped as follows in VS Code's 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'"
    }
    
  • How can I move the cursor by each display line with word wrapping?

    If you have word wrap on and would like the cursor to enter each wrapped line when using j, k, ↓ or ↑, set the following in VS Code's keybindings.json settings file.

    {
      "key": "up",
      "command": "cursorUp",
      "when": "editorTextFocus && vim.active && !inDebugRepl && !suggestWidgetMultipleSuggestions && !suggestWidgetVisible"
    },
    {
      "key": "down",
      "command": "cursorDown",
      "when": "editorTextFocus && vim.active && !inDebugRepl && !suggestWidgetMultipleSuggestions && !suggestWidgetVisible"
    },
    {
      "key": "k",
      "command": "cursorUp",
      "when": "editorTextFocus && vim.active && !inDebugRepl && vim.mode == 'Normal' && !suggestWidgetMultipleSuggestions && !suggestWidgetVisible"
    },
    {
      "key": "j",
      "command": "cursorDown",
      "when": "editorTextFocus && vim.active && !inDebugRepl && vim.mode == 'Normal' && !suggestWidgetMultipleSuggestions && !suggestWidgetVisible"
    }
    

    Caveats: This solution restores the default VS Code behavior for the j and k keys, so motions like 10j will not work. If you need these motions to work, other, less performant options exist.

  • I've swapped Escape and Caps Lock with setxkbmap and VSCodeVim isn't respecting the swap

    This is a known issue in VS Code, as a workaround you can set "keyboard.dispatch": "keyCode" and restart VS Code.

  • VSCodeVim is too slow!

    You can try adding the following setting, and reload/restart VSCode:

    "extensions.experimental.affinity": {
      "vscodevim.vim": 1
    }
    

    Caveats: One issue with using the affinity setting is that each time you update your settings file, the Vim plugin will reload, which can take a few seconds.

❤️ 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.

Buy Us A Coffee

Special shoutouts to:

  • 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.