Invite de commande Zsh avec statut Git asynchrone
Vincent Bernat
Zsh propose vcs_info
, une fonction permettant de récupérer des
informations liées à l’état du système de gestion des versions pour
actif dans le répertoire en cours. Il alimente une variable qui peut
ensuite être utilisée dans une invite de commande. Plusieurs logiciels
sont supportés, notamment Git et SVN. Voici un exemple de
configuration :
autoload -Uz vcs_info zstyle ':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
Vous pouvez ensuite utiliser la variable ${vcs_info_msg_0_}
dans
votre invite pour afficher la branche actuelle, la présence de
fichiers modifiés ainsi que l’action courante1. Jetez un œil à la
documentation pour plus de détails.
Sur les gros dépôts, certaines informations peuvent être coûteuses à
récupérer. Pendant que vcs_info
interroge Git, les interactions avec
Zsh sont bloquées. Une solution est d’exécuter vcs_info
de manière
asynchrone avec zsh-async.
La première étape est de définir un wrapper autour de
vcs_info
. Celui-ci s’exécutera dans un processus séparé et devra
communiquer son résultat en utilisant la sortie standard. Il attend le
répertoire courant en premier argument.
_vbe_vcs_info() { cd -q $1 vcs_info print ${vcs_info_msg_0_} }
La seconde étape est de définir un worker, également nommé
vcs_info
, et d’attacher une fonction qui traitera le résultat issu
du wrapper. Cette fonction appelle zle reset-prompt
pour forcer
un nouvel affichage de l’invite de commande avec les informations à
jour issues de ${vcs_info_msg_0_}
.
source $ZSH/.../async.zsh async_init async_start_worker vcs_info async_register_callback vcs_info _vbe_vcs_info_done _vbe_vcs_info_done() { local stdout=$3 vcs_info_msg_0_=$stdout zle reset-prompt }
La dernière étape est de demander l’exécution du wrapper au
worker avant d’afficher le prompt. Cela remplace l’invocation
synchrone de 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
C’est tout !
Sans se reposer sur vcs_info
, il serait possible d’améliorer
l’expérience en consultant le nom de la branche courante avant de
récupérer les informations plus coûteuses. Cependant, avec peu
d’efforts, cette intégration simple permet de répondre l’invite plus
rapide ! Jetez un œil au code complet : il contient
quelques améliorations.
-
Les actions incluent « merge », « rebase » et « bisect ». ↩︎