From: Amand Tihon Date: Wed, 17 Feb 2010 15:07:27 +0000 (+0100) Subject: Update git part of prompt. X-Git-Url: https://git.alrj.org/?p=zsh.d.git;a=commitdiff_plain;h=716984286bce77490f1462f905340d6e32013d35 Update git part of prompt. * Only recalculate git variables if needed. * Add symbols about repository status (clean, new, staged). * Some refactoring. --- diff --git a/S60_git b/S60_git index 8926a73..037e8b3 100644 --- a/S60_git +++ b/S60_git @@ -1,14 +1,97 @@ #! /usr/bin/zsh export __ZSH_GIT_BASEDIR="" -export __ZSH_GIT_BRANCH="" export __ZSH_GIT_SUBDIR="" -export __ZSH_GIT_STATE="" +export __ZSH_GIT_BRANCH="" +export __ZSH_GIT_ACTION="" +export __ZSH_GIT_STATUS="" export __ZSH_GIT_VARS_INVALID=1 +export __ZSH_GIT_STATUS_INVALID=1 + + +git_chpwd() { + # On cd, invalidate git status in prompt + export __ZSH_GIT_VARS_INVALID=1 +} + + +git_preexec() { + # On git command, invalidate git status in prompt + case "$1" in + git*) + export __ZSH_GIT_VARS_INVALID=1 + ;; + esac + + # *any* command could invalidate the repository status (new file, ...) + export __ZSH_GIT_STATUS_INVALID=1 +} + + +git_get_status() { + # Return only git status + local gitstat gitstatus + + gitstat=$(git status 2> /dev/null | grep '\(# Untracked\|# Changes\|# Changed but not updated:\)') + gitstatus="" + + if [[ $(echo ${gitstat} | grep -c "^# Changes to be committed:$") > 0 ]]; then + gitstatus='+' + fi + + if [[ $(echo ${gitstat} | grep -c "^\# Changed but not updated:$") > 0 ]]; then + gitstatus="${gitstatus}!" + fi + + if [[ $(echo ${gitstat} | grep -c "^# Untracked files:$") > 0 ]]; then + gitstatus="${gitstatus}?" + fi + + echo $gitstatus +} + git_parse() { + # psvar[3] == current action (merge, rebase, ...) + # psvar[4] == current branch + # psvar[5] == repository base directory + # psvar[6] == current subdir into repository + # psvar[7] == status (untracked, unstaged, staged) + + local git_dir ref base_dir sub_dir action branch gitstat gitstatus + + + # If nothing has been invalidated + if [[ "${__ZSH_GIT_VARS_INVALID}" == "0" && "${__ZSH_GIT_STATUS_INVALID}" == "0" ]]; then + + # reuse previous values + psvar[3]=${__ZSH_GIT_ACTION} + psvar[4]=${__ZSH_GIT_BRANCH} + psvar[5]=${__ZSH_GIT_BASEDIR} + psvar[6]=${__ZSH_GIT_SUBDIR} + psvar[7]=${__ZSH_GIT_STATUS} + + return + fi - local git_dir ref base_dir sub_dir action branch + # If only status has been invalidated + if [[ "${__ZSH_GIT_VARS_INVALID}" == "0" && "${__ZSH_GIT_STATUS_INVALID}" == "1" ]]; then + + # reuse previous values + psvar[3]=${__ZSH_GIT_ACTION} + psvar[4]=${__ZSH_GIT_BRANCH} + psvar[5]=${__ZSH_GIT_BASEDIR} + psvar[6]=${__ZSH_GIT_SUBDIR} + + export __ZSH_GIT_STATUS=$(git_get_status) + psvar[7]=${__ZSH_GIT_STATUS} + + export __ZSH_GIT_STATUS_INVALID=0 + return + fi + + + # Git prompt variables are invalid. Update them. git_dir=$(git rev-parse --git-dir 2> /dev/null) || return @@ -18,25 +101,25 @@ git_parse() { sub_dir=${sub_dir%/} ref=$(git symbolic-ref HEAD 2> /dev/null) || return - psvar[3]="" + action="" if [ -d "$git_dir/../.dotest" ]; then if [ -f "$git_dir/../.dotest/rebasing" ]; then - psvar[3]="-rebase" + action="-rebase" elif [ -f "$git_dir/../.dotest/applying" ]; then - psvar[3]="-am" + action="-am" else - psvar[3]="-am-rebase" + action="-am-rebase" fi branch="$ref" elif [ -f "$git_dir/.dotest-merge/interactive" ]; then - psvar[3]="-rebase-i" + action="-rebase-i" branch="$(cat "$git_dir/.dotest-merge/head-name")" elif [ -d "$git_dir/.dotest-merge" ]; then - psvar[3]="-rebase-m" + action="-rebase-m" branch="$(cat "$git_dir/.dotest-merge/head-name")" elif [ -f "$git_dir/MERGE_HEAD" ]; then - psvar[3]="-merge" + action="-merge" branch="$ref" else test -f "$git_dir/BISECT_LOG" && psvar[3]="bisect" @@ -45,10 +128,28 @@ git_parse() { branch="$(cut -c1-7 "$git_dir/HEAD")..." fi + # Status + gitstatus=`git_get_status` + # Got here, we're in git + psvar[3]=${action} psvar[4]=${branch#refs/heads/} psvar[5]=${base_dir} psvar[6]=${sub_dir} + psvar[7]=${gitstatus} + + # Save for next time + export __ZSH_GIT_BASEDIR="${base_dir}" + export __ZSH_GIT_SUBDIR="${sub_dir}" + export __ZSH_GIT_BRANCH="${branch#refs/heads/}" + export __ZSH_GIT_ACTION="${action}" + export __ZSH_GIT_STATUS="${gitstatus}" + + export __ZSH_GIT_VARS_INVALID=0 + export __ZSH_GIT_STATUS_INVALID=0 } + +chpwd_functions+='git_chpwd' +preexec_functions+='git_preexec' precmd_functions+='git_parse' diff --git a/S90_prompt b/S90_prompt index a9d379a..9ca2cd6 100644 --- a/S90_prompt +++ b/S90_prompt @@ -27,7 +27,7 @@ _exitcode="%(?::${C_BRED}[ %1v ]${C_NO} )$(true)" _action="%(3v,%3v%,)" -_path='${C_GREEN}%(5v,%20<..<%5v%<<${C_NO}${C_MAGENTA}@%4v%3v${C_NO}${C_GREEN}/%15<..<%6v%<<,%25<..<%~%<<)${C_NO}' +_path='${C_GREEN}%(5v,%20<..<%5v%<<${C_NO}${C_MAGENTA}@%4v%3v${C_BYELLOW}%7v${C_NO}${C_GREEN}/%15<..<%6v%<<,%25<..<%~%<<)${C_NO}' #