Scott Hanselman

Tabs vs Spaces - A peaceful resolution with EditorConfig in Visual Studio. Plus .NET Extensions!

September 29, 2017 Comment on this post [23] Posted in VS2017
Sponsored By

The culture wars continue. The country is divided with no end in sight. Tabs or spaces? There's even an insane (IMHO) assertion that the spaces people make more money.

I'm going with Gina Trapani on this one. I choose working code.

Teams can fight but the problem of formatting code across teams is solved by EditorConfig. I'm surprised more people don't know about it and use it, so this blog post is my small way of getting the word out. TELL THE PEOPLE.

Take a project and make a new .editorconfig file and put this in it. I'll use a dotnet new console example hello world app.

[*.cs]
indent_style = tab
indent_size = tab
tab_size = 4

I've set mine in this example to just *.cs, but you could also say [*.{cs,js}] or just [*] if you like, as well as have multiple sections.

You'll check this file in WITH your project so that everyone on the team shares the team's values.

Here in Notepad2 we can see someone has used spaces for whitespace, like a savage. Whitespace appears as pale dots in this editor.

image

I'll open this project in Visual Studio 2017 which supports the EditorConfig file natively. Notice the warning at the bottom where VS lets me know that this project has conventions that are different than my own.

user preferences for this file type are overwidden by this project's coding conventions

VS Format Document commands will use tabs rather than spaces for this project. Here is the same doc reformatted in VS:

image

At this point I'm comforted that the spaces have been defeated and that cooler heads have prevailed - at least for this project.

.NET Extensions to EditorConfig

Even better, if your editor supports it, you can include "EditorConfig Extensions" for specific files or languages. This way your team can keep things consistent across projects. If you're familiar with FxCop and StyleCop, this is like those.

There's a ton of great .NET EditorConfig options you can set to ensure the team uses consistent Language Conventions, Naming Conventions, and Formatting Rules.

  • Language Conventions are rules pertaining to the C# or Visual Basic language, for example, var/explicit type, use expression-bodied member.
  • Formatting Rules are rules regarding the layout and structure of your code in order to make it easier to read, for example, Allman braces, spaces in control blocks.
  • Naming Conventions are rules respecting the way objects are named, for example, async methods must end in "Async".

You can also set the importance of these rules with things like "suggestion," or "warning," or even "error."

As an example, I'll set that my team wants predefined types for locals:

dotnet_style_predefined_type_for_locals_parameters_members = true:error

Visual Studio here puts up a lightbulb and the suggested fix because my team would rather I use "string" than the full "System.String.

Visual Studio respects EditorConfig

The excellent editorconfig for .NET docs have a LOT of great options you can use or ignore. Here's just a FEW (controversial) examples:

  • csharp_new_line_before_open_brace - Do we put open braces at the end of a line, or on their own new line?
  • csharp_new_line_before_members_in_object_initializers - Do we allow A = 3, B = 4, for insist on a new line for each?
  • csharp_indent_case_contents - Do we freakishly line up all our switch/case statements, or do we indent each case like the creator intended?
  • You can even decide on how you Want To Case Things And Oddly Do Sentence Case: pascal_case, camel_case, first_word_upper, all_upper, all_lower

If you're using Visual Studios 2010, 2012, 2013, or 2015, fear not. There's at least a basic EditorConfig free extension for you that enforces the basic rules. There is also an extension for Visual Studio Code to support EditorConfig files that takes just seconds to install although I don't see a C# one for now, just one for whitespace.


Sponsor: Check out JetBrains Rider: a new cross-platform .NET IDE. Edit, refactor, test and debug ASP.NET, .NET Framework, .NET Core, Xamarin or Unity applications. Learn more and download a 30-day trial!

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Hosting By
Hosted in an Azure App Service
September 29, 2017 3:42
Thanks for the article! I use this in every project I work on and introduce it in pretty much every OSS I contribute to. There are a few rough edges I really with would be addressed with the Visual Studio 2017 implementation though.

First, and most important to me, I really wish that File -> New Project and File -> New File would adhere to my settings. Its really frustrating to always have to reformat every file when I create a new solution.

I really wish that I could set my preferences for *.csproj files. Not matter what I do, my csproj file always gets formatted with 2 space indentations.

Also, for file types like json or xml, it gets kind of frustrating that when Visual Studio modifies the file (for example adding an npm package to project.json or binding redirects getting added to web.config), the file always gets formatted with spaces regardless of my editor settings.

Other than this, I really love this feature; especially the csharp language preferences! :)
September 29, 2017 10:22
Seriously, do people still, in the year 2017, waste brain cycles to argue over things like tabs vs spaces? Grow up everyone. It was not an interesting debate 30 years ago, and sure as heck is not today. Now get back to work!
September 29, 2017 10:28
Crtl-K Ctrl-D, now idea what it uses in the engine bay but fixes the formatting for me so i can think about the code :)
September 29, 2017 10:36
You have an error in the snippet
I corrected it:

[*.cs]
indent_style = space
indent_size = 4
tab_size = 4
September 29, 2017 11:44
Here is a link to a very generic .editorconfig file I wrote supporting the following file types:


  • C# - .cs, .csx, .cake

  • Visual Basic - .vb

  • Script - .sh, .ps1, psm1

  • Configuration - .json, .xml, .yml, .config, .props, .targets, .nuspec, .resx, .ruleset, .vsixmanifest, .vsct

  • HTML - .htm, .html

  • JavaScript - .js, .ts

  • CSS - .css, .scss, .less

  • Markdown - .md

  • Visual Studio - .sln, .csproj, .vbproj, .vcxproj, .vcxproj.filters, .proj, .projitems, .shproj



All C# related code styles are also consistent with StyleCop's default styles.

https://github.com/RehanSaeed/EditorConfig
September 29, 2017 12:43
Space people make more money ?

Probably, but correlation is not causality. It is very likely that those earning more are senior programmers, who prefer spaces rather than tabs.
September 29, 2017 14:17
I would be one of those old people, maybe you would call us seniors if you were polite.
I have no clue why this is even a discussion. You can format almost any language
almost any way you want using the tools available. Use both spaces and tabs if you want. Just run
them through a formatter before viewing the code. I do this on pulls of code.
September 29, 2017 15:49
I don't indent my code. I type it in one line in uglify form. That way people will notice I am a pro coder.
September 29, 2017 17:22
What is the advantage of using the EditorConfig vs. just setting your format preferences in Visual Studio? Is it just so that you can have your formatting styles as part of the project, and not a setting within the editor?
September 29, 2017 17:48
IMHO, the editor (Visual Studio) should leave the current style of a file unchanged BUT display it to the user according to his preferred style. Like fonts and colors.
Problem solved.
September 29, 2017 19:52
I think you may be the exception to this rule however...

Developers Who Use Spaces Make More Money Than Those Who Use Tabs
https://stackoverflow.blog/2017/06/15/developers-use-spaces-make-money-use-tabs/
September 29, 2017 19:56
Why can't the version control system handle this? Git already manages line endings for us, so we don't have to fight over whether to put a CR before the LF or not. Why not make something similar for line beginnings?

After `git config --global core.indent 4s` I don't have to care what you have in your EditorConfig file, or what's in the files on the remote. My local clone will have correct indentation - as will yours, after you do `git config --global core.indent 4t`.
September 29, 2017 23:39
I also install the Format document on Save extension so I never have to invoke Format Document manually. #TeamTabs
September 30, 2017 1:00
The real question is where to put the first `{`. I personally HATE it on its own line. What a total waste of space - worse, it's a waste of an entire LINE. Put it at the end of the current line. For those people who say "I like to see which ending bracket corresponds to the opening bracket." Really? With the styling we get in VS, there is a vertical line showing you what it goes to. Not to mention, it seems like most people use the default 4 characters (per tab) which to me is HUGE and also over doing it. But with 4 you can easily discern between which sub element you are working with without the need of your separate lined `{`.

And as for the "working code" theory. That is great if you, nor anyone else in the future, has to fix/enhance the app. Difficult to read code where lines are inconsistently spaced/tabbed to me screams sloppy coding practices and thus potentially lousy code as well. I am not saying be anal about it, but I have no faith in ugly code that it is in the best shape that it can be without holes.

A simple Ctrl-E Ctrl-D is all it takes.
</soapbox>
September 30, 2017 1:33
Spaces. You of all people surprise me Scott.
September 30, 2017 11:58
Spacewars: soon in a theatre near you.
September 30, 2017 21:01
Kevin,
Few things about putting chicken lips on their own line is that it is easier to see if they are all lined up (the opening with the closing ones) making it easier to find missing ones.

It's also easier to copy and paste the block. You don't have to go up one line and then scroll to the end to grab one little measly chicken lip.

And if you are paid by the line of code written, free money!
October 01, 2017 7:40
Gold Jerry. Gold!!!
October 01, 2017 9:16
I don't get it. So you say people shouldn't fight about tabs/spaces, but then just show a solution that makes everyone on the same team use the same method.
Why can't it be more similar to the way git handles CRLF? Let every client defines how it wants to checkout the file, and view it locally in his own editor, and always commit after replacing all the spaces to some 'canonical' value (be it tabs or spaces, it doesn't matter - only the CI server 'sees' those files before it compiles/packages them).
Of course, it might be extended to any similar formatting argument.
I'm sure such a solution isn't too complicated. Maybe there are some git-hooks that already do it.
October 01, 2017 17:25
Tabs. Come on people! In all the debates I've ever read about tabs vs spaces, I've never seen anyone bring up the point I'm about to make for why tabs are better:

When you use tabs, it enables you to select blocks of code with the mouse (yes, the mouse) and be accurate with your selection so that it includes no leading or trailing spaces, without needing to click at the exact spot where the code block begins or ends.

With tabs, I can click-to-drag slightly before the start of the first line of the block of code I want to cut/copy and have the selection only start where the line of code begins (not including a leading space or tab). I have the ability to be quicker at point-and-click because I don't have to take the extra few milliseconds to align my cursor perfectly.

It also speeds up navigation by using the arrow keys because the cursor will jump 4 spaces at a time, instead of just one space at a time. It also results in smaller file sizes and differentiates semantically between what is meant to be indentation and what is meant to be a space.

And yes, I use a combination of mouse and keyboard when coding, because the mouse is infinitely better at being able to point where my eye is looking than having to "walk" the cursor there by fiddling with the arrow keys. Insisting that using only the keyboard for editing code is better than using the mouse as well, is like insisting that a horse and carriage is better than a motor-vehicle simply because it was the first thing they knew. I'll bet that one day when we have brain-computer interfaces that let you code entirely without your hands, these people will still cling to their prehistoric keyboards.

Every time I've ever had to pair-program with someone who prefers keyboard-only, I've sat there watching in agony at how slowly they work because they are constantly "walking the cursor" around the screen with the arrow keys. Spaces makes that even worse.
October 02, 2017 9:16
@Shayne van Asperen I can certainly see the value there but I also have some experience on the flip side of that. I’ve found that some source control tools like BitBucket do a horibble job with alignment when using tabs. It’s also pretty whacky when combining tabs and spaces for aligning things by “=“, or C#/Java fields and auto props, HTML/XML attributes...etc. Admittedly not everyone does that kind of thing, but I’m a fan of “pretty” code. Just that feeling of, “Awe, this looks really nice. Here’s someone who cares.” Watching someone walk around the code whether tabs or spaces is painful to sit through. But patience prevails since not everyone is hip to Ctrl+Left or Right. But more to the subject, I’ve had to go with the flow in many an instance where the rules existed before I got there. For my setup, I use spaces. But for shared projects the .editorconfig keeps me in line with the team preference.
October 04, 2017 0:50
Tabs
October 09, 2017 17:41
Crtl-K Ctrl-D, now idea what it uses in the engine bay but fixes the formatting for me so i can think about the code :) mehndi design video rajasthani mehndi

Comments are closed.

Disclaimer: The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.