3 minute read

Code formatting is a bit of a religious discussion among developers. Spaces or tabs, whitespace positions, and line endings at certain elements are all part of the style guide to a project.

Personally, I’m a K&R guy with so many years in C-style languages and a love of terse code.

Unfortunately, almost all .net/Visual Studio tools identify with Allman when working with C#, C++, and similar languages (JavaScript/TypeScript all seem default to K&R).

If you’re doing any .net core work in Visual Studio code, you can customize the indentation styles; however, it’s not part of the normal settings.json file built into Visual Studio Code. Omnisharp requires you add your own configuration file to your machine or the project.

Adding omnisharp.json

There are several options for where your configuration options are placed.

  1. You can add a config.json file to the Omnisharp extension directory itself–a machine-based config.
  2. You can add an omnisharp.json file to your user profile under ./omnisharp
  3. You can add an omnisharp.json file to the root of your project.

Personally, I prefer option #3 so I can check the configuration into source control to keep the styles along with the project. It’s become one of the common spin-up files, like the .gitignore file, to a new project.

Before: Our Class in Allman

To start, let’s take a look at how Omnisharp formats documents by default following the Allman style. Here’s a bit of pseudo-code for an event model and some methods.

namespace Models
{
  public class Event
  {
    public int id { get; set; }
    public string name { get; set; }
    public string description { get; set; }
    public bool is_promoted { get; private set; }
    public string host { get; set; }
    public DateTime created_date { get; set; }
    public DateTime start_date { get; set; }
    public DateTime end_date { get; set; }

    public void Promote()
    {
      if (start_date > DateTime.UtcNow)
      {
        is_promoted = true;
      }
    }

    public void Demote()
    {
      if (start_date > DateTime.UtcNow)
      {
        is_promoted = false;
      }
    }
  }
}

Configuring omnisharp.json

Once you’ve added your configuration file, on to the options. Here are the options I’m using for the closest K&R experience.

{
  "FormattingOptions": {
    "NewLinesForBracesInTypes": false,
    "NewLinesForBracesInAccessors": false,
    "NewLinesForBracesInAnonymousMethods": false,
    "NewLinesForBracesInAnonymousTypes": false,
    "NewLinesForBracesInLambdaExpressionBody": false,
    "NewLinesForBracesInObjectCollectionArrayInitializers": false,
    "NewLinesForBracesInProperties": false,
    "NewLinesForBracesInControlBlocks": false,
    "NewLinesForBracesInMethods": false,
    "NewLineForClausesInQuery": false,
    "NewLineForCatch": false,
    "NewLineForElse": false,
    "NewLineForFinally": false,
    "NewLineForMembersInObjectInit": false,
    "NewLineForMembersInAnonymousTypes": false,
    "WrappingPreserveSingleLine": true,
    "WrappingKeepStatementsOnSingleLine": true,
    "UseTabs": true,
    "TabSize": 2,
    "SpaceAfterCast": false
  }
}

Yes, there is a mix of NewLine and NewLines prefixes. If you’re familiar with ReSharper, many of the settings are very similar.

The last one in there is personal preference and not K&R specific, but formats casts without excess spaces.

(int) value => (int)value

After: Our Class in K&R

Now, with our options saved, you can resave the file or force Format Document to fire with Shift+Alt+F (Windows) to see our code reformatted in K&R.

namespace Models {
  public class Event {
    public int id { get; set; }
    public string name { get; set; }
    public string description { get; set; }
    public bool is_promoted { get; private set; }
    public string host { get; set; }
    public DateTime created_date { get; set; }
    public DateTime start_date { get; set; }
    public DateTime end_date { get; set; }

    public void Promote() {
      if (start_date > DateTime.UtcNow) {
        is_promoted = true;
      }
    }

    public void Demote() {
      if (start_date > DateTime.UtcNow) {
        is_promoted = false;
      }
    }
  }
}

And we’re done! If you went the route of project-based configuration, save the omnisharp.json file off somewhere safe so you can add it to each of your projects.

comments powered by Disqus