X-Git-Url: https://git.madduck.net/etc/zsh.git/blobdiff_plain/98e9afe73a2df757c892dc66046747b13898f140..a1bdf944d024ca91eca7637d8c0ce880ac2cae16:/.zsh/zshrc/85_git_prompt diff --git a/.zsh/zshrc/85_git_prompt b/.zsh/zshrc/85_git_prompt index 7e445b0..32d0e4f 100644 --- a/.zsh/zshrc/85_git_prompt +++ b/.zsh/zshrc/85_git_prompt @@ -7,36 +7,99 @@ # # Source repository: http://git.madduck.net/v/etc/zsh.git # -# Shamelessly adapted from http://www.jukie.net/~bart/conf/zsh.d/S55_git +# Shamelessly based on http://glandium.org/blog/?p=170 # -_get_git_cur_branch() { - git branch --no-color | sed -rne 's,^\* ,,p' +__git_get_repo_root() +{ + local relroot + relroot="$(git rev-parse --show-cdup 2>/dev/null)" || return 1 + if [ -n "$relroot" ]; then + readlink -f "$relroot" + else + echo $PWD + fi +} + +__git_get_branch() +{ + local ref + ref=$(git symbolic-ref -q HEAD 2>/dev/null \ + || git-name-rev --name-only HEAD 2>/dev/null) + echo "${ref#refs/heads/}" } -_is_git_repo() { - [ "$(git rev-parse --is-inside-work-tree)" = true ] +__get_root_offsets() +{ + local pwda reporoot loc + pwda=(${(s:/:)PWD}) + reporoot=(${(s:/:)1}) + echo $((1 - $#reporoot)) $(($#pwda - $#reporoot)) +} + +__get_prompt_path_components() +{ + local reporoot + reporoot="$1" + + set -- $(__get_root_offsets "$reporoot") + if [ "$2" -le 0 ]; then + echo %~ + else + echo "%${1}~" "%${2}~" + fi } -_set_git_psvar() { - if _is_git_repo; then - psvar[1]="$(_get_git_cur_branch)" +__vcs_get_repo_type() +{ + if __git_get_repo_root >/dev/null; then + echo git else - [ -n "$psvar[1]" ] && unset "psvar[1]" + echo NONE fi } +__vcs_set_prompt_variables() +{ + local pre branch post + local MAXLEN=25 + + case "${1:-$(__vcs_get_repo_type)}" in + git) + local reporoot="$(__git_get_repo_root)" + set -- $(__get_prompt_path_components "$reporoot") + branch="$(__git_get_branch)" + post="${(%)2}" + local prelen="$((MAXLEN - $#post - $#branch))" + [ $prelen -lt 10 ] && prelen=10 + pre="%${prelen}<..<${1}%<<" + pre="${(%)pre}" + ;; + *) + local p="%${MAXLEN}<..<%~%<<" + #TODO find a better way so we don't have to nuke $psvar, but since the + # %(nv.true.false) check for prompts checks element count, not + # content, that's all we get for now + psvar=("${(%)p}") + return + esac + + psvar[1]="$pre" + psvar[2]="$branch" + psvar[3]="$post" +} + update_git_vars_if_git_ran() { - # if the last command included the word git, the branch may have changed. - # checkout should be alright, but you never know... + local vcs="$(__vcs_get_repo_type)" case "$(history $(($HISTCMD - 1)))" in - *git*) _set_git_psvar;; + # $vcs appeared in last command, so be sure to update + *${vcs}*) __vcs_set_prompt_variables esac } precmd_functions+=update_git_vars_if_git_ran update_git_vars() { - _set_git_psvar + __vcs_set_prompt_variables } chpwd_functions+=update_git_vars