X-Git-Url: https://git.rmz.io/dotfiles.git/blobdiff_plain/3b5e99b9e0c217919225b705e6fb2b7095341b4d..b0876bc435231da3f114277d8f88a2237d0b49e8:/zsh/lib/99-prompt.zsh?ds=sidebyside diff --git a/zsh/lib/99-prompt.zsh b/zsh/lib/99-prompt.zsh new file mode 100644 index 0000000..f5ea7ed --- /dev/null +++ b/zsh/lib/99-prompt.zsh @@ -0,0 +1,141 @@ +# Setup the prompt with pretty colors +setopt prompt_subst +autoload colors; colors; + +hostcolor=cyan +[[ $(hostname) == "tardis" ]] && hostcolor=red + +if (( ! $+functions[task_today_list] )) then + function task_today_list {} +fi + +precmd() { + PROMPT=$'%T $(task_today_list)%n@%{$fg[$hostcolor]%}%m$(jobs_prompt)%-0>..>$(git_prompt_status)%>>\n' + PROMPT+=$'$(virtualenv_prompt)%(?..%{$fg_bold[white]%}%?)%{$reset_color%}$(vi_prompt_info)%{%(!.$fg[red]❰.$fg[green]❱)%1G%} ' + RPROMPT='%{$fg[green]%}%~%{$reset_color%}' +} + +jobs_prompt() { + printf '%s' "%(1j. $fg_bold[white]↵%{$fg_bold[red]%}%j.)%{$reset_color%}" +} + +vi_prompt_info() { + local vicmd="$fg_bold[green]❰$reset_color%1G" + local viins="$fg_bold[blue]❱$reset_color%1G" + local map=${KEYMAP:-viins} + printf '%s' "%{${${map/vicmd/$vicmd}/(main|viins)/$viins}%}" +} + +function zle-line-init zle-line-finish zle-keymap-select { + zle reset-prompt + zle -R +} + +# zle -N zle-line-init +# zle -N zle-line-finish +zle -N zle-keymap-select + +# reset zle on resize +TRAPWINCH() { + zle && { zle reset-prompt; zle -R } +} + +# Get the status of the working tree +git_prompt_status() { + if ! git rev-parse --is-inside-work-tree &>/dev/null; then + return + fi + local oid head ahead behind + local added deleted modified renamed unmerged untracked dirty + # Use porcelain status for easy parsing. + local status_cmd="git status --porcelain=v2 -b" + + # Get current status. + while IFS=$'\n' read line; do + if [[ "$line" == \#\ * ]]; then + [[ "$line" =~ '# branch.oid ([0-9a-f]+)' ]] && oid=$match[1] + [[ "$line" =~ '# branch.head (.*)' ]] && head=$match[1] + [[ "$line" =~ '# branch.upstream (.*)' ]] && upstream=$match[1] + [[ "$line" =~ '# branch.ab \+([0-9]+) -([0-9]+)' ]] && ahead=$match[1] && behind=$match[2] + else + # Count added, deleted, modified, renamed, unmerged, untracked, dirty. + # T (type change) is undocumented, see http://git.io/FnpMGw. + # index + [[ "$line" == 1\ M[.MTD]\ * ]] && (( updated++ )) + [[ "$line" == 1\ [AC][.MTD]\ * ]] && (( added++ )) + [[ "$line" == 1\ D[.MT]\ * ]] && (( deleted++ )) + [[ "$line" == 2\ R[.MTD]\ * ]] && (( renamed++ )) + + # work tree + [[ "$line" == 1\ [.MARCT]A\ * ]] && (( added++ , modified++ )) # intend-to-add + [[ "$line" == 1\ [.MARCT]M\ * ]] && (( modified++ )) + [[ "$line" == 1\ [.MARCT]D\ * ]] && (( deleted_wt++ )) + [[ "$line" == \?\ * ]] && (( untracked++ )) + + # merge conflicts + [[ "$line" == u\ (AA|DD|U?|?U)\ * ]] && (( unmerged++ )) + + #TODO more info for submodules? + fi + done < <(${(z)status_cmd} 2> /dev/null) + + local git_status=" " + + # Format branch and commit + git_status+="%{$fg_bold[green]%}$head" + git_status+="%{$fg_no_bold[yellow]%}(${oid[1,8]})" + + # Format upstream + git_status+="%{$fg[blue]%}" + [[ -z "$upstream" ]] && git_status+=" Ɇ" + (( ahead > 0 )) && git_status+=" >$ahead" + (( behind > 0 )) && git_status+=" <$behind" + + # Format push + git_status+="%{$fg_bold[blue]%}" + push_ab=( $(git rev-list --left-right --count @...@{push} 2>/dev/null) ) + if (( $? == 0 )); then + (( push_ab[1] > 0 )) && git_status+=" ⮝$push_ab[1]" + (( push_ab[2] > 0 )) && git_status+=" ⮟$push_ab[2]" + fi + + # Format stashed + git_status+="%{$fg_bold[cyan]%}" + stashed=$(git stash list | wc -l) + (( stashed > 0 )) && git_status+=" ⋎$stashed" + + # Format index + git_status+="%{$fg_no_bold[green]%}" + (( updated > 0 )) && git_status+=" *$updated" + (( added > 0 )) && git_status+=" +$added" + (( deleted > 0 )) && git_status+=" -$deleted" + (( renamed > 0 )) && git_status+=" ≈$renamed" + + # Format working tree + git_status+="%{$fg_no_bold[red]%}" + (( modified > 0 )) && git_status+=" *$modified" + (( deleted_wt > 0 )) && git_status+=" -$deleted_wt" + (( untracked > 0 )) && git_status+=" +$untracked" + git_status+="%{$fg_no_bold[magenta]%}" + (( unmerged > 0 )) && git_status+=" ♒$unmerged" + + git_status+="%{$reset_color%}" + + echo $git_status +} + +function virtualenv_prompt() { + if [[ -z $VIRTUAL_ENV ]] then + echo "" + else + echo "(${VIRTUAL_ENV##*/}) " + fi +} + +function print_if_fits() { + local zero length + + zero='%([BSUbfksu]|([FB]|){*})' + length=${#${(S%%)1//$~zero/}} + echo "%-$length(l.$1.)" +}