Tabs vs Spaces - A peaceful resolution with EditorConfig in Visual Studio. Plus .NET Extensions!
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.
@ftrain I choose the 3rd option: working code
— Gina Trapani ️ (@ginatrapani) December 27, 2015
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.
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.
VS Format Document commands will use tabs rather than spaces for this project. Here is the same doc reformatted in VS:
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.
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.
About Newsletter
I corrected it:
[*.cs]
indent_style = space
indent_size = 4
tab_size = 4
- 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
Probably, but correlation is not causality. It is very likely that those earning more are senior programmers, who prefer spaces rather than tabs.
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.
Problem solved.
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/
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`.
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>
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!
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.
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.
Comments are closed.
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! :)