💅 CShapier - The Prettier for C#
Explore alternatives to achieve consistent and readable code in C# projects, ensuring code quality and enhancing development workflows. Lets see if we can find C# equivalent of Prettier for automated code formatting
The Benefits of Auto Formatting
Time-saving Writing code and manually formatting it can be a time-consuming task. Auto formatting allows you to save time by automating the formatting process, allowing you to focus more on the writing process and the syntax.
Improved code readability: Well-formatted code is much easier to read and understand, especially during code reviews. New developers joining your organization can quickly grasp the logic and structure of well-formatted code, facilitating their onboarding process.
Consistency: It is important to maintain consistency in source code, even if it is not directly visible on the client side. Auto formatting becomes invaluable, particularly for large projects with multiple contributors, as it ensures a consistent coding style throughout the codebase.
Why Prettier-Esque Formatting
Prettier is an opinionated code formatter
Opinionated style guide despite not aligning with your preferred style, has its unique benefits eliminate wasteful discussions, free up mental threads, and save developers’ time.
When it comes to code formatting, I have a preferred style, but more importantly, I prefer not to worry about it. Using a Opinionated style formatting approach allows me to focus on writing code without being burdened by formatting decisions.
I prioritize code readability and consistency over specific style choices. Whether it’s tabs or spaces, 2 spaces or 4, or even 3 spaces, I don’t mind 🤷♂️ as long as the code remains readable and consistent. I don’t want to be bothered with the details as long as it doesn’t become my problem.
Everybody wants to add just a tiny piece of configuration to satisfy their use case. As a result we end up with inconsistently designed tools, with unexpected combinations that don’t work correctly, with bugs and regressions that, when fixed in one configuration, break something else with another configuration. -Dan Abramov
CSharpier
CSharpier is an opinionated code formatter for C#, utilizes Roslyn to parse and re-print code based on its own rules, derived from the printing process of Prettier but with subsequent evolution. It adheres to the Option Philosophy of Prettier and offers a limited set of formatting options without intending to introduce additional ones.
Its a port of Prettier for C# with a steady growth on github gaining 720⭐ on github in 2 years and 8 months
Easy Setup
Setting up CSharpier is a breeze and can be done in just 5 minutes. Here’s how:
- Install CSharpier.MSBuild to your project.
- Add a configuration file to the root directory.
- Specify the folders you want to ignore.
- Build and push your project.
That’s it! In no time, you’ll have CSharpier up and running smoothly.
Support for Editors
It supports most of major editors its not needed but If you prefer to your code to be formatted on save or via some key shortcut its quite useful
- Visual Studio Extension 11,895 installs with ⭐5/5
- Visual Studio Code Extension 90,103 installs with ⭐4.2/5
- Rider Extension 5,303 installs with ⭐4.7/5
- Neovim
Comparison
How does it compare to other options
Dotnet Format
dotnet-format is a code formatter for dotnet that applies style preferences to a project or solution. Preferences will be read from an .editorconfig
file. At this time dotnet-format is able to format C# projects with a subset of supported .editorconfig
options.
max_line_length not supported
Unfortunately, dotnet format does not currently support the max_line_length option. Consequently, it considers code exceeding the line length as valid.
var document = _context.Documents.Include(d => d.Packages).FirstOrDefault(d =>d.Id == linkPackageModel.DocumentId && d.CreatedBy == _currentUserService.UserId);
var document = _context.Documents.Include(d => d.Packages).FirstOrDefault(d =>d.Id == linkPackageModel.DocumentId && d.CreatedBy == _currentUserService.UserId);
This limitation has been recognized since July 2019, as there is an open issue regarding this on GitHub.
This is a very hard problem if you want it to work well. I’m hoping to get some time to discuss this with the team in the future. -Sam Harwell Oct 2019
Considering these circumstances, it’s uncertain whether the max_line_length feature will be added to dotnet format anytime soon.
cant remove multiple new lines
Due to the limitations of dotnet format, it is unable to remove multiple new lines automatically. As a result, if I want to update the code from the previous section to
- add an owners with subscription
- get Versions of the Packages
- add a releaseDate constraint to FirstOrDefault
I like to add new lines to separate the context of the code. I often find myself writing code like this. Don’t worry I wont commit this code
var document = _context.Documents.Include(d=>
d.Owners.Where(
o=>o.hasSubscription
))
.Include(d => d.Packages).ThenInclude(p=>p.Versions)
.FirstOrDefault(d =>d.Id == linkPackageModel.DocumentId && d.CreatedBy == _currentUserService.UserId
&& d.ReleaseDate > utcNow
);
var document = _context.Documents.Include(d=>
d.Owners.Where(
o=>o.hasSubscription
))
.Include(d => d.Packages).ThenInclude(p=>p.Versions)
.FirstOrDefault(d =>d.Id == linkPackageModel.DocumentId && d.CreatedBy == _currentUserService.UserId
&& d.ReleaseDate > utcNow
);
Its ugly and I would like the auto formatter to fix this for me but because dotnet format cant detect multiple blank lines I would have to manually fix this.
But with CSharpier, you can easily format the code to achieve the desired structure
var document = _context.Documents
.Include(d => d.Owner.Where(o => o.hasSubscription))
.Include(d => d.Packages)
.ThenInclude(p => p.Version)
.FirstOrDefault(
d =>
d.Id == linkPackageModel.DocumentId
&& d.CreatedBy == _currentUserService.UserId
&& d.ReleaseDate > utcNow
);
var document = _context.Documents
.Include(d => d.Owner.Where(o => o.hasSubscription))
.Include(d => d.Packages)
.ThenInclude(p => p.Version)
.FirstOrDefault(
d =>
d.Id == linkPackageModel.DocumentId
&& d.CreatedBy == _currentUserService.UserId
&& d.ReleaseDate > utcNow
);
Rider for the win?
So why not Rider or ReSharper?
Dollar bill y’all, dollar bill y’all -Jimmy Spicer
While Rider is a compelling choice to address formatting challenges, it does come with certain considerations. While it provides strong formatting support, relying on it solely for auto formatting might be impractical due to the license fee and the expectation of all team members using the same editor.
From a personal standpoint, I prefer the flexibility of switching between editors based on the task at hand. Additionally, I have invested time in configuring my current editors, and the thought of setting up key bindings again in a different editor can be cumbersome and time-consuming.
Conclusion
Ultimately, the choice of a code formatting solution depends on factors such as personal preference, team requirements, and the specific context of the project. Whichever tool or approach is selected, the main goal remains consistent: to enhance code readability, maintainability, and collaboration within the development team.