Themes
A theme is a palette of 20 colors. This page explains how to write a theme file and select it. The terminal interface reads the active theme when it starts and draws every role of it; :theme <name> switches the theme until you quit.
Write and select a theme
Section titled “Write and select a theme”Create the folder ~/.config/tildemail/themes/ (tmail does not create it; the themes folder of the installation, if any, is read after it) and add one file per theme, named <name>.toml. A theme file has a [colors] table. A role the file leaves out takes the value of the built-in default theme (except top_bar_fg, top_bar_bg and conversation_bg, which follow the colors of the theme itself, see Roles), so a theme can set as few colors as you like:
[colors]background = "#2E3440"foreground = "#D8DEE9"accent = "#88C0D0"error = "#BF616A"Select it with the top-level theme key of config.toml:
theme = "nord"Write theme before any table. Written after a [table] header, it belongs to that table, and tmail check warns that the key is misplaced.
Check the result with tmail themes list and tmail themes show <name> (see Commands).
Ready-made themes
Section titled “Ready-made themes”The themes/ folder of the repository holds eight themes, made from well-known palettes: catppuccin-latte (light), dracula, gruvbox-dark, gruvbox-light, nord, solarized-dark, solarized-light and tokyo-night. Each sets every role. A color is a little lighter or darker than in the original palette where that was needed to give every text role a contrast of at least 4.5:1 against the background and the rows of a conversation, and of at least 3:1 against the selected row, and the tests check it.
To use them from a clone, copy the files: mkdir -p ~/.config/tildemail/themes && cp themes/*.toml ~/.config/tildemail/themes/. The release archives carry the same folder (copy it yourself, tmail does not read the archive), and the .deb installs it in /usr/share/tildemail/themes/, and tmail reads that folder after ~/.config/tildemail/themes/: theme = "nord" works right after the install, and a file of the same name in your own folder wins, so you can copy one and change it.
I kept the palette small on purpose: a few meaningful roles instead of a color for every element of the screen. The built-in default theme is dark.
| Group | Roles |
|---|---|
| Base | background, foreground, muted, border |
| Accent and selection | accent, selection_bg, selection_fg |
| Status | error, warning, success, info |
unread, flagged, quote |
|
| PGP signature | signature_good, signature_bad, signature_unknown |
| Top bar | top_bar_fg, top_bar_bg |
| Conversations | conversation_bg |
Where each role is drawn:
| Role | Drawn in |
|---|---|
background, foreground |
the background and the text of every pane |
border |
the frames of the panes, the rule under the header in the reader, and the background of the selected row when its pane does not have the focus |
muted |
the date, the hints on the last line, the flag and state columns of a read message, secondary text in the reader |
accent |
the title of the pane that has the focus, the selection marker, the signed and encrypted marks, the selected attachment |
selection_bg, selection_fg |
the selected row of the pane that has the focus |
unread |
the subject and the state mark of an unread message, in bold |
flagged |
the star of a flagged message |
quote |
quoted lines in the reader |
error |
error messages on the last line, and the Problem: line of a message that cannot be opened |
warning, success, info |
messages of that kind on the last line; info also draws the attachments in the reader |
signature_good, signature_bad, signature_unknown |
the Signature: line of the reader, and the trust line under Key: |
top_bar_fg, top_bar_bg |
the bar at the top of the screen that your scripts fill with top_status (see Scripting); a theme that leaves them out gets its own foreground on its own border, the colors of the last line, so a light theme has a light bar. A script can override these two colors with top_status.set_colors |
conversation_bg |
the background of the rows that belong to a conversation: the head with ▸ (n) and the messages shown under an open one. Single messages keep background, and the selected row keeps the selection color. A theme that leaves it out keeps its own background there, so a light theme is not tinted with the dark color of the default theme |
The three signature roles keep a good signature apart from the others: signature_unknown covers an unknown key and an untrusted one, and signature_bad covers a bad or malformed signature.
Colors
Section titled “Colors”A color is exactly # followed by six hex digits, in upper or lower case. Short forms (#RGB), alpha, color names and 256-color numbers are not accepted.
Symbols
Section titled “Symbols”A theme can also change the small symbols of the interface, in a [symbols] table next to [colors]. A key you leave out keeps the symbol of the default theme, so a theme can change just one.
[symbols]encrypted = "\uF023" # a padlock of a Nerd Fontrule = "-"separator = " | "| Key | Where it is drawn | Default |
|---|---|---|
unread |
unread message in the list | ● |
flagged |
flagged message | ★ |
answered |
answered message | ↩ |
signed |
signed message | s |
encrypted |
encrypted message, the padlock | # |
selection |
in front of the row you are on | ▌ |
expandable, collapsible |
account of the sidebar, closed or open | ▸, ▾ |
online, offline, error_mark |
connection of an account in the sidebar | ●, ○, ! |
separator |
between the parts of the last line and the entries of the top bar | │ |
bullet |
in front of an item of a bulleted list in the reader, followed by a space | • |
rule |
repeated to draw the line under the header of a message, a rule in the text and the line under the header of a table | ─ |
ellipsis |
ends a text that was cut to fit: the list, the sidebar, the top bar, the last line and the reader | … |
Each symbol is a text of 1 to 8 characters without control or invisible characters (a zero-width space or a bidirectional mark, for instance); the file is invalid otherwise. What the screen can draw is stricter, because the columns of the list and of the sidebar are one cell wide: every symbol except separator must be exactly one cell wide, and separator one to five. A symbol that does not fit is not used: the one of the default theme is drawn instead and a warning in the log names the symbol. A wide emoji is two cells, a symbol with the emoji selector (U+FE0F) is refused, and expandable and collapsible take one character only; use a glyph of a Nerd Font or another one-cell symbol. Some symbols are still fixed: the quote mark of the reader (│), the junction ┼ and the vertical bar of a table, the arrow between the account and the folder in the last line, and the ellipsis of the help window and of the key hints.
File rules
Section titled “File rules”- The theme name is the file name without
.toml. It may contain only letters, digits,_and-, and it is case sensitive. Other*.tomlfiles are skipped, andtmail themes listsays so. Files that do not end in.tomlare ignored. defaultis reserved: adefault.tomlfile is never used, andtmail themes listshows it as skipped.- Only regular files directly in the themes folder count; a symbolic link to a file is fine. Subfolders are ignored. A file larger than 64 KB is invalid.
- A theme is invalid when it has an unknown key under
[colors], a value that is not a#RRGGBBstring, an unknown key or a value that is not a text of 1 to 8 characters under[symbols], or a TOML syntax error. The error names the theme and the key (Theme 'broken': unknown key colors.acent.). For a syntax error it gives only the position, never the content of the file.
When a theme cannot be used
Section titled “When a theme cannot be used”A theme that cannot be used never stops the program. If theme names a missing, invalid or badly named theme, the code that loads the theme falls back to default and logs a warning with the reason. The terminal interface falls back to default when it loads the theme and posts the warning as a status message; tmail themes does not log it today.