Jonghyeon Jeon
Jonghyeon Jeon

Reputation: 149

zsh & python. trying to use python script in zsh prompt, however, cannot

Hi I am trying to use python script to show my laptop's battery status on my zsh prompt. I am following this.

I made batcharge.py script in my ~/bin/ and I did chmod 755 batcharge.py in commad line.

this is batcharge.py script

#!/usr/bin/env python
# coding=UTF-8

import math, subprocess

p = subprocess.Popen(["ioreg", "-rc", "AppleSmartBattery"], stdout=subprocess.PIPE)
output = p.communicate()[0]

o_max = [l for l in output.splitlines() if 'MaxCapacity' in l][0]
o_cur = [l for l in output.splitlines() if 'CurrentCapacity' in l][0]

b_max = float(o_max.rpartition('=')[-1].strip())
b_cur = float(o_cur.rpartition('=')[-1].strip())

charge = b_cur / b_max
charge_threshold = int(math.ceil(10 * charge))

# Output

total_slots, slots = 10, []
filled = int(math.ceil(charge_threshold * (total_slots / 10.0))) * u'▸'
empty = (total_slots - len(filled)) * u'▹'

out = (filled + empty).encode('utf-8')
import sys

color_green = '%{[32m%}'
color_yellow = '%{[1;33m%}'
color_red = '%{[31m%}'
color_reset = '%{[00m%}'
color_out = (
    color_green if len(filled) > 6
    else color_yellow if len(filled) > 4
    else color_red
)

out = color_out + out + color_reset
sys.stdout.write(out)

and this is my .zshrc script.

BAT_CHARGE=~/bin/batcharge.py
function battery_charge {
    echo `$BAT_CHARGE` 2>/dev/null
}
set_prompt(){
NEWLINE=$'\n'
PROMPT="%F{202}%n%f at %F{136}%m%f in %F{green}%1~%f${NEWLINE}%# "
RPROMPT='$(battery_charge)'
}
autoload add-zsh-hook
add-zsh-hook precmd set_prompt

and I restarted my shell, however, it keeps showing '% $(battery_charge)

where did I do wrong?

Upvotes: 1

Views: 604

Answers (1)

chepner
chepner

Reputation: 532003

You need to enable the PROMPT_SUBST option for command substitutions to be evaluated in a prompt.

(Also, there's no need to define BAT_CHARGE or battery_charge; just call your Python script directly from the prompt.)

setopt PROMPT_SUBST
set_prompt(){
  NEWLINE=$'\n'
  PROMPT="%F{202}%n%f at %F{136}%m%f in %F{green}%1~%f${NEWLINE}%# "
  RPROMPT='$(~/bin/batcharge.py)'
}
autoload add-zsh-hook
add-zsh-hook precmd set_prompt

And even more simply, since you are setting the value of RPROMPT each time it is displayed using the precmd hook, you don't need an embedded command substitution in the first place. Just set RPROMPT directly:

set_prompt(){
  NEWLINE=$'\n'
  PROMPT="%F{202}%n%f at %F{136}%m%f in %F{green}%1~%f${NEWLINE}%# "
  RPROMPT=$(~/bin/batcharge.py)
}
autoload add-zsh-hook
add-zsh-hook precmd set_prompt

Upvotes: 2

Related Questions