A Programmers blog
Programming tips, code snippets, etc.


VSCode Vim-centric configuration and usage

Posted on

Configuring VSCode to be Vim-centric

I primarily write code in Python, Javascript, and C# using Vim with a billion plugins and configuration files inherited from past coworkers. Ever since I learned Vim I really enjoyed using it, but over time the plugins used have become unsupported and began breaking the complex plugin setup.

The more I use VSCode I realize I've been missing out on modern editor features. The obvious answer is to do some spring cleaning on the Vim setup, move everything to Neovim, find new supported plugins, and re-write any broken configurations. There are even ways to get VSCode language features into Neovim with Coc.nvim for example. Alas, that is quite a lot of work when I can just install VSCode with the VSCodeVim extension and be almost all of the way to a great development experience.

Keep in mind that you can and probably should use multiple editors. I doubt I will stop using Vim entirely. Visual Studio or Jetbrains Rider for example are amazing tools for working with C#. Tmux makes it really easy to work across multiple codebases with Vim.

Initial VSCode setup

  1. Install VSCode if you haven't already.
  2. Go to Extensions and install the VSCodeVim extension.
  3. After a editor restart you can now use vim keybindings.

My general settings file

To open your settings file open the command palette and type open settings. You should see an option like `Preferences: Open Settings (JSON). This is where your global user configuration lives. You can also have a per-project settings file too.

{
  // VSCodeVim extension settings, see https://github.com/VSCodeVim/Vim
  "vim.leader": "<space>",
  "vim.sneak": true,
  "vim.useSystemClipboard": true,
  "vim.surround": true,
  "vim.insertModeKeyBindings": [
    {
      "before": ["j", "j"],
      "after": ["<Esc>"]
    }
  ],
  "vim.normalModeKeyBindings": [
    {
      "before": ["<leader>", "g", "t"],
      "commands": ["editor.action.revealDefinition"]
    },
    {
      // cmd B to close it
      "before": ["<leader>", "t", "r"],
      "commands": ["workbench.view.explorer"]
    },
    {
      // cmd B to close it
      "before": ["<leader>", "g", "r"],
      "commands": ["workbench.view.explorer"]
    }
  ],
}

Keybinding settings:

You can open this in the command pallete under Preferences: Open Keyboard Shortcuts (JSON).

Note: some of these are just disabling ctrl behavior in Vim, it may be easier/better to just disabled all of those in the vim extension.

// Place your key bindings in this file to override the defaultsauto[]
[
    {
        // Removes the ctrl+j behavior so ctrl+j works to open the terminal pane in Windows
        "key": "ctrl+j",
        "command": "-extension.vim_ctrl+j",
        "when": "editorTextFocus && vim.active && vim.use<C-j> && !inDebugRepl"
    },
    {
        // Removes the ctrl+b behavior so ctrl+b works to open the side bar in Windows
        "key": "ctrl+b",
        "command": "-extension.vim_ctrl+j",
        "when": "editorTextFocus && vim.active && vim.use<C-j> && !inDebugRepl"
    },
    {
        // Removes the ctrl+b behavior so ctrl+b works to open the side bar in Windows
        "key": "ctrl+b",
        "command": "-extension.vim_ctrl+b",
        "when": "editorTextFocus && vim.active && vim.use<C-b> && !inDebugRepl && vim.mode != 'Insert'"
    }
]

Must know keybindings/vim shortcuts

Note that some/most of these are different with my configuration, but this is the link to official documentation.

For Vim, the Leader key is space in my configuration. All bindings are for normal mode unless specified. Ideally all frequent bindings require minimal movement to reduce strain.

ActionWindowsMacosVim or VSCode
Command PaletteSHIFT+CTRL+PSHIFT+CMD+P
Select file Explorer (toggle)SHIFT+CTRL+ESHIFT+CMD+E
Open/Close Side BarCTRL+BCMD+B
Open/Close Panel (commonly the terminal)CTRL+JCMD+J
FindCTRL+FCMD+F
Find and replaceCTRL+HOPT+CMD+F
SaveCTRL+SCMD+S:w
Go to definitiongd
Toggle line commentgc
Toggle block commentgC
Show hover tipsgh

Other tips

When in a python file you probably need to configure the python path

Official keybindings cheatsheet (no ctrl keys work with the Vim extension installed, but can be configured to):

Downsides compared to my old setup

One of the biggest benefits of the old setup vs the new one is how easy it was to multiplex terminals. I could split my view with 4 terminals or more, maybe all of them running vim, maybe not. I could switch between those with ctrl+<h,j,k,l> seamlessly (also works with vim splits). With VSCode...

Django tests don't integrate with VSCode at all, you will need an extension or just run them in the terminal.

You have to pay attention to what python interpreter you are using, I have the auto activation of python environments disabled because it is buggy when switching projects.