5

I would like to add the output of a Python script into my zsh prompt but I am not sure how to do it?

Is this done by what is called "PROMPT EXPANSION" in the man pages?

Please someone set me on the right track, i.e. post some helpful links I could not find with Google.

slm
  • 369,824

2 Answers2

10

There are two principal ways:

  1. Parameter expansion by enabling PROMPT_SUBST
  2. The psvar array

1. Parameter expansion in prompt

If PROMPT_SUBST is enabled

setopt PROMPT_SUBST

the prompt is subjected to parameter expansion, command substitution and arithmetic expansion before it is evaluated.

That way, the output of a script can be included via command substitution. For example:

PROMPT='Look at this: $(python yourscript.py) >'

If the output contains escape sequences (%~, %M, %F{red} etc.) they will be evaluated before the prompt is printed.

2. The psvar array

One of the first nine values of the array psvar can be set to the output of the script. It can then be recalled by using %Xv, where X is a number between 1 and 9 (defaults to 1 if X is left out).

psvar[5]=$(python yourscript.py)
PROMPT='Look at this: %5v >'

In order to refresh the value every time before the prompt is printed, the hook function precmd has to be set:

precmd() {
    psvar[5]=$(python yourscript.py)
}

If there already is a precmd function, or if more than one function is to be used, it is a good idea to use add-zsh-hook.

# load add-zsh-hook, need to be done only once
autoload -Uz add-zsh-hook

pyscript() {
    psvar[5]=$(python yourscript.py)
}

add-zsh-hook precmd pyscript

This adds pycript to the list of functions that need to be run before printing the prompt.

Jeff Schaller
  • 67,283
  • 35
  • 116
  • 255
Adaephon
  • 4,456
  • though using the solution with psvar the return string itself is not not evaluuated as you showed in solution 1. Is there a possibility to do this also in solution 2? – Cutú Chiqueño Sep 27 '14 at 12:20
4

You can do this by setting up a precmd hook which will take the output of the command and format it as you want, and then make it available to your PROMPT. Minimally, you need:

autoload -U add-zsh-hook
add-zsh-hook precmd my_precmd_hook_function

Define my_precmd_hook_function to call your python script and capture its output in a variable. You can then use that variable in your $PROMPT:

my_precmd_hook_function() {
  python_says=$(myPythonScript arg1 arg2)
}

PROMPT='$python_says'

You can set as many variables as you need in your precmd hook and use them to build a quite complex PROMPT. Just bear in mind that the more you do in the precmd hook, the longer it will take zsh to draw the prompt and return control to you. If your python script is more than trivially simple, you will undoubtedly notice a lag.

You can see the full range of possibilities in the SIMPLE PROMPT ESCAPES section of the zshmisc man page.

D_Bye
  • 13,977
  • 3
  • 44
  • 31
  • 1
    Note that the shell option PROMPT_SUBST needs to be enabled in order to expand parameters in the prompt string. – Adaephon Sep 26 '14 at 13:09