-
Notifications
You must be signed in to change notification settings - Fork 0
Color Roles
Both theme families paint from a small set of named roles rather than colouring each Visual Studio classification individually. A role is a decision — "this is what a type name looks like" — and the classifications listed under it are the places that decision lands.
The tables below are the Focus mapping, read from the TEMPLATE in
FocusThemes/Themes/gen-themes.py. Graphite uses the same roles, minus the split
across type kinds: see Graphite Themes.
The Focus family gives each of the five C# type kinds a colour of its own. Roslyn ships a separate classification for each, so all five are reachable from Fonts and Colors without an extension — only the italic on interfaces needs one.
| Role | Classifications |
|---|---|
class |
class name, module name, type parameter name, delegate name, array name, pointer name, function pointer name, User Types, User Types(Delegates), User Types(Type parameters)
|
interface |
interface name, User Types(Interfaces)
|
record |
record class name, record struct name
|
struct |
struct name, User Types(Value types)
|
enum |
enum name, User Types(Enums)
|
class is the fallback for anything that is a type but is not one of the four
kinds singled out. interface is a lighter tint of the class hue rather than a
hue of its own: it is the same family, and italic is what tells the two apart.
enum member name is deliberately not on the enum row. The design colours
the name of the type, not its members, and a member is read as a value — so it
sits with variable.
| Role | Classifications |
|---|---|
keyword |
keyword, keyword - control, preprocessor keyword, label name, mismatched brace, plus the XML, XAML and CSS keyword classifications |
method |
method name, extension method name
|
variable |
local name, field name, property name, event name, parameter name, enum member name, Identifier, and the XML/XAML/HTML attribute names |
operator |
operator, operator - overloaded, HTML Operator
|
string |
string, string - verbatim, and the attribute-value classifications |
number |
number, constant name, string - escape character, Literal, XML CData Section
|
comment |
comment, the xml doc comment text, punctuation, namespace name, preprocessor text
|
Two of these share a colour with another role by design. Constants and escape
sequences ride with number, because both are literal values. Punctuation and
namespace names ride with comment, because both are structure the eye should be
able to skip.
Every other role is a hue drawn in the design. These two are not, and that is a decision rather than a shortage of hues.
variable is the theme's plain-text hue, desaturated. Names are the most
frequent thing on a screen of code. Giving them a full-strength hue of their own
would make every line compete with itself, so they read as text — present, but
not claiming attention. They still carry some colour, because the alternative
(leaving identifiers at plain text) collapses locals, fields and properties into
the same read as punctuation, and "what is this name" stops being answerable at a
glance.
operator is the keyword hue, lightened. An operator is syntax, in the same
way a keyword is, so it belongs to that family. But it recurs several times per
line, and a fully saturated hue on every = and . reads as noise rather than
as structure. Lightening it keeps the relationship and drops the volume.
A consequence worth knowing when reading the generator's output: operator sits
within a few degrees of keyword on the colour wheel, and variable within a
few degrees of the plain-text hue. The separation report printed on every run
measures hue only, so it flags those two pairs every time. That is why it reports
rather than fails — for these, saturation and lightness are the channels doing
the work.
Brace pairs cycle through three roles by depth: class, then method, then
string. A mismatched brace uses keyword, and the keyword hue is kept out of
the cycle for that reason — the warning only reads as a warning if nothing else
on the line is already wearing it.
A .vstheme carries colour only. It has no attribute for weight or slant, so
emphasis comes from MEF ClassificationFormatDefinition exports instead —
FocusThemes/FocusEmphasis.cs and GraphiteTheme/GraphiteEmphasis.cs.
Italic: comment, the three xml doc comment classifications, keyword,
keyword - control, interface name, type parameter name, parameter name,
extension method name.
Bold: class name, record class name, keyword - control,
operator - overloaded.
Two notes on that split. keyword is italic in its entirety because C# has no
separate classification for predefined types: int and string are plain
keyword, exactly like public and class, so slanting primitives means
slanting every keyword. And interface name is italic but not bold — it is
already marked as abstract by the slant, and stacking bold on top would make
interfaces the loudest thing on screen rather than types in general.
These definitions set only the weight and slant flags and never touch
ForegroundColor, so the active theme still owns the colour. That also means the
emphasis applies under every theme, not just these: MEF format definitions are
static metadata and cannot be scoped to one theme. Switching to the built-in Dark
keeps comments italic.
Anything you have changed yourself in Fonts and Colors wins over all of it. See Customizing.