Create options page for code cleanup pattern in ReSharper
Rider has a Unity tab on the C# File Layout page to make it easy to edit the Unity specific pattern XAML. ReSharper has nothing.
In the meantime, it's possible to do this by hand.
- Edit the XML. It's actually read as XAML, so normal XAML rules apply.
- XML encode the text and copy/paste into a
.sln.DotSettingsfile, as the value to a string entry.
Details below:
1. Edit the XML
The following is the default XML pattern. It can be edited to suit, or left as a simple <Patterns xmlns="urn:schemas-jetbrains-com:member-reordering-patterns"></Patterns> to prevent any
Default file layout pattern
<Patterns xmlns="urn:schemas-jetbrains-com:member-reordering-patterns" xmlns:unity="urn:schemas-jetbrains-com:member-reordering-patterns-unity">
<Entry DisplayName="Public Delegates" Priority="100">
<Entry.Match>
<And>
<Access Is="Public" />
<Kind Is="Delegate" />
</And>
</Entry.Match>
<Entry.SortBy>
<Name />
</Entry.SortBy>
</Entry>
<Entry DisplayName="Public Enums" Priority="100">
<Entry.Match>
<And>
<Access Is="Public" />
<Kind Is="Enum" />
</And>
</Entry.Match>
<Entry.SortBy>
<Name />
</Entry.SortBy>
</Entry>
<Entry DisplayName="Static Fields and Constants">
<Entry.Match>
<Or>
<Kind Is="Constant" />
<And>
<Kind Is="Field" />
<Static />
</And>
</Or>
</Entry.Match>
<Entry.SortBy>
<Kind>
<Kind.Order>
<DeclarationKind>Constant</DeclarationKind>
<DeclarationKind>Field</DeclarationKind>
</Kind.Order>
</Kind>
</Entry.SortBy>
</Entry>
<Entry DisplayName="Serialized Fields">
<Entry.Match>
<unity:SerializedField />
</Entry.Match>
<!-- No sorting -->
</Entry>
<Entry DisplayName="Non-serialised Fields">
<Entry.Match>
<And>
<Kind Is="Field" />
<Not>
<unity:SerializedField />
</Not>
</And>
</Entry.Match>
<Entry.SortBy>
<Readonly />
<Name />
</Entry.SortBy>
</Entry>
<Entry DisplayName="Constructors">
<Entry.Match>
<Kind Is="Constructor" />
</Entry.Match>
<Entry.SortBy>
<Static/>
</Entry.SortBy>
</Entry>
<Entry DisplayName="Properties, Indexers">
<Entry.Match>
<Or>
<Kind Is="Property" />
<Kind Is="Indexer" />
</Or>
</Entry.Match>
</Entry>
<Entry DisplayName="Event Functions">
<Entry.Match>
<unity:EventFunction />
</Entry.Match>
<Entry.SortBy>
<!-- Prioritises common event functions. For alphabetical, replace with <Name /> -->
<unity:EventFunctionName />
</Entry.SortBy>
</Entry>
<Entry DisplayName="Interface Implementations" Priority="100">
<Entry.Match>
<And>
<Kind Is="Member" />
<ImplementsInterface />
</And>
</Entry.Match>
<Entry.SortBy>
<ImplementsInterface Immediate="true" />
</Entry.SortBy>
</Entry>
<Entry DisplayName="All other members" />
<Entry DisplayName="Nested Types">
<Entry.Match>
<Kind Is="Type" />
</Entry.Match>
</Entry>
2. XML Encode + add to .sln.DotSettings
This will save the settings to a per-solution settings file, that is normally checked in to source control. You can also add it to the .sln.DotSettings.user file, which is for user specific settings that don't get committed. Alternatively, you can go to Extensions -> ReSharper -> Manage Options and right click on the "This Computer" layer -> Open Containing Folder and edit the GlobalSettingsStorage.DotSettings file, which will affect all projects.
The file format of the .DotSettings file is not for the faint of heart. It is ultimately, a simple XML file. It uses XAML types for String, Boolean, etc. but it's really just a list of name/value pairs. To make things interesting, the names are hierarchical keys, and specified by path. And the value, while often just a simple string, boolean or integer, can also be a more complex type, such as XML or JSON, in which case it needs to be encoded. All of which makes it look very scary, but it's really just an XML encoded value inside a name/value pair inside an XML file.
Once the modified file layout pattern has been encoded, add an <s:String> element with an x:Key attribute of /Default/CodeEditing/Unity/AdditionalFileLayout/Pattern/@EntryValue, and copy the encoded layout pattern into the element value. If the file already exists, simply add the element like any other XML element. If the file does not exist, you'll need to add a root wpf:ResourceDictionary element.
Finally, you should end up with something like:
Default encoded Unity file layout pattern inside DotSettings file
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:String x:Key="/Default/CodeEditing/Unity/AdditionalFileLayout/Pattern/@EntryValue"><Patterns xmlns="urn:schemas-jetbrains-com:member-reordering-patterns"
xmlns:unity="urn:schemas-jetbrains-com:member-reordering-patterns-unity">
<!-- Pattern to match classes used by Unity that contain serialised fields and event
function methods. Based on the standard "Default Pattern", this will also order
event functions before normal methods, and does not reorder serialised fields,
as this order is reflected in the Unity editor's Inspector -->
<TypePattern DisplayName="Unity classes" Priority="100">
<TypePattern.Match>
<unity:SerializableClass />
</TypePattern.Match>
<Entry DisplayName="Public Delegates" Priority="100">
<Entry.Match>
<And>
<Access Is="Public" />
<Kind Is="Delegate" />
</And>
</Entry.Match>
<Entry.SortBy>
<Name />
</Entry.SortBy>
</Entry>
<Entry DisplayName="Public Enums" Priority="100">
<Entry.Match>
<And>
<Access Is="Public" />
<Kind Is="Enum" />
</And>
</Entry.Match>
<Entry.SortBy>
<Name />
</Entry.SortBy>
</Entry>
<Entry DisplayName="Static Fields and Constants">
<Entry.Match>
<Or>
<Kind Is="Constant" />
<And>
<Kind Is="Field" />
<Static />
</And>
</Or>
</Entry.Match>
<Entry.SortBy>
<Kind>
<Kind.Order>
<DeclarationKind>Constant</DeclarationKind>
<DeclarationKind>Field</DeclarationKind>
</Kind.Order>
</Kind>
</Entry.SortBy>
</Entry>
<Entry DisplayName="Serialized Fields">
<Entry.Match>
<unity:SerializedField />
</Entry.Match>
<!-- No sorting -->
</Entry>
<Entry DisplayName="Non-serialised Fields">
<Entry.Match>
<And>
<Kind Is="Field" />
<Not>
<unity:SerializedField />
</Not>
</And>
</Entry.Match>
<Entry.SortBy>
<Readonly />
<Name />
</Entry.SortBy>
</Entry>
<Entry DisplayName="Constructors">
<Entry.Match>
<Kind Is="Constructor" />
</Entry.Match>
<Entry.SortBy>
<Static/>
</Entry.SortBy>
</Entry>
<Entry DisplayName="Properties, Indexers">
<Entry.Match>
<Or>
<Kind Is="Property" />
<Kind Is="Indexer" />
</Or>
</Entry.Match>
</Entry>
<Entry DisplayName="Event Functions">
<Entry.Match>
<unity:EventFunction />
</Entry.Match>
<Entry.SortBy>
<!-- Prioritises common event functions. For alphabetical, replace with <Name /> -->
<unity:EventFunctionName />
</Entry.SortBy>
</Entry>
<Entry DisplayName="Interface Implementations" Priority="100">
<Entry.Match>
<And>
<Kind Is="Member" />
<ImplementsInterface />
</And>
</Entry.Match>
<Entry.SortBy>
<ImplementsInterface Immediate="true" />
</Entry.SortBy>
</Entry>
<Entry DisplayName="All other members" />
<Entry DisplayName="Nested Types">
<Entry.Match>
<Kind Is="Type" />
</Entry.Match>
</Entry>
</TypePattern>
</Patterns>
</s:String>
</wpf:ResourceDictionary>
If you wish to have an empty pattern, with no special matching for Unity types (be careful of serialised fields, however), you can include:
<s:String x:Key="/Default/CodeEditing/Unity/AdditionalFileLayout/Pattern/@EntryValue"><?xml version="1.0" encoding="utf-8"?>
<Patterns xmlns="urn:schemas-jetbrains-com:member-reordering-patterns">
</Patterns></s:String>