My VsCode Setup
I want NeoVim to be my main driver and have given it multiple focused attempts. However, I seem to always have skill issues to get it to work the way I want it to. Installing plugins and themes are the easy part. The problem lies with the LSP setup, debugging, easy search and replace and renaming or refactoring of files and classes - where the strengths of an IDE truly shine. Furthermore, it takes a lot of time to learn and re-learn how to use and setup and end up you spend more time trying to figure out your workflow. I am all for investing time spent to get better at a tool, but the trade-off at this point doesn’t seem to favour me. Again, maybe it is a skill issue on my part.
As I mostly work with .NET, my favourite IDE for .NET is Rider. However, my current workplace does not allow the use of it, so the next best thing is VsCode. I am not a big fan of VsCode. It is … okay… and it just gets the job done.
Themes are also another issue. I used to like atom one dark but nowadays, I very much prefer black metal themes or base 16 themes. It is not as colourful, colors are more muted, easier on the eyes and overall much simpler to look at and work with. However, I couldn’t find similar black metal themes in the VsCode marketplace :( . So I spent some time and made my favourite theme out of the lot “Black Metal Bathory” using Theme Studio and copilot to help refine / publish it. Would love to work on the other themes and port them over to VsCode if I have the time and discipline for that.
Setup
After much tinkering, I finally settled on a configuration in VsCode and these are the plugins I use:
- C# base plugin
- Git Lens
- VsCode Vim
- NerdTree
- Harpoon
- My own theme referenced from metalelf0, Black Metal Bathory
The important part for me are the key bindings. In NeoVim, the <leader> key is super useful and it was a pain to replicate that over in VsCode. For some reason, the .vimrc file defined by the plugin doesn’t work well for me and I resorted to just plain mapping it back to the vscode built-in apis. Below shows the json snippet for my Preferences: Open User Settings(Json).
settings.json
"vim.normalModeKeyBindings": [
{
"before": [
"<leader>",
"h",
"h"
],
"commands": [
"vscode-harpoon.editEditors"
]
},
{
"before": [
"<leader>",
"h",
"a"
],
"commands": [
"vscode-harpoon.addEditor"
]
},
{
"before": [
"<leader>",
"h",
"q"
],
"commands": [
"vscode-harpoon.addEditor1"
]
},
{
"before": [
"<leader>",
"g",
"q"
],
"commands": [
"vscode-harpoon.gotoEditor1"
]
},
{
"before": [
"<leader>",
"h",
"w"
],
"commands": [
"vscode-harpoon.addEditor2"
]
},
{
"before": [
"<leader>",
"g",
"w"
],
"commands": [
"vscode-harpoon.gotoEditor2"
]
},
{
"before": [
"<leader>",
"h",
"e"
],
"commands": [
"vscode-harpoon.addEditor3"
]
},
{
"before": [
"<leader>",
"g",
"e"
],
"commands": [
"vscode-harpoon.gotoEditor3"
]
},
{
"before": [
"<leader>",
"h",
"r"
],
"commands": [
"vscode-harpoon.addEditor4"
]
},
{
"before": [
"<leader>",
"g",
"r"
],
"commands": [
"vscode-harpoon.gotoEditor4"
]
},
{
"before": [
"<leader>",
"h",
"t"
],
"commands": [
"vscode-harpoon.addEditor5"
]
},
{
"before": [
"<leader>",
"g",
"t"
],
"commands": [
"vscode-harpoon.gotoEditor5"
]
},
{
"before": [
"<leader>",
"h",
"y"
],
"commands": [
"vscode-harpoon.addEditor6"
]
},
{
"before": [
"<leader>",
"g",
"y"
],
"commands": [
"vscode-harpoon.gotoEditor6"
]
},
{
"before": [
"<leader>",
"h",
"u"
],
"commands": [
"vscode-harpoon.addEditor7"
]
},
{
"before": [
"<leader>",
"g",
"u"
],
"commands": [
"vscode-harpoon.gotoEditor7"
]
},
{
"before": [
"<leader>",
"h",
"i"
],
"commands": [
"vscode-harpoon.addEditor8"
]
},
{
"before": [
"<leader>",
"g",
"i"
],
"commands": [
"vscode-harpoon.gotoEditor8"
]
},
{
"before": [
"<leader>",
"h",
"o"
],
"commands": [
"vscode-harpoon.addEditor9"
]
},
{
"before": [
"<leader>",
"g",
"o"
],
"commands": [
"vscode-harpoon.gotoEditor9"
]
},
{
"before": [
"<leader>",
"e",
"f"
],
"commands": [
"workbench.files.action.showActiveFileInExplorer"
]
},
{
"before": [
"<leader>",
"q",
"o"
],
"commands": [
"workbench.action.closeOtherEditors"
]
},
{
"before": [
"g",
"r"
],
"commands": [
"references-view.findReferences"
]
},
{
"before": [
"g",
"i"
],
"commands": [
"references-view.findImplementations"
]
},
{
"before": [
"g",
"d"
],
"commands": [
"editor.action.revealDefinition"
]
},
{
"before": [
"r",
"n"
],
"commands": [
"editor.action.rename"
]
},
{
"before": [
"<leader>",
"f",
"f"
],
"commands": [
"workbench.action.quickOpen"
]
},
{
"before": [
"<leader>",
"f",
"p"
],
"commands": [
"workbench.action.showCommands"
]
},
{
"before": [
"<leader>",
"f",
"t"
],
"commands": [
"workbench.action.findInFiles"
]
},
{
"before": [
"<leader>",
"f",
"d"
],
"commands": [
"editor.action.formatDocument"
]
},
{
"before": [
"<C-.>"
],
"commands": [
"gitlens.toggleFileBlame:key"
]
},
{
"before": [
"<leader>",
"z",
"m"
],
"commands": [
"workbench.action.toggleZenMode"
]
},
{
"before": [
"<leader>",
"e",
"e"
],
"commands": [
"workbench.action.toggleSidebarVisibility"
],
"when": [
"!editorTextFocus"
]
},
{
"before": [
"<leader>",
"m",
"m"
],
"commands": [
"bookmarks.toggle"
]
},
{
"before": [
"<leader>",
"m",
"l"
],
"commands": [
"bookmarks.toggleLabeled"
]
},
{
"before": [
"<leader>",
"b"
],
"commands": [
"bookmarks.listFromAllFiles"
]
},
{
"before": [
"<leader>",
"c"
],
"commands": [
"bookmarks.clear"
]
},
{
"before": [
"<leader>",
"t",
"o"
],
"commands": [
"workbench.action.terminal.focus"
]
}
],
"vim.visualModeKeyBindings": [
{
"before": [
"<leader>",
"f",
"t"
],
"commands": [
"workbench.action.findInFiles"
]
},
{
"before": [
"<leader>",
"l"
],
"commands": [
"editor.action.selectHighlights"
]
}
],
Short Description of the Setup
I like having NerdTree key bindings to move around the file explorer. One downside is that mapping q is a nightmare. I found out that using the default keybinding Shift + Esc to close the side window works out the best. For file search, text search, opening up shortcuts like telescope, they are all part of the <leader>f<key> operation.
For window splits and moving the cursor between them, I use <leader>vs for vertical split and <leader>hs for horizontal split. Then, I use Ctrl+W for closing tabs, Ctrl+Shift+H/J/K/L for moving cursor between tab windows, and Ctrl+H/J/K/L for moving between tabs within a window. This is just personal preference, there are already in-built vim bindings to do all of these but I find these to be easier for me.
Exporting and Backing Up
At first I couldn’t find a good way to do this. “Do I only backup the settings.json?”, “Where is the keybindings settings file?”, “I don’t want to sync settings to my GitHub account…”.
Turns out, we can just export the Default VsCode Profile.
Backing Up
Search in VsCode for Profiles: Export Profile. Select the ... and click on export. Name the file as Default.code-profile. All settings, keybindings and plugins are defined in this one file. This makes things much easier to work with.
Importing Profile as Default Profile
If you are just importing the profile as some other profile that you switch to occasionally, then you can name it however you want. However, I think the point of this entire thing is to import the profile as the default profile that we work with.
Hence, the reason is: even though you can import profiles into VsCode, you cannot make them the default profile. There can only be one default profile. In order to make an imported profile a default profile, you have to import the profile that is named Default.
You will then be prompted to do a replace, which means that your current settings will all be gone, which shouldn’t be an issue assuming you are importing to a new setup.
This also works on Antigravity IDE as it is a fork of VsCode.