Zsh Prompt Customization

2019-08-12 06:35发布

Hi I know that you set the prompt variable to edit the prompt like this

export PROMPT="This is the date %d"

How do you execute a command and print the result everytime when prompt loads.

1条回答
放荡不羁爱自由
2楼-- · 2019-08-12 06:46

There are actually two (main) ways to achieve this:

  1. Use command substitution to run a command as part of the prompt

    setopt promptsubst
    PROMPT='Date %d Result $(a_command) '
    
    • promptsubst has to be enabled, else zsh will not do any paremeter expansions, arithmetic expansions or command substitutions.
    • Also, the prompt text needs to be quoted in such a way that the expansions are not made when setting PROMPT. So either put it in single quotes or, if you have/want to use double quotes, prepend $ with a \ to quote them separately where necessary:

      PROMPT="Date %d Result \$(a_command) Const $(another_command)"
      

      This will expand $(another_command) when setting PROMPT (so it is run only once and its result than substituted permanently) and $(a_command) every time the prompt is shown.

  2. Make use of the precmd function (or hook) and the psvar array:

    autoload -Uz add-zsh-hook
    a_function () {
        psvar[1]=$(a_command)
    }
    two_function () {
        psvar[2]=$(two_command)
    }
    add-zsh-hook precmd a_function
    add-zsh-hook precmd two_function
    PROMPT='Date %d Result1 %v Result2 %2v '
    
    • If set, the precmd function is run just before the prompt is printed. You can also set a list of functions to run in the precmd_functions array.
    • add-zsh-hook provides an easy way to add functions to that array.
    • %Nv in the prompt is replaced by the N-th element of the psvar array. If N is left out (%v) N==1 is assumed (this is also true for other prompt token that take numeric arguments)

On first glance the second method may look far more complicated then just using promptsubst. But this is only the case for very simple substitutions. Using precmd allows for using more complex functions without making the definition of PROMPT unreadable due to cramming several lines of code inside a $( ).

You can also combine both approaches and forego the use of psvar in some or all cases:

autoload -Uz add-zsh-hook
setopt promptsubst
a_function () {
    a_parameter=$(a_command)
}
two_function () {
    psvar[2]=$(two_command)
}
add-zsh-hook precmd a_function
add-zsh-hook precmd two_function
PROMPT='Date %d Result ${a_parameter} %2v'
查看更多
登录 后发表回答