- Introduction
- Reference
- Getting Started
- Text
- Colors
- Styles
- Decorations
- Labels
- Surround
- Multiline
- Links
- Prompt End
- Scrollback Theme
- Basic Theme
- Module Specific Settings
- Faux Modules
This guide will explain the configuration for Apollo and go over creating a basic theme. All configuration is done using zstyles, so I highly recommend reviewing the zsh/util documentation.
Zstyle definitions assign a value to an attribute based on context, and the flexibility of this context is what makes it so useful. Below is a guide to describe the structure of context within Apollo.
zstyle ':apollo:<theme>:<line>:<prompt_side>:<module>:<mode>:<element>:<element/module_side>' attribute "value"
^ ^ ^ ^ ^ ^ ^ ^
| | | | | | | Attribute name
| | | | | | |
| | | | | | left or right side of module/element text if applicable. * for both
| | | | | |
| | | | | Subsection of module. Possibly module specific.
| | | | |
| | | | Module mode. Value of * applies to all modes
| | | |
| | | Module name. Value of * applies to all modules
| | |
| | left or right prompt. * for both
| |
| Prompt line number. * for all lines
|
Active theme or * for all themes
Every module has the following attributes available:
Attribute | Type | Description |
---|---|---|
min_width | integer | Minimum width to enforce on module. |
always_show | boolean | Show module even when it contains empty output. |
fg_color | color | Foreground color for module. |
bg_color | color | Background color for module. |
style | list | Style for module text (bold,standout,underline) |
always_refresh | boolean | Force refresh of prompt on async update even if module text hasn't changed. |
All modules include the following elements provided by the framework:
Element | Description |
---|---|
main | This is the module text itself |
separator | String to use as left module separator when NOT at beginning of line |
begin | String to use to left of module when at beginning of line |
end | String to use to right of module when at end of line |
left:surround | String to left of module text |
right:surround | String to right of module text |
Two special elements can be set at the module level AND as extensions of individual regular elements:
Element | Description |
---|---|
left:label | String to left of module/element |
right:label | String to right of module/element |
To better understand how these all fit together, here's a quick reference. The first is a look at the module as a whole, the second is a closer breakdown of module_text, which is made up of the elements inside the module:
{separator/begin}{left:surround}{left:label}{module_text}{right:label}{right:surround}{end}
{left:label}{element1_text}{right:label}{left:label}{element2_text}{right:label}{etc...}
Every element has the following attributes available:
Attribute | Type | Description |
---|---|---|
fg_color | color | Foreground color |
bg_color | color | Background Color |
text | string | String to display |
style | list | Style for element text (bold,standout,underline) |
blend* | boolean | Determines fg_color and bg_color from adjacent modules. |
revblend* | boolean | Determines fg_color and bg_color from adjacent modules. Reversed colors compared to blend |
*Overrides fg_color and bg_color. Only valid for begin/end and separator elements.
The "text" attribute will not have an effect in many cases if the text is dynamic and generated by the module, but any elements with static text may utilize the "text" attribute.
All other module options should be controlled via attributes at the module scope, even if they only impact an individual element in the module. This is done for the sake of providing a uniform configuration interface.
Examples:
zstyle ':apollo:example:*:*:*:*:surround:*' text " "
zstyle ':apollo:example:*:right:*:*:separator' text ""
zstyle ':apollo:example:*:right:*:*:separator' revblend "true"
zstyle ':apollo:example:*:left:*:*:separator' text ""
zstyle ':apollo:example:*:left:*:*:separator' blend "true"
zstyle ':apollo:example:*:*:*:*:begin' blend "true"
zstyle ':apollo:example:*:*:*:*:begin' text ""
zstyle ':apollo:example:*:*:*:*:end' blend "true"
zstyle ':apollo:example:*:*:*:*:end' text ""
Apollo will load additional configuration files from ${XDG_CONFIG_HOME}/.config/apollo/ or from ${HOME}/.config/apollo/ if XDG_CONFIG_HOME is not set. The file must have a .conf extension. This is where you should place any themes in development or for personal use. I highly recommend not setting module lists as part of the theme so that users can easily decide their own module lists without being theme dependent. I do however recommend testing themes with a variety of module configurations to ensure that it maintains the desired look. Module lists are defined by the following:
zstyle ':apollo:*:core:modules:left' modules 'root_indicator' 'context' 'public_ip' 'virtualenv' 'quota' 'newline' 'vi_mode' 'dir' 'ruler'
zstyle ':apollo:*:core:modules:right' modules 'command_execution_time' 'status' 'php_version' 'newline' 'background_jobs' 'git' 'date' 'clock'
The vast majority of elements are defined by setting a "text" attribute. The text attributes accept any string and unicode characters are supported. Unicode characters can be added directly either by copying the glyphs or using unicode escape sequences within ANSI-C quotes. If you'd like to generate a full chart of unicode characters and their escape sequences, you can add the following function to your shell configuration:
unicode_chart() {
local x y a
for ((y=0;y<=65535;y++)); do
for x in 0 1 2 3 4 5 6 7; do
a=$(([##16]y))
a="${(l:4::0:)a}"
printf "%-10s %-10b" "\\u$a" "\\u$a "
((y++))
done
((y--))
echo
done
for ((y=65536;y<=1114109;y++)); do
for x in 0 1 2 3 4 5 6 7; do
a=$(([##16]y))
printf "%-10s %-10b" "\\U$a" "\\U$a "
((y++))
done
((y--))
echo
done
}
This generates 26MB of output, so I highly recommend redirecting output to a file.
Compatibility note: Unicode character support is highly dependent on terminal and font. Unfortunately there's no reliable way to test what an environment supports, so if your theme is dependent on a specific font, be sure to note it.
Every element accepts two different attributes for color, fg_color and bg_color. As you'd expect, these are for setting the color of the font and the background color. Each of them accepts one of the following values:
- Color names per https://jonasjacek.github.io/colors/
- Numbers between 0 and 255
- 24-bit #RRGGBB hex codes
zstyle ':apollo:example:*' fg_color white
zstyle ':apollo:example:*:*:*:*:surround:*' fg_color blue
zstyle ':apollo:example:*:core:*' fg_color red
zstyle ':apollo:example:core:prompt:end' fg_color blue
Compatibility note: Just like with unicode characters, color support is very dependent on the terminal environment. Most modern environments support 24-bit truecolor, but support for 256 color palette is much better, and all terminals should support the base 8 color palette.
All elements support a style attribute. This attribute accepts a list of one or more of the following options:
- bold
- standout
- underline
Decorations consist of strings to place at the beginning and end of each prompt lines, as well as the separators between modules. These elements support the normal color attributes, as well as two additional attributes:
- blend
- revblend
These override the default color attributes, and instead inherit colors from the adjacent modules. For example to replicate the popular powerline style you can set the following:
zstyle ':apollo:example:*:*:*:*:begin' text ""
zstyle ':apollo:example:*:left:*:*:separator' text ""
zstyle ':apollo:example:*:right:*:*:separator' text ""
zstyle ':apollo:example:*:*:*:*:end' text ""
zstyle ':apollo:example:*:*:*:*:(begin|end)' blend "true"
zstyle ':apollo:example:*:left:*:*:separator' blend "true"
zstyle ':apollo:example:*:right:*:*:separator' revblend "true"
Decorations have a negligible performance impact, but if they're not used on your theme the logic can be disabled with the following:
zstyle ':apollo:example:core:decorations' disabled "true"
All modules, as well as the elements provided by modules, support left and right label text.
In addition to left and right labels, modules can add left and right surround strings.
zstyle ':apollo:example:*:*:*:*:surround:left' text "("
zstyle ':apollo:example:*:*:*:*:surround:right' text ")"
Multiline prompts are supported by adding "newline" or "ruler" to the module lists. Ruler is only valid for the left module list, and the right list can not span more lines than the left. The ruler will display a configurable string spanning from the left prompt to the right. The string will repeat itself as needed to bridge the gap and resize with window changes.
zstyle ':apollo:example:*:core:ruler' text "─"
Multiline prompts can also add additional strings to the beginning and end of each line. These are intended for characters that visually tie the lines together but any strings is valid. This must also be explicitly enabled.
zstyle ':apollo:example:core:links' enabled "true"
zstyle ':apollo:example:*:*:core:links:none' text ""
zstyle ':apollo:example:*:left:core:links:top' text "╭─"
zstyle ':apollo:example:*:left:core:links:mid' text "├─"
zstyle ':apollo:example:*:left:core:links:str' text "│ "
zstyle ':apollo:example:*:left:core:links:bot' text "╰─"
zstyle ':apollo:example:*:right:core:links:top' text "─╮"
zstyle ':apollo:example:*:right:core:links:mid' text "─┤"
zstyle ':apollo:example:*:right:core:links:str' text " │"
zstyle ':apollo:example:*:right:core:links:bot' text "─╯"
Prompt end allows for adding a string at the very end of the prompt just before the cursor.
zstyle ':apollo:example:core:prompt:end' text "> "
The scrollback theme setting sets the theme to use after executing a command and saving a line to the scrollback buffer. The value should point to an actual theme name, so if you'd like to customize this you should create a separate theme. This primarily provides a way of shrinking a multiline theme down to a single line theme to save space. Note that asynchronous modules will NOT run for a scrollback theme.
zstyle ':apollo:example:core:scrollback' theme "scrollback"
This is a simple theme I created to demonstrate some of the settings mentioned above. It starts off with setting the general colors for the theme and then moves on to set more specific things.
zstyle ':apollo:bluefade:*' fg_color white
zstyle ':apollo:bluefade:*' bg_color blue
zstyle ':apollo:bluefade:*:*:*:*:begin' text "░▒▓"
zstyle ':apollo:bluefade:*:*:*:*:end' text "▓▒░"
zstyle ':apollo:bluefade:*:*:*:*:surround:*' text " "
zstyle ':apollo:bluefade:*:*:*:*:separator' text "|"
zstyle ':apollo:bluefade:*:*:*:*:(begin|end)' blend true
zstyle ':apollo:bluefade:*:core:ruler' bg_color none
zstyle ':apollo:bluefade:*:core:ruler' fg_color blue
zstyle ':apollo:bluefade:*:core:ruler' text "\|/_"
zstyle ':apollo:bluefade:core:scrollback' theme scrollback
In general I recommend leaving module specific settings outside of the theme, as it would require users to override settings for the specific theme if they want something different. That said, it's generally fine to configure how something will display as long as you avoid deciding what will be displayed. For example it's fine to style individual elements for the git module, but setting the list of elements to display should be avoided in most cases. Ideally the user should be able to switch themes without it impacting the information displayed.
It's technically possible to create a simple module using only zstyle. This is done by setting the main module text. You can set it to a static string, a variable, command substitution, or whatever other shell expression. Pay close attention to quoting. If it's something you want to evaluate on every run, it should be encased in single quotes or properly escaped. Otherwise it will only be evaluated when the style is set on startup. Keep in mind that since these "modules" don't have a cache key function, they won't make use of the module cache. Therefore this should only be used for simple tasks.
zstyle ':apollo:example:*:*:fake:*:main' text "\$variable"
zstyle ':apollo:example:*:*:fake:*:main' text '$(some_function)'