
CSharpen
C# File Organizer
Order, sort and regionalize symbols by access level, name and type, and other features to keep your C# files sharp.

Features
- Order, sort and regionalize symbols by access level, name and type.
- Remove unused
using
directives.
- Remove unused package references (NuGet) of one or more projects in a solution.
- Perform Quick Fixes.
- Apply coding styles.
- Rename symbols by convention.
- Regionalize interface implementations.
- Output File Diagnostics and Quick Fixes.
Keyboard shortcut
- Current file: ⇧+⌥+⌘+f on macOS, shift+alt+ctrl+f on Windows/Linux
- Tip: Think Format Document command, which is ⇧+⌥+f on macOS or shift+alt+f on Windows/Linux, but add ⌘ on macOS or ctrl on Windows/Linux.
Commands
- Current file: "Sharpen Document" (
kokoabim.csharpen.sharpen-file
)
- Project files: "Sharpen All Files In Project..." (
kokoabim.csharpen.sharpen-project-files
)
See Features -> Commands for more.
Remove Unused Package References
Remove unused package references (NuGet) from one or more projects. For all C# files of the projects being processed, unused using
directives will be removed and, if enabled, the file will be sharpened (setting: csharpen.sharpenFilesWhenRemovingUnusedReferences
).
Command: "Remove Unused References Of Project..." (kokoabim.csharpen.remove-unused-references
)
Known Issue
It is possible that used using
directives are removed. This is due to VS Code incorrectly indicating that a using
directive is not used (by way of its vscode.languages.getDiagnostics(Uri):Diagnostic[]
API). The setting csharpen.delayBeforeRemovingUnusedUsingDirectives
adds a delay after showing the file in the editor which may help with this issue though adds time to the overall process.
Note: If this occurs, use the Quick Fix to re-edd the using
directive. (⌘+. on macOS or ctrl+. on Windows/Linux)
Remove Unused Using Directives
Remove unused using
directives (either when sharpening a file, removing unused package references or using a standalone command).
Stand-alone command: "Remove Unused Using Declarations" (kokoabim.csharpen.remove-unused-usings
)
Based on configurable Quick Fix title patterns, performs all matched Quick Fixes for the current file. Can be invoked by command (Perform Quick Fixes
) or when sharpening a file by setting csharpen.performQuickFixesOnSharpen
to true
(false
by default). Whether enabled or not, not invoked when processing all project files.
See settings for default patterns. More default patterns can be added in future releases.
Coding Styles
Apply coding styles using a command ("Apply Coding Styles") or when sharpening (by setting csharpen.codingStylesEnabled
to true
).
Current Coding Styles
Setting |
Description |
csharpen.convertNonPrivateFieldsToProperties |
Convert non-private fields to properties. Preserves value assignment (if any). |
csharpen.useLanguageKeywordsInsteadOfFrameworkTypes |
Change BCL/Framework types to language keywords on return and member types. Example: System.String to string , Int32 to int , etc. |
Individual rules can be disabled in settings. By default all rules are enabled.
Future Coding Styles
On subsequent releases, additional rules will be added.
Symbol Renaming
Based on configurable logic and patterns, symbols can be renamed on sharpen. The renaming operation uses VS Code's built-in rename functionality thus all references in other files are renamed as well.
An example use case (and a default setting): All methods that (1) include a member modifier of async
, (2) have a return type of Task
or ValueTask
(with or without generic type arguments) and (3) the symbol name does not end with Async
are renamed to have a suffix of Async
.
See settings: csharpen.symbolRenamingEnabled
and csharpen.symbolRenaming
.
Regionalize by Access Modifier and Type
Regionalize symbols by access modifier and/or type on sharpen. Customizable in settings.
Regionalize Interface Implementations
Regionalize interface implementations by grouping them together within regions on sharpen.
Supported interface implementations:
IAsyncDisposable
, IDisposable
ICloneable
ICollection
, ICollection<T>
IComparable
, IComparable<T>
IConvertible
IEnumerable
, IEnumerable<T>
IEqualityComparer<T>
IEquatable<T>
IFormattable
IList
, IList<T>
Interface implementations grouped by the interface name (without generic type argument list) because of the implementation size:
IAsyncDisposable
, IDisposable
ICollection
, ICollection<T>
IConvertible
IList
, IList<T>
Interface implementations grouped in a shared interfaces
region:
ICloneable
IComparable
, IComparable<T>
IEnumerable
, IEnumerable<T>
IEqualityComparer<T>
,
IEquatable<T>
IFormattable
Notes:
- Explicit interface implementations are detected and supported.
- With
IDisposable
and IAsyncDisposable
the finalizer (i.e. destructor) and possible /^_?(is)?disposed$/i
(RegExp pattern) boolean instance field are also moved to the region.
Output File Diagnostics and Quick Fixes
Output File Diagnostics and Quick Fixes to output panel. This includes language-specific diagnostics (e.g. syntax, semantic, compiler error/warning) and what Quick Fixes are available.
Commands:
- Current file: "Output File Diagnostics" (
kokoabim.csharpen.output-file-diagnostics
)
- Project files: "Output File Diagnostics For All Files In Project..." (
kokoabim.csharpen.output-file-diagnostics-for-project-files
)
Requirements
Special Handling
The following symbols are specially handled. They are not supported in the settings but are always ordered/sorted in the following:
using
directives:
- sorted alphabetically
- placed at top
- unused
using
directives are removed (setting csharpen.removeUnusedUsingsOnSharpen
)
namespace
declarations:
- sorted alphabetically
- placed after
using
directives
- if one exists, converted to a file-scoped namespace (setting
csharpen.enforceFileScopedNamespaces
)
Known Issues / Limitations
Program.cs
A Program.cs
file must contain a Program
class with a static Main
method. Top-level statements are not supported. A default file filter is provided to detect this.
Undo/Redo
Undo/redo is supported but because a Format Document command is performed prior-to and after organizing a file, an undo/redo may need to be repeated for each operation. Annoying, I know. 😒
Preprocessor Directives
First off, within methods, property bodies and enums, preprocessor directives are left alone and preserved.
But... on the namespace level and within types (i.e. wrapped around members), there are considerations to be aware of.
#pragma
directives before and after a single type or member should be preserved.
#if
and #endif
directives before and after a single type or member should be preserved.
#region
and #endregion
directives are not preserved. These are entirely stripped out.
- Default file filters are provided to detect and ignore files with
#else
and #elif
directives. If a file is sharpened with these directives outside of methods, property bodies and enums, there are unexpected results. Though, if the directives exist within methods, property bodies and enums, it should be ok. The default file filters have confirmOnDeny
set to true
to provide ability to conveniently continue sharpening when detected and you know what you're doing.
Note: All sharpening modifications can always be undone.
In-Depth Language Specification
If you're curious, the C# specification grammar was referenced when writing this extension to increase the accuracy of parsing and organizing C# files. You may find it interesting to see how the language is defined. I did. 🤓