The default theme uses blue for local branches, green for remote branches, and goldenrod (brownish yellow) for tags. When creating a new theme, you should probably follow that example. If your theme already uses other colors, then stick to that.
In older releases these reference faces used to have a background
color and a box around them. The basic default faces no longer do so,
to make Magit buffers much less noisy, and you should follow that
example at least with regards to boxes. (Boxes were used in the past
to work around a conflict between the highlighting overlay and text
property backgrounds. That’s no longer necessary because highlighting no
longer causes other background colors to disappear.) Alternatively
you can keep the background color and/or box, but then have to take
special care to adjust magit-branch-current
accordingly. By default
it looks mostly like magit-branch-local
, but with a box (by default
the former is the only face that uses a box, exactly so that it sticks
out). If the former also uses a box, then you have to make sure that
it differs in some other way from the latter.
The most difficult faces to theme are those related to diffs, headings, highlighting, and the region. There are faces that fall into all four groups - expect to spend some time getting this right.
The region
face in the default theme, in both the light and dark
variants, as well as in many other themes, distributed with Emacs or
by third-parties, is very ugly. It is common to use a background
color that really sticks out, which is ugly but if that were the only
problem then it would be acceptable. Unfortunately many themes also
set the foreground color, which ensures that all text within the
region is readable. Without doing that there might be cases where
some foreground color is too close to the region background color to
still be readable. But it also means that text within the region
loses all syntax highlighting.
I consider the work that went into getting the region
face right to be
a good indicator for the general quality of a theme. My
recommendation for the region
face is this: use a background color
slightly different from the background color of the default
face, and
do not set the foreground color at all. So for a light theme you
might use a light (possibly tinted) gray as the background color of
default
and a somewhat darker gray for the background of region
.
That should usually be enough to not collide with the foreground color
of any other face. But if some other faces also set a light gray as
background color, then you should also make sure it doesn’t collide
with those (in some cases it might be acceptable though).
Magit only uses the region
face when the region is "invalid" by its
own definition. In a Magit buffer the region is used to either select
multiple sibling sections, so that commands which support it act on
all of these sections instead of just the current section, or to
select lines within a single hunk section. In all other cases, the
section is considered invalid and Magit won’t act on it. But such
invalid sections happen, either because the user has not moved point
enough yet to make it valid or because she wants to use a non-magit
command to act on the region, e.g., kill-region
.
So using the regular region
face for invalid sections is a feature. It
tells the user that Magit won’t be able to act on it. It’s acceptable
if that face looks a bit odd and even (but less so) if it collides
with the background colors of section headings and other things that
have a background color.
Magit highlights the current section. If a section has subsections,
then all of them are highlighted. This is done using faces that have
"highlight" in their names. For most sections, magit-section-highlight
is used for both the body and the heading. Like the region
face, it
should only set the background color to something similar to that of
default
. The highlight background color must be different from both
the region
background color and the default
background color.
For diff related sections Magit uses various faces to
highlight different parts of the selected section(s). Note that hunk
headings, unlike all other section headings, by default have a
background color, because it is useful to have very visible separators
between hunks. That face magit-diff-hunk-heading
, should be different
from both magit-diff-hunk-heading-highlight
and
magit-section-highlight
, as well as from magit-diff-context
and
magit-diff-context-highlight
. By default we do that by changing the
foreground color. Changing the background color would lead to
complications, and there are already enough we cannot get around.
(Also note that it is generally a good idea for section headings to
always be bold, but only for sections that have subsections).
When there is a valid region selecting diff-related sibling sections,
i.e., multiple files or hunks, then the bodies of all these sections
use the respective highlight faces, but additionally the headings
instead use one of the faces magit-diff-file-heading-selection
or
magit-diff-hunk-heading-selection
. These faces have to be different
from the regular highlight variants to provide explicit visual
indication that the region is active.
When theming diff related faces, start by setting the option
magit-diff-refine-hunk
to all
. You might personally prefer to only
refine the current hunk or not use hunk refinement at all, but some of
the users of your theme want all hunks to be refined, so you have to
cater to that.
(Also turn on magit-diff-highlight-indentation
,
magit-diff-highlight-trailing
, and magit-diff-paint-whitespace
; and
insert some whitespace errors into the code you use for testing.)
For added lines you have to adjust three faces:
magit-diff-added
, magit-diff-added-highlight
, and
diff-refined-added
. Make sure that the latter works well with both
of the former, as well as smerge-other
and diff-added
. Then do the
same for the removed lines, context lines, lines added by us, and
lines added by them. Also make sure the respective added, removed,
and context faces use approximately the same saturation for both the
highlighted and unhighlighted variants. Also make sure the file and
diff headings work nicely with context lines (e.g., make them look
different). Line faces should set both the foreground and the
background color. For example, for added lines use two different
greens.
It’s best if the foreground color of both the highlighted and the
unhighlighted variants are the same, so you will need to have to find
a color that works well on the highlight and unhighlighted background,
the refine background, and the highlight context background. When
there is an hunk internal region, then the added- and removed-lines
background color is used only within that region. Outside the region
the highlighted context background color is used. This makes it
easier to see what is being staged. With an hunk internal region the
hunk heading is shown using magit-diff-hunk-heading-selection
, and so
are the thin lines that are added around the lines that fall within
the region. The background color of that has to be distinct enough
from the various other involved background colors.
Nobody said this would be easy. If your theme restricts itself to a certain set of colors, then you should make an exception here. Otherwise it would be impossible to make the diffs look good in each and every variation. Actually you might want to just stick to the default definitions for these faces. You have been warned. Also please note that if you do not get this right, this will in some cases look to users like bugs in Magit - so please do it right or not at all.