CSharpier
repository·main·Indexed 25 days ago
https://github.com/belav/csharpierAn opinionated code formatter for C# and XML that automates code style consistency by parsing and re-printing code. It is available as a .NET tool, a programmatic library via CSharpier.Core, and as extensions for Visual Studio, VS Code, and JetBrains Rider. The tool follows an "Option Philosophy" to minimize configuration fatigue and includes a printing engine evolved from Prettier.
What's inside CSharpier
- CSharpier is an opinionated code formatter for C# and XML. It works by parsing your code and re-printing it according to its own internal rules. The printing engine is a port of Prettier that has been evolved for C# and XML. It follows an "Option Philosophy" similar to Prettier, providing only a few basic options to minimize configuration fatigue.
What is SyntaxFinder used for?
mainSyntaxFinder is a tool used to scan C# code files using
SyntaxWalkersto analyze developer preferences and code patterns. It is primarily used for research and data collection, such as:- Determining if developers prefer spaces or tabs.
- Determining if developers prefer always using braces or no braces.
- Identifying if developers add empty lines into object initializers.
- Finding files that contain specific types of
SyntaxNodes. - Printing examples of how specific types of Syntax were formatted.
What is CSharpier?
mainCSharpier is an opinionated code formatter for C# and XML. It works by parsing your code and re-printing it according to its own internal rules. The printing process is based on a port of Prettier but has evolved specifically for C# and XML.
CSharpier follows the Prettier 'Option Philosophy', meaning it provides a minimal set of configuration options to ensure consistent formatting across projects. Requests for new formatting options are generally considered out of scope.
Integration options for CSharpier
mainBeyond manual CLI usage, CSharpier can be integrated into your development workflow in several ways:
- Editor Integration: Configure your editor to format code automatically on save.
- Pre-commit Hooks: Use CSharpier to ensure code is formatted before commits are finalized.
- Build Process: Integrate formatting as part of your MSBuild process.
- Programmatic Usage: Call CSharpier via its API within your own applications.
- CI/CD: Use CSharpier in your continuous integration pipelines to enforce formatting standards across the codebase.
How CSharpier resolves the formatter version
mainWhen performing a formatting action, CSharpier follows a specific resolution order to determine which version of the tool to use. It attempts to find the most relevant version in this priority:
- MSBuild version: It first looks for a version defined within the
.csprojfile. - Local dotnet tool: It checks for a local version installed via
dotnet tools(e.g., via a tool manifest). - Global version: It falls back to a globally installed version of CSharpier.
Ensuring the correct version is used is critical for consistent formatting (for example, ensuring specific rules like adding blank lines between methods are applied correctly).
- MSBuild version: It first looks for a version defined within the
CSharpier extension formatting behavior
mainThe CSharpier extension supports several formatting triggers and contexts:
- Automatic Warming: Existing open documents are warmed up for formatting.
- Edit-based Formatting: Formatting can be triggered by edits made to the document.
- Run on Save: The extension supports 'run on save' functionality (specifically in VS Code).
- Unsaved Documents: Unsaved documents can be formatted (primarily applicable to VS Code).
- Language Filtering: Formatting actions are only shown/available for C# files.
Best Practice: Use CSharpier as a local dotnet tool
mainTo ensure consistent formatting across all team members and different environments, it is important to install and use CSharpier as a local dotnet tool rather than a global installation.How CSharpier locates the dotnet CLI
mainThe extension requires the
dotnetCLI to function. It uses the following resolution logic to find thedotnetexecutable:- Uses the path specified in
dotnet.dotnetPathif set. - Uses the paths specified in
omnisharp.dotNetCliPathsif set. - Attempts to run
dotnet --infoto check if it is on the system PATH. - On non-Windows systems, it attempts to run
sh -c "dotnet --info"to check the PATH.
- Uses the path specified in
How CSharpier versioning is determined in Rider
mainThe Rider plugin does not include the formatter itself; it uses the
dotnettool CSharpier. The plugin determines which version of CSharpier to use by following this priority:- It looks for a dotnet manifest file in your project to use a local, project-specific version.
- If no manifest is found, it looks for a globally installed version of CSharpier on your system.
Enable debug logs in editor extensions
mainIf the CSharpier extension is unable to format files, you can enable debug logging to capture more information about the failure. The process varies by editor:
Visual Studio
- Navigate to
Tools - Options - CSharpier. - Set
Log Debug Messagestotrue.
VSCode
- Navigate to
File - Preferences - Settings - Extensions - CSharpier. - Check
Enable debug logs. - Restart VSCode.
Rider
- Execute the action
Debug Log Settings. - Add an entry for
#com.intellij.csharpier.CSharpierLogger. - Restart Rider.
- Navigate to
Ignore XML code blocks using csharpier-ignore comments
mainIgnoring code in XML follows a similar pattern to C#. Use XML comments to wrap the elements you wish to exclude from formatting.
- Single element: Use
<!-- csharpier-ignore -->before the element. - Ranged elements: Use
<!-- csharpier-ignore-start -->and<!-- csharpier-ignore-end -->to wrap a block of XML.
<Root> <Child> <!-- csharpier-ignore --> <Element /> <!-- csharpier-ignore-start --> <Element /> <Element SomeAttribute = "yeah" /> <!-- csharpier-ignore-end --> </Child> </Root>- Single element: Use
Configure CSharpier using configuration files
mainCSharpier can be configured using several file types. The configuration file is resolved based on the location of the file being formatted: it looks for a
.csharpierrcfile (JSON or YAML) or a.csharpierrc.json/.csharpierrc.yamlfile at or above the target file. If none are found, it falls back to an.editorconfigfile, respecting standard editorconfig inheritance.Supported configuration files:
.csharpierrc(JSON or YAML).csharpierrc.json(JSON).csharpierrc.yaml(YAML).editorconfig(INI)