As native iOS app developers, Xcode is our IDE of choice. Most of us use Xcode for the larger part of the day. Therefore it is important that Xcode is something we can look at for prolonged time; its appearance should not fatigue, disgust or distract us, and it should support us in our work where possible. The “Theme” that you can configure in Xcode’s “Fonts & Colors” settings, is the primary point for influencing this appearance.
This post is highly subjective and most rationale is driven by aesthetic preferences and emotional associations. The aim of this post is not to provide a single Xcode Theme to rule them all, but rather to inspire you to think about how you can enable your Xcode Theme to better support you in your work.
Dark background vs. Light background
Most developers do seem to find their way to the “Fonts & Colors” settings; rarely do you see the “Default” theme in the wild, other than perhaps in coding demos by Apple during WWDCs. The Theme is, of course, a means to personalize Xcode, but when you observe the abundance of themes listed on sites that gather Xcode Themes, that have a dark background, the principal concern for people changing their theme almost seems to be to move away from using a light background.
There are plenty of sources – some more substantiated than others – that have something to say about whether or not dark text on a light background is better than light text on a dark background, or vice versa. It is important to note that many of these sources focus on the ideal design of text pages – content that is read. Given this quote from Robert C. Martin from his book “Clean Code: A Handbook of Agile Software Craftsmanship”, you could say those sources then are important in determining your IDE theme:
“Indeed, the ratio of time spent reading vs. writing is well over 10:1. We are constantly reading old code as part of the effort to write new code. ...[Therefore,] making it easy to read makes it easier to write.”
Though opinions are divided, the majority seems to conclude that:
“While white text on a black background provides very high value contrast, it is less readable and causes greater eye fatigue than black text on a white background.”
However, though the ratio of 10 over 1 might be correct in terms of how much we dwell through existing code compared to how much we actually write, most developers will probably not read the code like a book, but scan through it to comprehend the structure and intent. For scanning, light text on a dark background works better, because it better allows for highlighting important content, while less important content can recede into the background. This is exactly the reason why Apple introduced Dark Mode in macOS Mojave.
“On a sunny summer day I love to read a book outside. Not right in the sun; that’s too bright. I’ll hunt for a shady spot under a tree. The shaded paper contrasts with the crisp text nicely. If you were to actually measure the contrast between the two, you’d find it is much lower than black text on a white background (or white on black) on your display device of choice. Black text on white from a computer display is akin to reading a book in direct sunlight and tires the eye.”
We chose for a background color that is dark, but not completely black. There are two reasons: firstly, a completely black background will provide you with a mirror in which you can admire yourself all day. This is not a bad thing per se, but not particularly what you would like to focus on. Second, a somewhat more gray background color connects nicely with both the Light and Dark appearance in macOS Mojave. The current line is slightly darker, the selection slightly lighter.
Text: Syntax Identifiers
The text will have various bright colors and shades of white. Which colors you will see where depends on what kind of file you are looking at. Most common in iOS development are Swift, Objective-C (.m and .h) and XML-based (e.g. Plist) files. Xcode themes provide 23 different “syntax identifiers” for which you can specify different colors and fonts. Not all identifiers will apply to all file types, but plain text will be visible somewhere in pretty much all files.
The plain text syntax identifier is used among others in definitions of properties, methods, constants, classes and enums, scoped value names and XML text content. A YAML file will be displayed entirely as plain text. Plain text is visible in many different contexts, often for important elements in the syntax. As such it should stand out and fit in, so a bright shade of white is most suitable. Full white (
#FFFFFF) is, however, a bit too bright; the hard contrast this creates against the background is unpleasant and distracts from the other syntax elements, therefore we tone it down a little.
Comments & Documentation Markup
There are three syntax identifiers for comments: regular comments, documentation markup and documentation markup keywords. Only a few of the default Xcode themes provide a slight variation between these comment types in terms of color and typography, while configuring a bit more contrast can prove very useful. But let’s first take a look at what differentiates these types of comments.
A regular comment is any text that is preceded by two forward slashes (continuing until a line-break), or text preceded by a slash followed by a single asterisk and terminated by (at least) an asterisk and slash (Or in HTML, anything between
// Copyright © Touchwonders B.V., 2018. // MARK: - UIApplicationDelegate Methods // swiftlint:disable line_length /* This is a regular comment as well */
Regular comments are often used when “toggling” comments (the act of commenting out a line), for compiler or tool directive comments such as MARK, TODO and FIXME comments in Swift, and you’ll find them in the file header (i.e. the first few lines of most code files).
Documentation comments, as the name suggests, are used for documentation. This can be (among others) for types, properties or functions, and if the documentation comments are put right above the definition, you will be able to read this documentation in Xcode’s Quick Help wherever you use that definition. Xcode provides a shortcut to help you add documentation via the menu: Editor → Structure → Add Documentation. This kind of comments uses three forward slashes for single-line comments, and a slash followed by two asterisks for multi-line comments (while a single asterisk and slash still suffice for closing). By default, your documentation comments will show up in the “Description” section in the Xcode Quick Help. There are however also sections for documenting parameters, return value/type and possible errors thrown. You can use markup keywords in your documentation comments to target these sections:
Documentation comments often contain more important information to the developer than regular comments, but both should not attract too much attention compared to the code itself. Therefore we select two shades of gray, in which documentation is brighter. The markup keywords should stand out from the documentation, as the section headers do in the Quick Help, but again it should not attract too much attention. We make the markup keywords slightly brighter than the documentation, and as only exception among all syntax identifiers, we select a bolder font weight.
|Documentation Markup Keywords|
Strings, Characters & Numbers
String and number literals generally constitute important parts of your code. They either will end up user-facing or are part of an algorithm or function in which there’s little room for error. Strings and numbers are most liable to incorrect values or typos, therefore these should be clearly visible and stick out. We chose a bright shade of red and purple, respectively. The choice here is rather arbitrary, but these colors contrast well against color choices that will be discussed further on.
Keywords are the anchor points of your code, representing the components of the language. These include fundamental expressions, statements, attributes and declarations. They represent control flow such as loops and branching. They are used to introduce functions and methods, variables and constants, and to define fundamental types. This perhaps is the most important syntactic component and hence gets a bright color that really sticks out against the rest: orange. Here again, the choice is a bit arbitrary but chosen to contrast, yet fit in too, with the other colors.
Preprocessor statements instruct the preprocessor to perform certain operations on your source code, prior to it being compiled. This, for example, might involve including header files, conditional inclusion of code, or defining macros. #pragma is also a preprocessor directive, but in Xcode is most often used to organize code and inhibit compiler warnings.
These kinds of statements often dig a little deeper, below the surface of what you see in your code file. Therefore we associate an earthy, brown color with this.
URLs and Attributes
URLs will not often appear in your Obj-C or Swift code. If they are represented as a string literal, they will not be recognized as a URL syntax element. If they are part of a comment, they will be recognized as a URL. You can choose to let these blend in with the rest of the comment or have them stick out, but it is important to know where else they might appear. Take for instance an XML file, particularly a WSDL, in which there can be numerous URLs that reference external definitions:
<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"> …
In this example, all URLs are attribute values, in which Xcode choses to syntactically color the double-quotes as String, but the URLs are recognized as such and will not be the same color. Each XML tag (in this case
<wsdl>) will be colored as Keyword. Attribute names in a tag have their own syntax identifier, Attributes. For these, we chose a color that is derived from the color for Keywords but toned down a lot, as to let the keywords take the foreground. For URLs, we chose a color that aesthetically fits in both this XML context and the aforementioned comments.
Project versus Other
Remaining are two groups of syntax identifiers, one prefixed with “Project”, the other with “Other”. Simply put, “project” is your code, “other” is someone else’s, but this is not entirely true. Project syntax is applied to your project code and to frameworks (which are not yet compiled). These frameworks might be third-party or your own. In theory, you can edit these (but if you ever used Cocoapods, this takes care of configuring included frameworks as read-only). On the “other” hand there are libraries, already compiled pieces of code and data that are not part of your Xcode target. You cannot edit these.
Your project code is more liable to change, more dynamic, hence (but also a bit out of nostalgia) we chose green. Contrasting that is the “other” code that is more static, “frozen” if you like, hence we gave it a blue color.
Each group consists of the following six identifiers: Class Names, Function and Method Names, Constants, Type Names, Instance Variables and Globals, and Preprocessor Macros. We use subtle variations in hue, saturation and brightness to distinguish these. A combination of higher saturation and higher brightness is used to convey importance, as it sticks out more strongly. Lower saturation indicates less importance. When lower saturation is combined with higher brightness, a color moves more towards white, which is used to indicate a more static nature.
Function and Method Names can be impactful, you use them to perform certain actions in your code, hence they are quite important. Compared to these, Instance Variables and Globals often are used in a more passive context, primarily for reading their value, so we tone these down slightly. Class and Type names convey important information but are relatively static. Very static are Constants, which commonly inform on relatively important points in your code such as success/failure or are used in checks for a certain mode, and hence are brighter. Lastly, Preprocessor Macros can serve as function or as constant so their nature is a bit uncertain, however, they should be handled with care so we chose to let them stick out too.
|Project Class Names|
|Project Function and Method Names|
|Project Type Names|
|Project Instance Variables and Globals|
|Project Preprocessor Macros|
|Other Class Names|
|Other Function and Method Names|
|Other Type Names|
|Other Instance Variables and Globals|
|Other Preprocessor Macros|
Cursor and Invisibles
There are two colors yet unaddressed, which are not part of the syntax but are defined at the same level of your background color and selection. The Cursor needs to be clearly visible and contrast well to everything. We chose full white for this. As we chose a slightly toned down shade of white for Plain Text, this still sufficiently contrasts. The cursor will always be on the current line, for which we chose a color which is slightly darker than the background color, further increasing emphasis. Xcode also allows you to select either a Vertical Bar Cursor, an Underline Cursor or Block Cursor. The latter two can cause confusion in determining where the insertion point is, where the Vertical Bar is a very precise indication.
Invisibles are characters that don’t have any visual mark, but often (but not always) do take visual space. These include whitespaces, newlines, joiners and control characters. You can toggle Editor → Show Invisibles, after which Xcode shows visual marks for these invisible characters; a middot (
·) for spaces, a “not sign” (
¬) for newlines. We chose to contrast these invisibles to plain text and give them a color that resembles a “shadow”.
As most programmers know, the font you use in your IDE is preferably monospaced. This ensures that characters that look similar (such as 1 and I, and 0 and O) can better be differentiated, punctuation and other potentially narrow characters are more visible and any chunks of text of equal character count take up equal space. There are plenty fonts to choose from. We chose Adobe’s "Source Code Pro”, a crisp and legible typeface that also rather looks nice. At 12 points, this is perfectly legible for most of us, but if too small, Xcode provides an easy menu item under Edit → Format → Font → Bigger to increase the font size by one. The font size is consistent across all syntax identifiers. As said, only Documentation Markup Keywords have a heavier font weight. Lastly, the default “Normal” line spacing provides sufficient air between the lines. If you find the available spacing options too narrow or too relaxed, there are fonts such as Meslo LG that provide a variety of baked-in line spacing.
All aspects of our Xcode Theme have now been discussed. Every component of it can be determined by giving it some thought, by associating certain values or emotions to it. A theme that looks nice is perfectly valid, but it can be a powerful tool to convey information that lets you scan through your code more easily.
Our theme is available on GitHub, where it is accompanied by a simple script that installs it in the correct directory:
~/Library/Developer/Xcode/UserData/FontAndColorThemes. The theme might change over time and we love to hear your thoughts on it, as well as your experiences with the theme you use. Get in touch!