Home Screenshots Download Order Blog* Support
User Guide Style Tab Grouping Add-ins

Tab Grouping

Introduction

By default tabs with the same name and from the same folder are grouped together. Additionally you can: .NET regular expressions are used for grouping rules. See Regular Expression Language Elements MSDN page for .NET regular expressions details.

Tab title grouping

Tab title grouping settings

Everything starts from a window title that an open document has in Visual Studio (you can check it opening the Windows dialog from the main Window menu in Visual Studio). This window title is matched with the Title grouping regex. Then <Name> and <Ext> groups checked to see if they both matched something, if not then this title remains untransformed and not grouped with other titles. Titles that successfully matched with <Name> and <Ext> are grouped with other titles having the same <Name> (<Name> grouping comparison is case sensitive unless the Group titles ignoring case differences option is turned on).

Default Title grouping regex (?<Name>(.*[/\\])?.+?)(?<Ext>\..+) matches the Name group as all symbols before the first dot after the path and matches the Ext group as the dot and all subsequent symbols. For example:

Title Name Ext
Class1.cs Class1 .cs
Class1.xaml.cs Class1 .xaml.cs
App_Code/Class1.cs App_Code/Class1 .cs
Project.X/Class1.cs Project.X/Class1 .cs

If for your project type Visual Studio doesn't add a path to titles, you can use a simpler Title grouping regex (?<Name>.+?)(?<Ext>\..+). I will use this shorter regex for the next examples.

You can use several separate Name and Ext groups, the resulting string will be concatenated from all captures. It allows you to capture multiple parts of the original tab title as the name or extension. For example, (?<Name>.+?)-(?<Name>.+?)(?<Ext>\..+) will create the MainWindow name from the Main-Window.xaml tab. (?<Ext>Test)(?<Name>.+?)(?<Ext>\..+) will create the Test.xaml extension from the TestWindow.xaml.

What if you want to group Model.cs and ModelTest.cs tabs, Controller.cs and ControllerTest.cs? First you have to decide how you want the result looks like. A tab group has the single name and several extensions, plus the tab group name should present in all original titles. This leads to the group name Model for the first pair and Controller for the second. Extensions can be different or can be the same (same extensions will be confusing, but it will work), plus each extension text should present in the corresponding original title. The simplest result fulfilling these requirements is "Model .cs Test.cs" and "Controller .cs Test.cs". A Title grouping regex producing this result is (?<Name>.+?)(?<Ext>(Test)?\..+). Alternatively, you can create a separate regex for test tabs and combine it with the default regex using the OR operator '|': (?<Name>.+?)(?<Ext>Test\..+)|(?<Name>.+?)(?<Ext>\..+).

You may want to stop some tabs to group with others. There are two ways to achieve this. First, you can limit tab grouping to explicit list of extensions: (?<Name>.+?)(?<Ext>\.(xaml|xaml\.cs))$. Or you can add a regex without <Name> and <Ext> that matches tabs that you don't want to group: .+\.[Dd]esigner\..+|(?<Name>.+?)(?<Ext>\..+).

If you want to group interface and implementation files like IService.cs and Service.cs, consider to use the ITransform add-in.

Removing parts of a tab text

It is easy to remove unimportant parts of a tab text using the Title grouping regex. First, you have to ensure that <Name> and <Ext> groups match something in the target title, then you just move unneeded parts out of <Name> and <Ext> groups. For example, to remove a path from a tab name use the following regex: (.*[/\\])?(?<Name>.+?)(?<Ext>\..+).

Attention

This regex works slightly differently than the Remove path from tab name option as it occurs before tab grouping. The remove option is implemented as a transform and occurs after tab grouping. Thus for two tabs App_code/Model.cs and App_view/Model.html using the remove path regex lets these tabs to group together, while using the remove option doesn't let these tabs to group.

To group Model.cs and ModelTest.cs tabs, but to drop .cs from Test.cs producing "Model .cs Test" use the following regex: (?<Name>.+?)(?<Ext>Test)\..+|(?<Name>.+?)(?<Ext>\..+).

Transforming tab text to be more descriptive

From an add-in for Tabs Studio you can completely change any tab name or extension using the TitleManager property and the ApplyTransforms method. For example, the Disambiguator add-in detects when two or more tabs have the same title and adds Visual Studio folder or project to titles for these tabs. And the ITransform add-in improves interface tab name representation, transforming interface titles after grouping.

Document path grouping

Path grouping settings

By default tabs are grouped only if their associated Visual Studio documents are in the same folder. This is a good default as you don't want Window1.xaml from Project1 to be grouped with Window1.xaml.cs from Project2. But sometimes really relevant files can reside in different folders. For example, it would be nice to group default.js from the Scripts folder with default.htm from the HTML folder. It can be set up in Path Grouping settings.

Having two files c:\src\Window1.xaml and c:\src\Window1.xaml.cs matching algorithm removes the common path from two files, appends '$' symbol to the end of both files and concatenates them. Resulting Window1.xaml$Window1.xaml.cs$ string is matched with Path grouping regex. If M named group matches the string then two files are combinable. If not, two full paths with two '$' symbols are concatenated (resulting in c:\src\Window1.xaml$c:\src\Window1.xaml.cs$ string) and again matched with Path grouping regex. If M named group matches the string then two files are combinable. If not, then files are not combinable.

Attention

If file paths are combinable then additional tab title grouping rules are checked - for two tabs to be grouped they need to satisfy both title grouping and path grouping rules. For documents not included in the current solution, path grouping works if you open them manually, but they can't be found as corresponding files automatically. Two paths are lexicographically "sorted", it is guaranteed that the concatenation is Project1\Window1.xaml$Project2\Window1.xaml.cs$ and not Project2\Window1.xaml.cs$Project1\Window1.xaml$.

Default Path grouping regex (?<M>^[^\\]+$) matches only when there are no back slashes in the first paths concatenation and thus groups files only from the same directory. If we try c:\Project1\Window1.xaml and c:\Project2\Window1.xaml.cs files, then the first concatenation would be Project1\Window1.xaml$Project2\Window1.xaml.cs$ - it has two back slashes and would not match default regex.

Let's see some path grouping examples:

1. Group files from the two specific folders.

Let HTML\1033\*.htm files be combinable with Scripts\1033\*.js files:

(?<M>^HTML.+?htm\$Scripts.+?js\$)|(?<M>^[^\\]+$)

2. Group files with the specific extension.

Let *.htm files from any folder be combinable with other files:

(?<M>htm\$)|(?<M>^[^\\]+$)

3. Group files from the specific folder.

Let all files from the c:\Projects\4\4\HTML folder be combinable with other files:

(?<M>c:\\Projects\\4\\4\\HTML)|(?<M>^[^\\]+$)

4. Group files from a subfolder.

Let files from the subfolder be combinable with files in upper directory (for example, c:\Projects\4\default.htm and c:\Projects\4\code\default.js):

(?<M>^[^\\]+\\[^\\]+$)|(?<M>^[^\\]+$)

5. Group files from the specific subfolder.

Let files from the View subfolder be combinable with files in the upper directory (for example, c:\Projects\default.htm and c:\Projects\View\default.js):

(?<M>^[^\\]+\$View\\[^\\]+\$)|(?<M>^[^\\]+$)

6. Deny grouping for the specific extension.

Deny files with .Designer.cs extension to be combinable with other files:

(.+Designer\.cs\$)|(?<M>^[^\\]+$)

Corresponding files in different folders

As Visual Studio documents from different folders can be grouped together, the TabsStudio.Connect.OpenCorrespondingFile command and the Open context menu command can also find corresponding files in other folders (other than the current folder for the active document):

Opening corresponding file from different folder

Attention

The opened solution is scanned for files and those files that match grouping options are displayed in the context menu. Documents not included in the current solution can't be found as corresponding files automatically.

Super groups

PriorityGroup, MvcGroup and Sorter add-ins can create super groups of tabs. The following screenshot shows 3 super groups of tabs organized by project and separated with 20 pixels margin:

3 super groups of tabs organized by project

Tabs Studio core provides super group properties (Tabs SuperGroupMargin, Tab SuperGroupIsFirstTab, Tab SuperGroupIsLastTab, Tab SuperGroupName), Tabs Studio add-ins set these properties for super group tabs, the tabs style uses super group properties to define presentation, the tabs layout algorithm in Tabs Studio core adds margin between super groups.

Tabs SuperGroupMargin double property defines margin between super groups in pixels. Default value is 0 - no margin between groups. 20 is a good value to visually separate groups:

<Style TargetType="TabsStudio:Tabs" BasedOn="{StaticResource DefaultTabsStyle}">
	<Setter Property="SuperGroupMargin" Value="20"/>
</Style>

A large SuperGroupMargin value like 9999 (larger than remaining free row space) with the horizontal tabs layout will force groups to take separate rows:

Super groups in separate rows