## Visual Studio Code for Vim Users

A Vim user's guide to setting up Visual Studio Code

# An Editor Tale as Old as January 1, 1970

Like many people, my journey to Vim did not start at Vim; I spent many days and many nights downloading editors, installing plugins, and learning key bindings that have sinse been forgotten. I had been using SublimeText for a few years when I went into college, but like many poor soles, my first course was a Java course, which broke me, and, as despserate as I have ever been, I booked an appointment at the sinister medical practice of Dr. Java.

# Configuring Visual Studio Code

You should now be able to navigate files with vim keys like you would in vim, but we can make it better. Let’s start off with some basic VS Code settings that I have found make my experience a whole let better. Start off by opening your settings.json by opening your command palette and letting the “Preferences: Open Settings (JSON)” command rip. If you would like, there is a GUI, but this is faster and easier to show with minimal screenshots or long winded explanations. Here are some setitngs that I’m a big fan of.

"editor.rulers": [120]


Moving from an 80 character line limit to a 120 character line limit was a big positive change in my life, almost as big as getting my driver’s license or turning 21. It is just so freeing not to have to make ugly line break to follow some rule that you don’t even know why you follow.

"editor.minimap.enabled": false


I do not know what psychopath decided that using 10-20% of your screen realestate to show you a zoomed out view of your file was a good idea. Looking at you SublimeText.

"editor.fontSize": 10


This change was big for me, I think VS Code font is scaled up or my terminal font is scaled down. Either way, during my first use, VS Code felt super cramped since I usually work with at least two splits. If the default 12pt font size looks good and does not hurt your eyes, keep it, it’s your life.

"terminal.external.osxExec": "iTerm.App"


The handy command ⌘⇧c opens an external terminal window, so if you use something like iTerm, it’ll use that. Even better, if you have an existing iTerm window, it’ll just add a tab instead of a whole new window. Super handy if you want to do something like check logs for something unrelated to your current project without flooding the integrated terinal with unrelated history.

"terminal.integrated.shell.osx": "/usr/local/bin/zsh"


I use zshell.

"workbench.editor.showTabs": false


Since I’m a vim guy, I don’t really care for tabs, I only care what’s open in the current split, so it’s nice being able to see the entire filename and path within the project all the time. See an issue with this setting in the caveats section below.

"go.autocompleteUnimportedPackages": true,


Enables the great Go autocomplete I raved about earlier.

"python.linting.pylintPath": "/Users/rking/.pyenv/shims/pylint",


I unfortunately have to edit some Python every now and again, and this makes sure the Python plugin uses the linter for my currently active virtualenv so that way it knows about all the packages and such.

"python.linting.pylintArgs": ["--max-line-length=120"],


120 > 80 both mathematically and as a line length.

This last section is done in a different JSON config, specifically keybindings.json. It can be accessed similarly by using the “Preferences: Open Keyboard Shortcuts (JSON)” command.

[
{
"key": "ctrl+h",
"command": "workbench.action.focusLeftGroup"
},
{
"key": "ctrl+j",
"command": "workbench.action.focusAboveGroup"
},
{
"key": "ctrl+k",
"command": "workbench.action.focusBelowGroup"
},
{
"key": "ctrl+l",
"command": "workbench.action.focusRightGroup"
},
{
"key": "ctrl+shift+h",
"command": "workbench.action.moveActiveEditorGroupLeft"
},
{
"key": "ctrl+shift+j",
"command": "workbench.action.moveActiveEditorGroupDown"
},
{
"key": "ctrl+shift+j",
"command": "workbench.action.moveActiveEditorGroupUp"
},
{
"key": "ctrl+shift+j",
"command": "workbench.action.moveActiveEditorGroupRight"
},
{
"key": "ctrl+w s",
"command": "workbench.action.splitEditorDown"
},
{
"key": "ctrl+w v",
"command": "workbench.action.splitEditorRight"
},
{
"key": "cmd+m",
"command": "workbench.action.terminal.toggleTerminal"
}
]


The first four commands let me use C-{hjkl} to navigate between splits (known as groups in VS Code terminology) like I do in vim/tmux. The second four let me move editor groups around to change the order. The next two let me create vertical/horizontal splits using C-w {sv} like I do in vim. They don’t open exactly the same since the second time you make a vertical split, it sets it to thirds instead of a half and two quarters, but I have yet to find that a hinderance, if anything, it’s almost better because when you close the third vertical split, it goes back to halves. The last one is my preferred terminal hotkey.

# Configuring VSCodeVim

Most of this is going to be a repeat stuff you can read in the project’s docs, but I’ll just give an example and one rule to follow: never ever set vim key bindings in the main “keybindings” options for VS Code, you will find weird behavior. Doing it this way will ensure that the bindings only impact your vim setup. Note that we’re back in the settings JSON, not the keybindings JSON.

I find the syntax kind of strange, but here is an example of some of my vim key bindings that I missed in VS Code that I moved over relatively easily:

"vim.normalModeKeyBindings": [
{
"before": ["g", "h"],
"commands": [
"cursorHome",
]
},
{
"before": ["g", "j"],
"commands": [
"cursorBottom",
]
},
{
"before": ["g", "k"],
"commands": [
"cursorTop",
]
},
{
"before": ["g", "l"],
"commands": [
"cursorEnd",
]
},
],


What those do is make g-{hjkl} go to the beginning of the line, bottom line, top line, or end of the line respectively, which I find a lot more coherent than ^, \$, gg, G. You can rebind in all the vim major modes: “vim.normalModeKeyBindings”, “vim.insertModeKeyBindings”, etc., and all follow the same syntax. “before” is the keys you press before the command happens, and you either put in the command(s) you want to happen in a list, or you can use the “after” setting to specify an existing keybinding to emulate. So

{
"before": ["g", "h"],
"after": ["g", "j"]
}


Would cause the effect of gj whenever I pressed gh.

I haven’t been able to find a list of all the keybinding commands like “workbench.focusLeft”, but if you open up the keymaps GUI by going using the “Preferences: Keymaps” command or hitting ⌘K ⌘S, you can search for commands, and if one is already bound, you can copy the actual command by right clicking.

# VSCode Tips and Trick

• One plugin I really missed from vim was Tagbar, but I found the objects menu accessed with ⌘⇧o to fill the void quite nicely.
• If you want to edit some random file, don’t bother looking for an extension, VS Code will alert you once it opens if it has an extension to help.
• Some other hotkeys I regularly use:
• ⌘P: Equivalent of ctrlp, fuzzy file matcher, builtin, works like a charm.
• ⌘B: Toggles the left bar.
• ⌘⇧E: Takes me to the file tree.
• ⌘⇧M: Takes me to a pane with all the linting issues in my entire project.
• ⌘⇧D: Takes me to the Docker side menu, more on that in the plugins section.
• ⌘⇧K: Takes me to the Kubernetes side menu, again, more on that in the plugins section.

# Useful Plugins

Here are some additional plugins that I have installed that I find useful and have my leaving the editor less and less:

• Go: I don’t know how you’d write Go without it.
• Python: Everyone writes Python.
• Lisp: Everyone should write Common Lisp.
• ATS: I like ATS in case you haven’t noticed.
• GitLens: Really useful inline Git information and a nice sidemenu to view information quickly.
• Docker: Outside of Dockerfile syntax highlighting, which is alone worth the install, adds another handy dandy side menu to see all your containers, images, and registeries.
• Kubernetes: Helm chart syntax highlighting, plus another really nice sidebar for easily looking at cluster information.
• YAML: In case the above plugin wasn’t a clue, I edit a lot of YAML, this plugin adds syntax highlighting and makes navigating a large YAML file with the object brwoser easy.
• Better TOML: I don’t use rust, but I do edit TOML files sometimes.
• markdownlint: Who knew markdown was so strict?
• Markdown Preview Mermaid Support: If you happen to write Mermaid diagrams, makes your life a lot easier.
• LaTeX Workshop: One of the best LaTeX writing experiences I’ve ever had.
• Settings Sync: If you edit on multiple computers, like I do, makes keeping your configs synced an after thought.
• Bracket Pair Colorizer: I got used to this functionality during my Spacemacs stint, not as useful for Go, but required for not going crazy editing Lisp.

# Eye Candy (Not Useful) Plugins

Here are some plugins that aren’t useful, but I like a pretty setup:

• Gruvbox Themes I use gruvbox dark medium on everything, I find it really easy on the eyes with really good contrast.
• Material Icon Theme: Some pretty icons because you gotta have those.
• Titlebar-Less VSCode for mac: A stupid plugin to make your stupid editor look better in windowed mode on your stupid mac.
• Fix VSCode Checksums: Makes the corruption errors go away if you’re stupid enough to install the above plugin.

# Caveats

Two things that really stick out to me and still become a pain every now and again. The first being that the file browser and terminal not treated like “groups” so I cannot simply ctrl-{hjkl} to them like I would into a NERDTree, but I rarely find that a hinderance since the cmd+p file switcher works so well. The other is that I cannot remap :q to close the entire group instead of the current editor, so if I have a bunch of tabs open and want to completely remove a vertical split, it takes a few more key strokes. I have hopes that the second of the two complaints will be corrected as the plugin continues to mature.

# Closing Thoughts

I still use vim, probably everyday, but for what I feel it was born to do, edit files. Whenever I need to make a quick change or edit a config file, I still find myself typing those three magic letters and going to town, but when working on a large project with test suites and spralling dependencies, I use something that was made to do that, Visual Studio Code. Who’s to say that that the open source go language server will not get to the point that I can go back to using vim full time, or another shinny new editor will catch my eye, but for now, I am happy, I am writing code, and thinking about the code, not the writing of the code.

# Update 1/27/2019: Finding Zen

The second caveat that I mentioned above that was actually somewhat of an annoyance was the fact that I could not easily close an editor group or remap :q to close the entier group so if you wanted to remove a pane you may have to close quite a few tabs. zentabs fixed that for me. By simply setting the max amount of tabs per group to 1, bam, editor groups now behave like vim panes. I let one :q rip and since the group always only has one tab, it closes immediately and all is good with the world.

The only thing I would say my setup lacks at this point is more control over the line numbers and linting info. I would to be able to mvoe the linting indicators (warnings, errors, etc.) to appear next to the linee number and remove the always present scrollbar on the right. Can probably done with some settings tweaking or another extension. Will update this post with anymore tweaks that I find to make my VS Code experience better.