CodeSkipper: The Code Browser for Visual C#

A Brief Tour of CodeSkipper

Getting Started
Navigating with the Keyboard
Element Filtering
Organizing Your Code with Tags
Viewing Your Class Hierarchy
Managing Tabs and History
Adding New Types
Sorting Your Code
Standard Keyboard Shortcuts
Odds and Ends

Getting Started

This guide should give you a clear picture of what CodeSkipper offers. We have included an example solution to help you follow along if you wish, but simply reading will give you the gist.

After you've run install.msi, start Visual Studio. You should find CodeSkipper installed, and its tool window open in your environment.

Main ToolWindow Open the Tutorial.sln solution provided with CodeSkipper (you'll find it in CodeSkipper's installation directory). You should see the middle pane fill with a list of types, like so.

The textbox the top is a find box. This is useful for rapidly navigating code with the keyboard.

The top pane below that, containing the text [No Active Code File]  This serves the same purpose tabs do in internet browsers: a way to keep multiple contexts and navigate quickly between them. We'll talk more about tabs later on.

The middle pane shows a list of types defined in the current solution. With it you can select types to see their members, apply commands to them by right clicking, or navigate to their source code definition by double clicking.

The bottom pane shows a list of the members of the currently selected type. As with the types pane, you can apply commands to the selected members, and double click on them to navigate to their source.

Note: CodeSkipper comes up in a vertical configuration. You can, however, dock it or resize it horizontally - it will adjust its layout to suit your needs.

Navigating with the Keyboard

Another way to navigate your code rapidly in CodeSkipper is with the keyboard. Try chording Ctrl and ',' twice (Ctrl + Comma?). The focus should shift to the textbox at the top of CodeSkipper's toolwindow. Try typing 'ex', and you'll see the elements in the types pane restrict to only those that begin with ex.

Now you have three types showing, but suppose the selected one isn't what you want? If the names have a similar prefix, you probably don't want to keep typing enough of the name to disambiguate. You could just doubleclick, but that would take your hands off the keyboard.

You have several keyboard-friendly options:

  1. You can use the arrow keys to move up and down in the list.
  2. You can use the '*' wildcard to match any number of any characters and then type more disambiguating text. (Note you can use any number of wildcards, at any position in the match pattern).
  3. You can match the next uppercased letter, by typing a capital letter. This is useful when you have multiple camel-cased names that have the same prefix word.

Try these out to get a sense of which is most appropriate for a given situation. If you type 'ex*r', for example, you'll see that both ExampleInterface and ExternalReport match. But if you type 'exR', only ExternalReport matches.

If you find you navigate to the same type frequently, you'll be happy to know that CodeSkipper tracks the patterns you enter, and associates them with the type you ultimately navigated to. The next time you enter a pattern, you'll find that type selected (in the same solution, anyway).

Once you have a type selected, you can now navigate directly to its code definition by pressing the Enter key.

But what if you want to navigate to a type member instead? After you've selected a type, you'll see that its members appear in the members pane. Rather than pressing Enter to navigate to the type, press '.'. This will complete the type's name in the text field, and place a '.' after it. Anything you type from here will affect the member's pane instead (and of course all the same techniques apply, including pressing 'Enter' to navigate to the member).

A helpful tip: if you are already editing the source for a type, and want to navigate to a member within it, you can open the find window and immediately press '.'. This will expand to the current type, allowing you to find the desired member.

Element Filtering

Even with typeahead and wildcards, if you have a relatively large number of types, it can be tedious and numbing to wade through all of them. To address this, CodeSkipper provides filters to present different slices of your types. To see the possible type filters, press the type filter toolbar button (Show Filters) above the types pane. You should see the filters pane expand above the types pane, like so:

Type Filters Pane

The first filter you see allows you to filter based on the kind of the type. If you want, for example, just to see classes, click on the 'Classes' item in the filter list. You will now see only classes in the types pane. Try clicking on the various kinds to get a sense of it. Suppose you want to see both classes and structs? Just hold the shift or control key down as you click.

There are several other filters available to help you narrow your view of types. You can change which one you're looking at by clicking on its associated toolbar button. Below is a list of the different filters and what they offer.

Kind Filter by the kind of type (e.g. Class, Interface, Struct...)
Access Filter by the access modifiers on the type (Public, Private...)
Tag Filter by tags (user specified categories) associated with the type. A convenience tag "All Untagged Types" is provided to show you types you haven't tagged. We'll talk more about tags later.
Interface Show types implementing a particular interface.
Namespace Filter by the namespace the type is declared in.
Project Filter by the project the type is defined in.
Attribute Filter by the attributes that are associated with the type.
File Filter by the file the type is defined in.

Try playing around with these a bit. Here's a tip: if you select a filter value, then switch to a different filter category, the following dialog box should appear:

File

As you can see, you can combine filters to narrow your search very specifically, by holding down the shift or control key as you switch between categories. You could, for example, keep your view narrowed to all types in a specific project or namespace as you switch between public and internal classes.

But how do you clear a filter without switching categories? As soon as you selected an item, the Clear Filter button (Clear Filters) was enabled. Clicking it will clear any filters you have in place. In addition, you will see that the current category's button will change to reflect it has a filter. Clicking this will clear just the filters in this category.

And what about members? As you'd expect, the member pane expands to show member filters when you click on the member filter toolbutton (Show Filters). It works completely differently than the type filter (no of course it doesn't - just seeing if you're awake). To see it in action, select the User class from the types list, and try out the various member filters. Several are available:

Kind Filter by the kind of member (e.g. Method, Variable, Property...)
Access Filter by the access modifiers on the member (Public, Private...)
Instance/Static Show instance or static members.
Interface Filter by what interfaces the member helps implement.
Tag Filter by tags (user specified categories) associated with the member. A convenience tag "All Untagged Members" is provided to show you members you haven't tagged. We'll talk more about tags later.
Attribute Filter by attributes associated with the member.
Overload Filter by any override kind that is associated with the member. A convenience kind, "All Overrides", is provided that will show all members that are virtual, abstract, override, sealed, or new.

If you're ever wondering where some of your elements went, you may have specified a filter and forgotten it. How can you tell you have an active filter? Two things will alert you to this. First, the Clear Filter button will be enabled. Second, the background color of the associated list will change color to make it more obvious.

Organizing Your Code with Tags

Tags are all the rage. They used to be called categories, but the word tag is so much cooler. Tags in CodeSkipper are a mechanism for filtering your code elements in a customized way, making it easy to find and work with them as groups. You can define as many tags for a given type or member as you wish, and then filter by them. Tags are also useful when sorting, as you can have your code members physically grouped together automatically, and even have regions generated for common elements.

To add a tag, right click on the type in the types pane. Try it now, by right clicking the Report class.

The types menu will appear. Select the Add Tag... command, and the following dialog will appear:

File

It contains a list of all the tags that have been used in the current solution. You can choose an existing one, or enter a new tag name in the textbox at the top. Enter 'Example Tag', then press OK. Congratulations - your type has been tagged!

But where are tags stored? Right in the code. If you look at the Report class, you'll see the following:

[ Category("Example Tag") ]
class Report : BusinessObject
    

An attribute of type System.Category has been added to the class, with the name of the category in it. This attribute is built into .Net to show control properties in Visual Studio's property grid. We're hijacking it to prevent you requiring a new attribute class be added to every solution you create.

Prepopulating the Tags List

If you have specific tags that you use regularly, you can have the Add Tag dialog present them, even if you haven't yet tagged any code elements with them in the current solution. To do so, add them to the files predefinedTypeTags.txt and/or predefinedMemberTags.txt (found in your CodeSkipper installation directory). Each tag should be placed on a separate line.

Viewing your Class Hierarchy

What OO code browser would be complete without a view of your inheritance tree? To see your types in this manner, click the types view style button ( Hierarchy ) above the types pane. The button's appearance will change to  Flat List; clicking it multiple times will toggle between the two views.

All the behaviors applied to the flat list apply to the hierarchy, with the exception of multiple selection. Also, base types in the hierarchy that are external to the solution or don't match the current filter are displayed in gray.

Managing Tabs and History

Often while coding you'll find you're working with a handful of methods, moving back and forth between them. This is really easy to do with CodeSkipper: you just create a new tab for each method, and click between them. To create a tab, right click on tabs list and select New Tab. An additional tab will appear that is a copy of your current context. As you navigate around, new locations wil be added to the selected tab's history, and the tab's text will update to display the type and/or method containing the cursor.

You can add or remove tabs using either the context menu or the tabs toolbar, and you can also rearrange the tab order by clicking and dragging your tabs around.

Note: if you have more tabs created than are visible, a popup button will appear on the tabs toolbar with a list of all available tabs, in alphabetical order.

Adding New Types

You don't have to go to the Solution Explorer for every new type you want to create. To create a new type within CodeSkipper, right click in the type's list, and select the Add Type command. The following dialog will appear:

File

Here you enter the name of the type, its enclosing namespace and project, and CodeSkipper creates the file for you, much like the Add>>New Item... command available in the Solution Explorer. The file will be created relative to the selected project's directory, and depending on whether you chose to expand namespaces to directories, in the appropriate subdirectory.

Tip: If you have a namespace or project filter specified, these will be made the default values in the New Type dialog.

Sorting Your Code

Some coding's more mindless busy work is the process of ordering code members consistently. Using CodeSkipper you don't really need to explicitly organize, since the browser sorts everything visually for you, but other consumers of your code may not see it that way. To address this, CodeSkipper provides sorting features.

If you want to sort a code file manually, select Sort Active Document from the CodeSkipper menu. This will update the content of your file with a sorted version of it. You can look at the Visual Studio editor's change bars to see what CodeSkipper has moved around. If you don't like the sort that took place, just execute the Undo command.

Once you feel comfortable with what it does to your code, you can have CodeSkipper sort your code automatically whenever you save a file. This way you can write code in whatever order is convenient, and have it tidied up without a second thought.

We understand people have different (and often passionate) opinions on how code should be formatted, and how it should be ordered. Because of this we have taken pains to maintain your code's formatting: member bodies are rendered verbatim, and most whitespace between code members is preserved.

Moreover, people often have different ideas of how their code should be ordered. For this, CodeSkipper provides a large set of configuration options for how to organize your code members. To see how this works, select Tools->Options, then click on CodeSkipper->Sorting. The following panel will appear.

Options

On the left, you will see the different groupings that will be used during sorting. Groupings each describe an attribute by which you'd like your code sorted. For example, you might like to have all your fields together, or all members of an interface together. In this list, you can see there are groupings for various contexts (Using Directives, Namespace Members, and Type Members).

CodeSkipper will apply each checked grouping in order from top to bottom, so you can specify that you want first to have all type members grouped by whether they're instance or static members, then by interface members, then by kind. To change the order of a grouping, just select it, then press Move Up or Move Down.

If you don't want a grouping performed, just uncheck it.

When you select a grouping, the list on the right will present a list of possible attributes in that grouping. This specifies the order in which the elements will be sorted. So for example if you select the Type Members->Group by Kind grouping, you'll see that the default sort order is for fields first, followed by constructors, etc.

Region Generation

While we consider regions a poor man's version of CodeSkipper, there are those who love to use them in their code. For those who can't let go of text (or who work with those who can't), CodeSkipper's sorting can automatically surround groups with regions. By default, only interface members, dllImports, and tags will generate regions. If you wish to add others, simply select the grouping you want, then check the box marked Generate #region for Grouping.

Standard Keyboard Shortcuts

The various keyboard schemes of Visual Studio make use of many keys on your keyboard. To avoid clashing with these, all of CodeSkipper's commands make use of a prefix key, followed by the key for the command. Of the very few unused keys, "Ctrl+", was the most finger friendly we could find.

The default assigned secondary key bindings for CodeSkipper commands are as follows:

Find a CodeElementCtrl+,
Shift to Next TabCtrl+N
Shift to Previous TabCtrl+P
Clear all FiltersCtrl+Space
Go BackCtrl+B
Go ForwardCtrl+F
Sort Code FileCtrl+S
Create New TypeCtrl+T
Show the BrowserCtrl+C

Odds and Ends

A couple last little features. When looking at members, sometimes you want to see or manipulate inherited members in addition to those defined in a given type. To do this, click on the members scope toolbutton ( Scopes ) above the members list. This will show you the list of types up to object that this type inherits from. Selecting one will show all the members of types between that type and the current type.

In the browser, you can visually sort your types too. Clicking on the Sorting toolbutton ( Scopes ) for either the types or members pane will reveal that you can sort by Name, Kind of Element, or Element Access. For type members, there is an additional option, By Containing Type. This is useful when you've set the members scope to see inherited members.