Forcing C# indentation in Visual Studio Code using Omnisharp
By Martijn Storck
For most programmers, indentation isn’t something you deal with daily. For years, I was lucky enough to standardise on projects that used two spaces for indentation, or hard tabs that I set to two spaces in my editor. This lead me to conclude that indentation was a solved problem. Turns out I was very wrong. At least as far as Visual Studio Code is concerned. The advice in this post works for any editor that uses the Omnisharp language server, though, such as Vim.
As I mentioned, I had vscode setup for two space indentation with the following settings:
{
"editor.detectIndentation": false,
"editor.tabSize": 2,
"editor.insertSpaces": true
}
Things started going south when I opened a .NET project that had .cs
files indented with four spaces. My first guess was to enable indentation detection, but that didn’t work. Next, I tried to add language specific settings as this:
{
"[csharp]": {
"editor.tabSize": 4,
}
}
This would still lead to mixed results and files that were reindented randomly. In general the experience was horrible. Likewise, the indentation options available from the status bar menu weren’t helpful at all.
The grass is always greener on the Go side
I was longing for a Go-like approach. When working in Go the common approach is to have your editor run go fmt
on save, which brings code formatting in line with the Go standard (with hard tabs for indent, by the way!). So whatever mess you make in your editor gets fixed as soon as you save.
Luckily, Omnisharp provides just this. Omnisharp is the language server that provides IDE-like features to editors, like IntelliSense, semantic syntax highlighting, and formatting! I assume you, like 9 million developers before you, are already using Omnisharp through the official C# extension for Visual Studio Code. If not, install that first:
Enabling format on save is handled by the editor.formatOnSave
vscode option, which you could enable for just csharp files to start:
{
"[csharp]": {
"editor.formatOnSave": true,
"editor.tabSize": 4,
}
}
Unfortunately, this still lead to weird behaviour and I’m not sure what’s going on. The C# extension feeds the indentation settings to OmniSharp, but I guess this is a matter of ‘garbage in = garbage out’ since those settings didn’t work outside of OmniSharp either.
Configuring indentation directly in Omnisharp
In the end, what seemed to fix it for me was to create a configuration file for OmniSharp in the root of the project, called omnisharp.json
with the following contents:
{
"FormattingOptions": {
"UseTabs": false,
"TabSize": 4,
"IndentationSize": 4
}
}
For a full list of available options, check out the Omnisharp wiki on Github. Including the omnisharp.json
file in your project seems like a good idea to me, since it unifies formatting options for all developers on a team, regardless of editor and editor configuration.
All that’s left now is enabling formatOnSave
and restarting the language server. Enjoy perfect commits with perfectly indented code!
Closing thoughts
A lot of language extensions in Visual Studio Code support this format on save option. Not just Go, but also the various Ruby extensions and even the Svelte language server provide this feature. If your team has agreed on a style it’s worth it to start enforcing that style, to create better readability and prevent discussions about where to put brackets or how to indent a switch statement.