Images in this post missing? We recently lost them in a site migration. We're working to restore these as you read this. Should you need an image in an emergency, please contact us at imagehelp@codebetter.com
Coding style per project

A few months ago, when I installed Visual Studio 2008 on my system, I opened one of my projects, did the usual project conversion, edited some files, created a few others, saved, tested, and checked in source control. Another developer working on the same project, also with VS2008, later edited some of the same files I had edited.

Then I went to do a diff to verify the changes and I saw what I always hate to see. He hadn't changed a lot of code, but he was using different style settings in VS and all the extra spaces around ifs, function arguments, etc were making it harder to find the important changes. To be fair, I was the one that forgot to adjust my default settings to be more compatible with our current coding style.

The situation above is not all that critical, but is certainly a big annoyance. Some diff programs will allow you to ignore white space differences but it is still sickening to see your source code with mixed code formatting style in the same file, sometimes in the same method.

That kept me thinking: why aren't code format style settings part of the project? Imagine if you work for two different clients, with different standards, or that you are a contributor to Open Source projects that also have different opinions about code format. It's too easy to forget to adjust your settings every time you switch projects, even if you export and save the appropriate VS settings to import as needed. Any IDE with so many options as VS should offer an option to save any settings that deal with the actual code be part of the project. A developer should be able to explicitly ignore or change the project settings but not by default.

With that problem in mind, I thought it would be useful to just adopt the practice of exporting the VS settings that are relevant to the project coding style and checking that in source control too. Here's what I did.

Fire up the the Import and Export settings wizard and choose only the settings that relate to code formatting and for the languages the project uses, for example C#, HTML, and XML. In this case we will just do the C# settings.

 

Right here we hit a limitation in VS. There's no way to select only the code formatting settings for C#, so we will export all of them anyway. Once we do that, save the file to the project directory (like MyProject.vssettings) and add it to the project or solution. Open it in VS (it's just XML) an stare at the plethora of settings that are saved.

<UserSettings>
	  <ApplicationIdentity version="9.0"/>
	  <ToolsOptions>
	    <ToolsOptionsCategory name="TextEditor"
	    RegisteredName="TextEditor">
	      <ToolsOptionsSubCategory name="CSharp"
	    RegisteredName="CSharp" PackageName="Text Management Package">
	        <PropertyValue name="TabSize">4</PropertyValue>
	        <PropertyValue name="AutoListMembers">true</PropertyValue>
	        <!-- ...(snip)... -->
	        <PropertyValue name="AutoListParams">true</PropertyValue>
	      </ToolsOptionsSubCategory>
	      <ToolsOptionsSubCategory name="CSharp-Specific"
	    RegisteredName="CSharp-Specific"
	    PackageName="Visual C# Language Service Package">
	        <PropertyValue name="NewLines_QueryExpression_EachClause">1</PropertyValue>
	        <PropertyValue name="Space_Normalize">0</PropertyValue>
	        <PropertyValue name="WarnWhenMembersCauseCompilerGeneratedReferences">1</PropertyValue>
	        <PropertyValue name="CollapseInactiveBlocksOnOpen">1</PropertyValue>
	        <PropertyValue name="Watson_MaxExceptionsToReport">1</PropertyValue>
	        <PropertyValue name="EditAndContinueReportEnterBreakStateFailure">1</PropertyValue>
	        <!-- ...(snip)... -->
	        <PropertyValue name="RemoveUnusedUsings">1</PropertyValue>
	        <PropertyValue name="Rename_Overloads">0</PropertyValue>
	        <PropertyValue name="EncapsulateField_SearchInComments">0</PropertyValue>
	        <PropertyValue name="ProgressDialogDelaySeconds">2</PropertyValue>
	      </ToolsOptionsSubCategory>
	    </ToolsOptionsCategory>
	  </ToolsOptions>
	</UserSettings>

Upon closer inspection, we can more or less recognize each settings by their names. Let's remove the ones that don't seem to be related to code formatting. This is more or less a value judgment on the importance of some of the settings. My choice was to keep TabSize, IndentStyle, and InsertTabs in the first subcategory and, for the second subcategory, I'm keeping any of the setting whose name starts with NewLines_, Indent_, or Space_ and also the item named SortUsings.(I should probably just write a macro to do that at some point)

After all this sanitizing, my settings file is reduced to the following:

<UserSettings>
	  <ApplicationIdentity version="9.0"/>
	  <ToolsOptions>
	    <ToolsOptionsCategory name="TextEditor"
	    RegisteredName="TextEditor">
	      <ToolsOptionsSubCategory name="CSharp"
	    RegisteredName="CSharp" PackageName="Text Management Package">
	        <PropertyValue name="TabSize">4</PropertyValue>
	        <PropertyValue name="IndentStyle">2</PropertyValue>
	        <PropertyValue name="InsertTabs">true</PropertyValue>
	      </ToolsOptionsSubCategory>
	      <ToolsOptionsSubCategory name="CSharp-Specific"
	    RegisteredName="CSharp-Specific"
	    PackageName="Visual C# Language Service Package">
	        <PropertyValue name="NewLines_QueryExpression_EachClause">1</PropertyValue>
	        <PropertyValue name="Space_Normalize">0</PropertyValue>
	        <PropertyValue name="Space_AroundBinaryOperator">1</PropertyValue>
	        <PropertyValue name="NewLines_Braces_Method">1</PropertyValue>
	        <PropertyValue name="Indent_CaseLabels">1</PropertyValue>
	        <PropertyValue name="NewLines_Braces_ControlFlow">1</PropertyValue>
	        <PropertyValue name="NewLines_Braces_AnonymousMethod">1</PropertyValue>
	        <PropertyValue name="Space_WithinOtherParentheses">0</PropertyValue>
	        <PropertyValue name="Space_AfterBasesColon">1</PropertyValue>
	        <PropertyValue name="Indent_Braces">0</PropertyValue>
	        <PropertyValue name="Space_WithinMethodCallParentheses">0</PropertyValue>
	        <PropertyValue name="Space_AfterCast">0</PropertyValue>
	        <PropertyValue name="NewLines_Braces_CollectionInitializer">0</PropertyValue>
	        <PropertyValue name="NewLines_AnonymousTypeInitializer_EachMember">1</PropertyValue>
	        <PropertyValue name="NewLines_Keywords_Catch">1</PropertyValue>
	        <PropertyValue name="NewLines_Braces_ObjectInitializer">1</PropertyValue>
	        <PropertyValue name="NewLines_Braces_ArrayInitializer">0</PropertyValue>
	        <PropertyValue name="Space_WithinExpressionParentheses">0</PropertyValue>
	        <PropertyValue name="Space_InControlFlowConstruct">0</PropertyValue>
	        <PropertyValue name="Space_BetweenEmptyMethodDeclarationParentheses">0</PropertyValue>
	        <PropertyValue name="Indent_UnindentLabels">1</PropertyValue>
	        <PropertyValue name="SortUsings">1</PropertyValue>
	        <PropertyValue name="NewLines_ObjectInitializer_EachMember">1</PropertyValue>
	        <PropertyValue name="Space_WithinMethodDeclarationParentheses">0</PropertyValue>
	        <PropertyValue name="Space_BetweenEmptyMethodCallParentheses">0</PropertyValue>
	        <PropertyValue name="Space_BeforeSemicolonsInForStatement">0</PropertyValue>
	        <PropertyValue name="Space_BeforeComma">0</PropertyValue>
	        <PropertyValue name="Space_AfterMethodCallName">0</PropertyValue>
	        <PropertyValue name="Space_AfterComma">1</PropertyValue>
	        <PropertyValue name="Space_BeforeBasesColon">1</PropertyValue>
	        <PropertyValue name="Space_AfterMethodDeclarationName">0</PropertyValue>
	        <PropertyValue name="Space_AfterDot">0</PropertyValue>
	        <PropertyValue name="NewLines_Braces_Type">1</PropertyValue>
	        <PropertyValue name="Space_AfterLambdaArrow">1</PropertyValue>
	        <PropertyValue name="NewLines_Braces_LambdaExpressionBody">1</PropertyValue>
	        <PropertyValue name="Space_WithinSquares">0</PropertyValue>
	        <PropertyValue name="Space_BeforeLambdaArrow">1</PropertyValue>
	        <PropertyValue name="NewLines_Braces_AnonymousTypeInitializer">1</PropertyValue>
	        <PropertyValue name="Space_WithinCastParentheses">0</PropertyValue>
	        <PropertyValue name="Space_AfterSemicolonsInForStatement">1</PropertyValue>
	        <PropertyValue name="Indent_CaseContents">1</PropertyValue>
	        <PropertyValue name="Indent_FlushLabelsLeft">0</PropertyValue>
	        <PropertyValue name="Space_BetweenEmptySquares">0</PropertyValue>
	        <PropertyValue name="Space_BeforeOpenSquare">0</PropertyValue>
	        <PropertyValue name="Space_BeforeDot">0</PropertyValue>
	        <PropertyValue name="Indent_BlockContents">1</PropertyValue>
	      </ToolsOptionsSubCategory>
	    </ToolsOptionsCategory>
	  </ToolsOptions>
	</UserSettings>

It sucks that I still have to remember to load the settings for each project before making changes in that project, but at least I don't have to remember which individual settings to use for each project.

How do you handle this situation? Do you just live with the inconsistencies or is there an alternative way to deal with this issue? Are you using StyleCop (a.k.a. MS Source Analysis) or something like it to enforce some or all of the rules?


Posted 06-01-2008 9:51 PM by sergiopereira

[Advertisement]

Comments

Dew Drop - June 2, 2008 | Alvin Ashcraft's Morning Dew wrote Dew Drop - June 2, 2008 | Alvin Ashcraft's Morning Dew
on 06-02-2008 7:53 AM

Pingback from  Dew Drop - June 2, 2008 | Alvin Ashcraft's Morning Dew

Dew Drop - June 2, 2008 | Alvin Ashcraft's Morning Dew wrote Dew Drop - June 2, 2008 | Alvin Ashcraft's Morning Dew
on 06-02-2008 7:55 AM

Pingback from  Dew Drop - June 2, 2008 | Alvin Ashcraft's Morning Dew

PHenry wrote re: Coding style per project
on 06-02-2008 10:15 AM

Our small shop uses the Environment|Import and Export Settings|Use team settings file to help solve this issue.  

Someone on the team has to initially export their settings (hopefully the proj/team/company standards :>), put them on some drive which everyone can access and then everyone has to change their Environment settings.  The other hiccup is you have to re-export your settings if you make a change to your settings you want used by your team (VS08 isn't smart enough to save those settings to that team file).

sergiopereira wrote re: Coding style per project
on 06-02-2008 11:11 AM

@PHenry, that works for a single team. If someone is part of two different teams (think independent contractor or OSS contributor) you'll have multiple team settings files and you still have to remember to switch the setting every time. It sucks that this is an IDE-only setting and there's no project-level setting override.

Kyle Baley wrote re: Coding style per project
on 06-02-2008 3:06 PM

If ReSharper is an option, I think it has a solution-wide code style option. Check out Code Style Sharing in the Options screen. There's an option there to store the settings in a file. Not sure how it works but the implication is that it applies only to the current solution you're working on.

Arjan`s World » LINKBLOG for June 2, 2008 wrote Arjan`s World &raquo; LINKBLOG for June 2, 2008
on 06-02-2008 3:56 PM

Pingback from  Arjan`s World    &raquo; LINKBLOG for June 2, 2008

Casper Bang wrote re: Coding style per project
on 06-04-2008 11:51 AM

A Java developer, but experiencing similar things: The root of the problem stems from the fact that we still represent source code in an arbitrary flat file. What we should do of course, is to somehow represent it closer to it's natural syntax tree. Or perhaps simply add an indirection layer which would always sit in between the backing store (filesystem or SCM) and what our IDE sees. That way we could each use our own indentation style (a surprisingly controversial and emotional issue). I wonder why no one has done a plugin like this.

sergiopereira wrote re: Coding style per project
on 06-04-2008 12:05 PM

@Casper,

Interesting proposition. I wonder what would happen when we go about comparing files with other developers or across revisions in the SCM. It could be nice to have the other developer's styles translated to mine during the comparison.

Graeme Bradbury wrote re: Coding style per project
on 06-05-2008 4:15 AM

We use ReSharper to do the formatting/style and that has an option to attach the appropriate settings to the solution. It'll the automatically use the settings without needing developer action.

NOMAN WAHEED wrote re: Coding style per project
on 06-07-2008 9:10 PM

GOOD SITE

About The CodeBetter.Com Blog Network
CodeBetter.Com FAQ

Our Mission

Advertisers should contact Brendan

Subscribe
Google Reader or Homepage

del.icio.us CodeBetter.com Latest Items
Add to My Yahoo!
Subscribe with Bloglines
Subscribe in NewsGator Online
Subscribe with myFeedster
Add to My AOL
Furl CodeBetter.com Latest Items
Subscribe in Rojo

Member Projects
DimeCasts.Net - Derik Whittaker

Friends of Devlicio.us
Red-Gate Tools For SQL and .NET

NDepend

SlickEdit
 
SmartInspect .NET Logging
NGEDIT: ViEmu and Codekana
LiteAccounting.Com
DevExpress
Fixx
NHibernate Profiler
Unfuddle
Balsamiq Mockups
Scrumy
JetBrains - ReSharper
Umbraco
NServiceBus
RavenDb
Web Sequence Diagrams
Ducksboard<-- NEW Friend!

 



Site Copyright © 2007 CodeBetter.Com
Content Copyright Individual Bloggers

 

Community Server (Commercial Edition)