JetBrains IDEs hidden features: Syntax Highlighting
JetBrains has added powerful improvements to their IDE over the years, but leaves some features disabled in the default configuration. If my colleagues are representative, most users don’t know these features exist.
Here, we’re going to look at syntax highlighting. The default schemes only assign colors to a few token types. My goal is for you to be aware of the token types that are available, and to customize more of them.
And JetBrains, I want you to help change the defaults!
I’ll use this Java code to test out syntax highlighting in IntelliJ. But everything here applies to all JetBrains IDEs and languages.
Here’s what the code looks like with IntelliJ’s default light theme.
And here’s what it looks like with my light theme.
And here’s my dark theme.
If you just want to use my settings, you can get them here.
If you want to know what the colors mean, read on.
Foreground colors for concrete and abstract
I use a maroon color to represent concreteness (in classes and methods) and a teal color to represent abstractness.
- Interfaces are teal
- Concrete classes are maroon
- Abstract classes are maroon with a teal underline
Method calls are underlined with teal if the method is defined in an interface.
Method calls are underlined with maroon if the method is defined in a superclass.
Italics and bold for static and mutability
I use italics to represent static.
I use bold to represent mutability. This can help when stepping through code in the debugger. Only the bolded names can have their values change over time.
- Fields that are non-final, both static and non-static, are bold
- Parameters that get reassigned are bold
- Variables that get reassigned are bold, including loop variables
Background colors for errors
I use background colors to represent errors, warnings, and weak warnings.
Differences from defaults
IntelliJ ships with 4 predefined color schemes: Classic Light, Darcula, High contrast, and IntelliJ Light. Plugins can add more.
The default themes do not use many colors, and few token types are customized. Classes, interfaces, parameters, local variables, and method calls have no customization and are displayed as default text.
The default themes have custom foreground colors for keywords, fields, numbers, and string literals. I’ve kept these colors unchanged in my themes.
Italics and bold
The default themes use italics to represent static, which I kept unchanged.
IntelliJ Light doesn’t use bold. Classic Light uses bold for keywords, instance fields, and static final fields, but not static non-final fields.
If there is some meaning behind bold in this theme, I haven’t figured it out.
Errors and warnings
The default themes use a mix of background colors and text decorations to show errors, warnings, and weak warnings.
Text decorations can shadow each other.
Here, the underline for reassignment is obscured by the underwave for the type error.
To configure your own color scheme:
- Open the IDE settings, go to Settings > Editor > Color Scheme.
- Choose a built-in scheme, like IntelliJ Light or Darcula.
- Click the gear icon, and choose Duplicate…
- Give it a name and choose Apply.
Next it’s helpful to look at a specific language. I’ll click Java.
Clicking an element in the preview pane on the bottom will jump to its token type in the color scheme editor on top.
This makes it easy to discover the various token types, and can make it quick to set up a new color scheme. However, we usually don’t want to apply our config here at the “leaves” of the tree.
The token types that we can configure are organized into a hierarchy. Each token type either has custom display settings, or uses the settings from the parent type. The “Inherit values from” pane has a hyperlink we can click to jump to the parent type. Following one example chain:
- Java > Constant (static final imported field)
- Java > Constant (static final field)
- Java > Static field
- Language Defaults > Static field
- Language Defaults > Default
- General > Default text
It’s best to configure the token types as high in the hierarchy as possible, in “Language Defaults” or “General” whenever possible. Settings here will apply to all programming languages, which is especially helpful when working with a new language.
Let’s say we’re not too familiar with Scala code and we come across a trait.
We can see that trait is a keyword and the name is highlighted teal, a strong hint that traits are similar to interfaces.
Out of the box, my themes work pretty well for Scala.
With a bit of language-specific tweaking, we can make our themes even better. If we can keep the tweaks to a minimum, we will have a consistent experience across languages.
You already knew that JetBrains IDEs support syntax highlighting, but hopefully you learned something about how powerful the highlighting engine is. If you’re already configuring your own color scheme, I’d love to see your setup.
See my other post if you’d like to know more about how I picked specific colors.
What other features are chronically underused, because the IDE has them disabled by default?