]> git.rmz.io Git - dotfiles.git/blobdiff - zsh/lib/prompt.zsh
zsh: move venv status to second line of prompt
[dotfiles.git] / zsh / lib / prompt.zsh
index 4f313482deefe0c0836d694a295dacb95efd51a3..3453f4b7234b25f499f6a7d4d8027965f8e68517 100644 (file)
@@ -1,16 +1,25 @@
-hostcolor=green
+# Setup the prompt with pretty colors
+setopt prompt_subst
+autoload colors; colors;
+
+hostcolor=cyan
 [[ $(hostname) == "tardis" ]]  && hostcolor=red
 
 precmd() {
-  PROMPT='%T %n@%{$fg[$hostcolor]%}%m%{$reset_color%}%-0>..>$(git_prompt_status)%>>
-%(?..%{$fg_bold[white]%}%?%{$reset_color%})$(vi_prompt_info)%{%(!.$fg[red]❰.$fg[green]❱)%1G%} '
+  PROMPT='%T %n@%{$fg[$hostcolor]%}%m$(jobs_prompt)%-0>..>$(git_prompt_status)%>>
+$(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"
-  printf '%s' "%{${${KEYMAP/vicmd/$vicmd}/(main|viins)/$viins}%}"
+  local map=${KEYMAP:-viins}
+  printf '%s' "%{${${map/vicmd/$vicmd}/(main|viins)/$viins}%}"
 }
 
 function zle-line-init zle-line-finish zle-keymap-select {
@@ -18,8 +27,8 @@ function zle-line-init zle-line-finish zle-keymap-select {
   zle -R
 }
 
-zle -N zle-line-init
-zle -N zle-line-finish
+zle -N zle-line-init
+zle -N zle-line-finish
 zle -N zle-keymap-select
 
 # reset zle on resize
@@ -29,80 +38,96 @@ TRAPWINCH() {
 
 # Get the status of the working tree
 git_prompt_status() {
-  local branch ahead behind 
+  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 -b"
+  local status_cmd="git status --porcelain=v2 -b"
 
   # Get current status.
   while IFS=$'\n' read line; do
-    if [[ "$line" == \#\#\ * ]]; then
-      [[ "$line" =~ '## ([^.]*)\.\.\.(.*)' ]] && branch=$match[1]
-      [[ "$line" =~ 'ahead ([0-9]+)'  ]]      && ahead=$match[1]
-      [[ "$line" =~ 'behind ([0-9]+)'  ]]     && behind=$match[1]
+    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" == M[\ MTD]\ * ]]      && (( updated++ ))
-      [[ "$line" == [AC][\ MTD]\ * ]]   && (( added++ ))
-      [[ "$line" == D[\ MT]\ * ]]       && (( deleted++ ))
-      [[ "$line" == R[\ MTD]\ * ]]      && (( renamed++ ))
+      [[ "$line" == 1\ M[.MTD]\ * ]]      && (( updated++ ))
+      [[ "$line" == 1\ [AC][.MTD]\ * ]]   && (( added++ ))
+      [[ "$line" == 1\ D[.MT]\ * ]]       && (( deleted++ ))
+      [[ "$line" == 2\ R[.MTD]\ * ]]      && (( renamed++ ))
 
       # work tree
-      [[ "$line" == [\ MARCT]M\ * ]]    && (( modified++ ))
-      [[ "$line" == [\ MARCT]D\ * ]]    && (( deleted_wt++ ))
-      [[ "$line" == \?\?\ * ]]          && (( untracked++ ))
+      [[ "$line" == 1\ [.MARCT]A\ * ]]    && (( added++ , modified++ ))  # intend-to-add
+      [[ "$line" == 1\ [.MARCT]M\ * ]]    && (( modified++ ))
+      [[ "$line" == 1\ [.MARCT]D\ * ]]    && (( deleted_wt++ ))
+      [[ "$line" == \?\ * ]]              && (( untracked++ ))
 
-      # morge conflicts
-      [[ "$line" == (AA|DD|U?|?U)\ * ]] && (( unmerged++ ))
+      # 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=" %{$fg[yellow]%}"
+  local git_status=" "
 
-  # Format branch
-  if [[ -n $branch ]]; then
-    git_status+="$branch"
-  else
-    git_status+="$(git rev-parse --short HEAD 2> /dev/null)"
-    [[ $? -ne 0 ]] && return
-  fi
+  # Format branch and commit
+  git_status+="%{$fg_bold[green]%}$head"
+  git_status+="%{$fg_no_bold[yellow]%}(${oid[1,8]})"
 
   # Format upstream
-  local upstream_str
-  (( ahead  > 0 )) && upstream_str+="%{$fg[blue]%} >$ahead"
-  (( behind > 0 )) && upstream_str+="%{$fg[blue]%} <$behind"
-  git_status+="$upstream_str"
+  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)
-  if (( stashed > 0 )) then
-    stashed_str+="%{$fg_bold[cyan]%} ⋎$stashed%{$reset_color%}"
-  fi
-  git_status+="$stashed_str"
+  (( stashed > 0 )) && git_status+=" ⋎$stashed"
 
   # Format index
-  local index_str
-  (( updated > 0 )) && index_str+="%{$fg[green]%} *$updated"
-  (( added   > 0 )) && index_str+="%{$fg[green]%} +$added"
-  (( deleted > 0 )) && index_str+="%{$fg[green]%} -$deleted"
-  (( renamed > 0 )) && index_str+="%{$fg[green]%} ≈$renamed"
-  git_status+="$index_str"
+  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
-  local wt_str
-  (( modified   > 0 )) && wt_str+="%{$fg[red]%} *$modified"
-  (( deleted_wt > 0 )) && wt_str+="%{$fg[red]%} -$deleted_wt"
-  (( untracked  > 0 )) && wt_str+="%{$fg[red]%} +$untracked"
-  (( unmerged   > 0 )) && wt_str+="%{$fg[magenta]%} ♒$unmerged"
-  git_status+="$wt_str"
+  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