1

I perhaps may have started overthinking this, but I also couldn't find a suitable explanation for it. I recently installed oh-my-zsh and it comes with several themes that change the way the "prompt" looks and also the colors used, along with "where" the colors are used throughout the text.

If I understand this correctly there are several "base" colors, like some kind of red color, some green color, some blue, etc. The themes then can say "Hey I want a blue color here, and the specific blue color should be this hex value".

I'm confused as to why then the terminal emulator one uses can also apply a theme as well. I'm using HyperJS and I can apply a theme for it that seems to take charge over all of the colors, however the prompt layout can still be set via oh-my-zsh.

What's the difference between the themes being used in oh-my-zsh and a terminal's theme? Can someone explain the whole breakdown of what the themes are doing and such?

1

Terminal support for colors is specified by various standards, e.g. ECMA-48 or later standards that added more colors. These days terminals are mostly virtual windows and not dedicated hardware devices and the terminal emulated can usually be changed by setting the TERM environment variable—one can emulate a terminal that does not support colors, for example.

For modern terminals if you want colors the usual advice is to enable 256 color support, usually via TERM=xterm-256color as the old standards only specified far fewer colors. Various documents detail the exact codes used to generate colors, and this can be done manually

% print "\033[31;5mDANGER DANGER WILL ROBINSON\033[0m"
...

though for portability it is usually better to use a library such as ncurses or in your case specific ZSH syntax for the various color codes

% print -P '%F{red}DANGER%f'
...
% print -P '%F{red}DANGER%f' | hexdump -C
00000000  1b 5b 33 31 6d 44 41 4e  47 45 52 1b 5b 33 39 6d  |.[31mDANGER.[39m|
00000010  0a                                                |.|
00000011
% print "\033[31;5mxxx\033[0m" | hexdump -C
00000000  1b 5b 33 31 3b 35 6d 78  78 78 1b 5b 30 6d 0a     |.[31;5mxxx.[0m.|
0000000f

What oh-my-zsh is doing is bundling random bits of code similar to the above that (eventually) generate something like the \033[31m codes shown above that are then consumed by the terminal and displayed (or not). How the terminal handles these codes is up to the terminal, \033[31m ("foreground color red") could instead be displayed as green (or ignored); sets of such colors settings in the terminal might be called themes by the terminal software; this is completely distinct from oh-my-zsh themes despite using the same name.

  • Thank you for your response! So if I install a zsh theme it sounds like it’s more telling the shell where to put certain category of colors and then the terminal emulator can decide what the actual color of those categories are? Can different prompts affect this as well? – Max McKinney Sep 1 '18 at 17:36
1

Oh-my-zsh basicly does what the default promptinit of zsh already does. They just do it a bit differently, by sourcing theme files. The basic idea is that they modify the PS1, PS2, PS3 and PS4 values. Your terminal emulator doesn't change these values (afaik). For example, your $reset_color will be red if you have set in your terminal emulator that the default color of your font is red.

You can create your own theme on a stock ZSH install quite easily, for example, I have my own stock zsh theme (prompt):

You can create a file ~./.zsh/prompt/prompt_XXXXXXX_setup with the following content:

prompt_XXXXXXX_setup() {
    autoload -Uz colors && colors
    # You now have access to:
    # $fg[red] etc
    # $bg[red] etc
    # and the bold variant: $bg_bold and $fg_bold
    # and the $reset_color
    PROMPT="$fg_bold[blue]My shiney$reset_color $bg_bold[green]prompt %(!.#.%) " # although the docs seem to prefer you using PS1
}

prompt_XXXXXXX_setup "$@"

Now to enable this prompt:

zcompile ~/.zsh/prompt/prompt_XXXXXXX_setup # optional, but advised

# set this in your .zshrc and you will always have this as a prompt when using zsh
fpath=(~/.zsh/prompt $fpath)
autoload -Uz promptinit && promptinit && prompt XXXXXXX  

You can now switch prompts with prompt <name>, or get a list of prompts: prompt -l. If you want a more complicated setup, have a look here: zsh-prompt-powerline or my own setup. See also the ZSH docs here or source code of promptinit.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.