Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: Look for git info in background

After compiling up a 5.0.5 (and commenting out most of my .zshrc as some option was causing a "can't clobber parameter" file descriptor issue) I finally got it working - very neat!



On 08/04/14 16:25, Bart Schaefer wrote:
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
     zle -F $1
     exec {1}>&-
     zle reset-prompt
   zle -N update_super_status

   chpwd () {
     if zle -l update_super_status
       PROMPT='%m[waiting] $ '

   precmd () {
     if zle -l update_super_status
       (( 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

Messages sorted by: Reverse Date, Date, Thread, Author