On Apr 8, 11:36am, Nick Cross wrote:
}
} Apologies for resurrecting such an old thread ;-) However, on the same
} topic rather than using vcs_info is it also possible to run a python
} script in the background to update the prompt e.g.
}
} PROMPT='%m$(git_super_status) $ '
The basic pattern is:
(1) precmd (or entry in precmd_functions) that creates a background
job writing to a file descriptor
(2) widget that reads from that descriptor and updates the prompt
(3) chpwd (or chpwd_functions) that clears the old info so the prompt
won't be misleading before the widget updates it
If the state can change rapidly at times other than change of directory,
drop the third step and clear the old info in the precmd.
Something I didn't deal with in the vcs_info example was the possibility
of a race, e.g., if new prompts appear faster than the background jobs
finish then you may have multiple of them waiting to update the prompt
and they may do so in the wrong order. The precmd ought to remove the
old handler before creating the new one.
The vcs_info example is also a little special because it communicates
through the vcs_info_msg_0_ parameter instead of text output, so to
background it required generating a typeset command to pass the value
up to the parent, which then eval'd the typeset. That's not needed
in a case like $(git_super_status) where the output is directly used.
I don't recall now why I decided to use a coproc for the background job
instead of <<(...) substitution, which is easier.
typeset -g update_prompt_fd
PROMPT='%m[waiting] $ '
update_super_status () {
PROMPT="%m$(read -rE -u$1) $ " # double quotes, not promptsubst
update_prompt_fd=0
zle -F $1
exec {1}>&-
zle reset-prompt
}
zle -N update_super_status
chpwd () {
if zle -l update_super_status
then
PROMPT='%m[waiting] $ '
fi
}
precmd () {
if zle -l update_super_status
then
(( update_prompt_fd )) && zle -F $update_prompt_fd >/dev/null
exec {update_prompt_fd}<<( git_super_status )
zle -F -w $update_prompt_fd update_super_status
fi
}