Customize Your Zsh Prompt

[ ]

The content is recoverd from Wordpress Blog, for more details please check HERE

June 2, 2019

VOID001 Comments 4 comments

Screenshot

This image has an empty alt attribute; its file name is 78d4e48a5339575a8227fa866adcb765b8b641.png

You may need “good network condition” to preview this anime

Screenshot for my zsh prompt Instructions ————

I choose to use zsh promptinit system to write my own themes, which can be easily managed by zsh prompt

Before you start

the promptinit uses autoload mechanism to load the theme file, so first we need to ensure the theme file locates inside fpath, if not, we should add the path containing your theme file into fpath array, just like the following (suggest my theme is in ~/.zsh/themes):

fpath=(~/.zsh/themes $fpath)

Remember to put this line before any fpath & autoload modification, e.g: if you are using grml-zsh-config, it’s recommended to put this line into ~/.zsh.pre

And then you should set the theme file name to prompt_<theme>_setup, this will be recognized by the zsh promptinit system. Then create a function named prompt_<theme>_setup inside your theme file. Your theme file now should have a basic skeleton like this (e.g: your theme name is moe).

prompt\_moe\_setup () {

}

prompt\_moe\_setup [[email protected]](/web/20210514143128/https://void-shana.moe/cdn-cgi/l/email-protection)

According to the manpage [1], You can declare the following functions for your prompt theme:

Quick reference to hook functions: zsh has some defined hook functions, such as precmd, preexec, etc, you can define an array with the string “_functions” append, such as precmd_functions, You can try echo $precmd_functions to see what’s the content inside. And all the elements inside the array will be treated as functions, execute with the same context and argument as the basic function. If the function not found, just siliently ignore it, and continue to next one. for more information please refer to the zsh doc functions section [2]

Customize the PS, RPS

By convention, themes use for PS1, PS2, RPS1, etc. instead of PROMPT, RPROMPT. As the example above, inside prompt_moe_setup we can define PS1, PS2, etc. But what are PS1, PS2, RPS1?

There are also other prompt parameters(officially called parameters by zsh, but I think maybe variable is more intuitive) such as PS3,PS4, etc. but we don’t really use it in common. For all the prompt variables, they all accept the same prompt escape sequence. The following are some commonly used escape sequence:

For a full escape sequence reference please refer to the zsh-manual Propmt Expansion [3]. To debug your prompt string, you can simply use print -rP <STRING> to see the effect of your prompt, no need to reload zsh each time.

A trick of displaying error code information: I use %(?..%F{red}\(?%f) to display the error code in )RPS1, it will only show a red error code when the error code is not 0. The form %(?.<true-text>.<false-text>) is a conditional substring, means when the exit status of the last command is not 0, it will display the <false-text> else display <true-text>, we just leave the <true-text> blank so it won’t display anything when the command exit without any error.

Enable version control info

It might be good to display the git info (or other vcs) along with your prompt. zsh has a powerful module vcs_info that can help you with this need.

For a quick start, you need to add the following lines into your theme file. (Still use the example above)

prompt\_opts=(subst percent)

function prompt\_moe\_precmd() {
    vcs\_info
}

Then append \(vcs_info_msg_0_ into your prompt. Be careful that you should append the plain text \)vcs_info_msg_0 instead of this variable, since the variable will be evaluated only when it is declared, while the plain mode is subjected to Parameter Expansion [3], that is, it will be evaluated each time the text displays. The following line is an example of adding vcs_info to your PS1:

PS1="$PS1 \$vcs\_info\_msg\_0\_"

You might want also customize the $vcs_info_msg_0_ prompt, such as changing the color, add / remove information displayed. You can achieve this with zstyle. Following are a list of common options:

Note that we use “:vcs_info:*” above to match for all kinds of vcs systems as long as all repos to give them the settings. If you want to set different options for specified repos / vcs (e.g: Disable the check-for-changes for kernel repo since it’s too big and cause delay), see the example below:

zstyle ':vcs\_info:*:*:latest-linux-kernel' check-for-changes false

This will only disable check for unstaged change for repo with root directory named “latest-linux-kernel”.

About a full reference about vcs_info usage and configuration, see zsh documentation for vcs_info [4]

Async Zsh Prompt

Although the vcs_info is useful, you may already found lags when turn on the the check-for-changes option, esp. in large repos. It’s annoying that the prompt doesn’t display instantly after we press enter. One option is to disable the check-for-changes option for these huge repos, however it’s just a workaround.

Fortunately, we have async zsh job support which can solve the problem. There are different kinds of async plugin we can use in zsh, for this blog we will use zsh-async [5].

zsh-async supports async jobs as well as callback handlers. Along with ZLE (Zsh Line Editor [6]) command zle reset-prompt we can achieve the async update of PS1:

function prompt\_moe\_setup() {
    # Other codes ...    
    async\_start\_worker vcs\_updater\_worker
    async\_register\_callback vcs\_updater\_worker do\_update
}

function do\_update() {
    vcs\_info
    zle reset-prompt
}

function prompt\_moe\_precmd() {
    async\_job vcs\_updater\_worker
}


And then you have your async vcs_info now! But the code above is somehow glitchy, An optimized one can be found here: https://gist.github.com/VOID001/588347b0ef4b3a14759579e8bf6acb23#file-prompt_moe_setup-L48 (Still have some glitches but it’s currently fine for me)

The code above does the following things:

Ending

Writing bash/zsh script is somehow painful for me so I previously stick to oh-my-zsh for a long time. However the zsh completion and git-prompt-info is so slow that always bother me. So I tried to switch to grml-zsh-config and define a custom prompt for me, what I found suprising is that writing (simple) zsh scripts are not as difficult as I think thanks to the well-documented zsh manpage and online manual. So I wrote this article as a “Zsh Theme Creation Quick Start Guide” for those who are dissatisfied with the oh-my-zsh themes and want to have a chance to create your own theme.

Thanks for @lilydjwg for giving me lots of help when writing the theme. Thanks for @swordfeng for providing me with cute sample theme.

References


archlinux, Linux linux, prompt, zsh


Historical Comments

  1. naruto-ding says: January 13, 2020 at 2:00 am Hello,

    1. VOID001 says: January 14, 2020 at 3:44 pm Hello naruto-ding, Glad you like it! But I am sorry to tell you that I don’t have enough time to finish that series. That series of video is made when I was a senior student. The neu-os and the video tutorial is for teaching use of the “Linux Operating System” course in my school. After I graduate I have many other things to work and study so I don’t have the time to do that. I tried to ask the current maintainer of neu-os in my previous school to continue publishing some video tutorials but they are also very busy. Making one episode of the series tutorial will take me more than 12 hours – 20 hours or even further, there are a lot of preparation needed such as the slides, the references, the sample code, etc.
      However, in the future although I cannot update these OS tutorial videos, I will try to post some short videos (not in series) related to the operating system (such as ext4 file system, linux utility, command-line tools, etc). This kind of video will be less time consuming to made and to watch. Also I think it will provide some useful information for the audience.
  2. naruto-ding says: January 13, 2020 at 2:10 am I realize the comments under each blog is quite slow. Hope to get the chance to consult with you for daily questions if it doesn’t bother you too much. Maybe your email for further contact. (✿◡‿◡)

    1. VOID001 says: January 14, 2020 at 3:46 pm Hello naruto-ding,
      You can find my contact information here: https://void-shana.moe/void
      Feel free to send me the email/in-site comments/questions about os via github issue https://github.com/VOID001/neu-os, I will be very happy to exchange thoughts with you.

    2. VOID001 says: January 14, 2020 at 3:46 pm Hello naruto-ding,
      You can find my contact information here: https://void-shana.moe/void
      Feel free to send me the email/in-site comments/questions about os via github issue https://github.com/VOID001/neu-os, I will be very happy to exchange thoughts with you.

Back