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

Re: Look for git info in background



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
  }



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