Zsh prompt with asynchronous Git status (2024)

Zsh ships vcs_info, a function fetching information about theVCS state for the current directory and populating a variable that canbe used in a shell prompt. It supports several VCS, including Git andSVN. Here is an example of configuration:

autoload -Uz vcs_infozstyle ':vcs_info:*' enable git() { local formats="${PRCH[branch]} %b%c%u" local actionformats="${formats}%{${fg[default]}%} ${PRCH[sep]} %{${fg[green]}%}%a" zstyle ':vcs_info:*:*' formats $formats zstyle ':vcs_info:*:*' actionformats $actionformats zstyle ':vcs_info:*:*' stagedstr "%{${fg[green]}%}${PRCH[circle]}" zstyle ':vcs_info:*:*' unstagedstr "%{${fg[yellow]}%}${PRCH[circle]}" zstyle ':vcs_info:*:*' check-for-changes true}add-zsh-hook precmd vcs_info

You can use ${vcs_info_msg_0_} in your prompt to display the currentbranch, the presence of staged and unstaged changes, as well as theongoing action.1 Have a look at the documentation for moredetails.

Zsh prompt with asynchronous Git status (1)

On large repositories, some information are expensive to fetch. Whilevcs_info queries Git, interactions with Zsh are stuck. A possiblesolution is to execute vcs_info asynchronously with zsh-async.

The first step is to define a wrapper around vcs_info. Thiswrapper will run into a separate process and should communicate itsresult using the standard output. It expects the current directory asits first argument.

_vbe_vcs_info() { cd -q $1 vcs_info print ${vcs_info_msg_0_}}

The second step is to define a worker, vcs_info, and attach afunction to handle the result received from the wrapper. Theregistered function calls zle reset-prompt to force a refresh of theprompt with the updated information from ${vcs_info_msg_0_}.

source $ZSH/.../async.zshasync_initasync_start_worker vcs_infoasync_register_callback vcs_info _vbe_vcs_info_done_vbe_vcs_info_done() { local stdout=$3 vcs_info_msg_0_=$stdout zle reset-prompt}

The last step is to schedule the wrapper function in the workerqueue before displaying the prompt. This replaces the synchronousinvocation of vcs_info:

_vbe_vcs_precmd() { async_flush_jobs vcs_info async_job vcs_info _vbe_vcs_info $PWD}add-zsh-hook precmd _vbe_vcs_precmd

That’s it!

Without relying on vcs_info, it should be possible to have a betterexperience by fetching the current branch name before retrieving themore expensive information. However, without much effort, this simpleintegration can make your prompt snappier! Have a look at thecomplete code: it contains some small enhancements.

  1. Actions include “merge,” “rebase” and “bisect.”↩︎

Zsh prompt with asynchronous Git status (2024)
Top Articles
Latest Posts
Article information

Author: Catherine Tremblay

Last Updated:

Views: 6416

Rating: 4.7 / 5 (47 voted)

Reviews: 94% of readers found this page helpful

Author information

Name: Catherine Tremblay

Birthday: 1999-09-23

Address: Suite 461 73643 Sherril Loaf, Dickinsonland, AZ 47941-2379

Phone: +2678139151039

Job: International Administration Supervisor

Hobby: Dowsing, Snowboarding, Rowing, Beekeeping, Calligraphy, Shooting, Air sports

Introduction: My name is Catherine Tremblay, I am a precious, perfect, tasty, enthusiastic, inexpensive, vast, kind person who loves writing and wants to share my knowledge and understanding with you.