diff --git a/my.zsh b/my.zsh index b6d369b..deec22b 100644 --- a/my.zsh +++ b/my.zsh @@ -48,6 +48,7 @@ done # Load aliases . $myzsh/aliases +. $myzsh/plugins/git-prompt-plugin/git-prompt-plugin.zsh # Load the theme and coloring autoload -U colors && colors diff --git a/plugins/git-prompt-plugin/git-prompt-plugin.zsh b/plugins/git-prompt-plugin/git-prompt-plugin.zsh new file mode 100644 index 0000000..8bdb19a --- /dev/null +++ b/plugins/git-prompt-plugin/git-prompt-plugin.zsh @@ -0,0 +1,90 @@ +__GIT_PROMPT_DIR="${0:A:h}" + +## Hook function definitions +function chpwd_update_git_vars() { + update_current_git_vars +} + +function preexec_update_git_vars() { + case "$2" in + git*|hub*|gh*|stg*) + __EXECUTED_GIT_COMMAND=1 + ;; + esac +} + +function precmd_update_git_vars() { + if [ -n "$__EXECUTED_GIT_COMMAND" ] || [ ! -n "$ZSH_THEME_GIT_PROMPT_CACHE" ]; then + update_current_git_vars + unset __EXECUTED_GIT_COMMAND + fi +} + +autoload -U add-zsh-hook +add-zsh-hook chpwd chpwd_update_git_vars +add-zsh-hook precmd precmd_update_git_vars +add-zsh-hook preexec preexec_update_git_vars + + +## Function definitions +function update_current_git_vars() { + unset __CURRENT_GIT_STATUS + + local gitstatus="$__GIT_PROMPT_DIR/gitstatus.py" + _GIT_STATUS=$(python ${gitstatus} 2>/dev/null) + __CURRENT_GIT_STATUS=("${(@s: :)_GIT_STATUS}") + GIT_BRANCH=$__CURRENT_GIT_STATUS[1] + GIT_AHEAD=$__CURRENT_GIT_STATUS[2] + GIT_BEHIND=$__CURRENT_GIT_STATUS[3] + GIT_STAGED=$__CURRENT_GIT_STATUS[4] + GIT_CONFLICTS=$__CURRENT_GIT_STATUS[5] + GIT_CHANGED=$__CURRENT_GIT_STATUS[6] + GIT_UNTRACKED=$__CURRENT_GIT_STATUS[7] +} + +git_super_status() { + precmd_update_git_vars + if [ -n "$__CURRENT_GIT_STATUS" ]; then + STATUS="$ZSH_THEME_GIT_PROMPT_PREFIX$ZSH_THEME_GIT_PROMPT_BRANCH$GIT_BRANCH%{${reset_color}%}" + if [ "$GIT_BEHIND" -ne "0" ]; then + STATUS="$STATUS$ZSH_THEME_GIT_PROMPT_BEHIND$GIT_BEHIND%{${reset_color}%}" + fi + if [ "$GIT_AHEAD" -ne "0" ]; then + STATUS="$STATUS$ZSH_THEME_GIT_PROMPT_AHEAD$GIT_AHEAD%{${reset_color}%}" + fi + STATUS="$STATUS$ZSH_THEME_GIT_PROMPT_SEPARATOR" + if [ "$GIT_STAGED" -ne "0" ]; then + STATUS="$STATUS$ZSH_THEME_GIT_PROMPT_STAGED$GIT_STAGED%{${reset_color}%}" + fi + if [ "$GIT_CONFLICTS" -ne "0" ]; then + STATUS="$STATUS$ZSH_THEME_GIT_PROMPT_CONFLICTS$GIT_CONFLICTS%{${reset_color}%}" + fi + if [ "$GIT_CHANGED" -ne "0" ]; then + STATUS="$STATUS$ZSH_THEME_GIT_PROMPT_CHANGED$GIT_CHANGED%{${reset_color}%}" + fi + if [ "$GIT_UNTRACKED" -ne "0" ]; then + STATUS="$STATUS$ZSH_THEME_GIT_PROMPT_UNTRACKED%{${reset_color}%}" + fi + if [ "$GIT_CHANGED" -eq "0" ] && [ "$GIT_CONFLICTS" -eq "0" ] && [ "$GIT_STAGED" -eq "0" ] && [ "$GIT_UNTRACKED" -eq "0" ]; then + STATUS="$STATUS$ZSH_THEME_GIT_PROMPT_CLEAN" + fi + STATUS="$STATUS%{${reset_color}%}$ZSH_THEME_GIT_PROMPT_SUFFIX" + echo "$STATUS" + fi +} + +# Default values for the appearance of the prompt. +ZSH_THEME_GIT_PROMPT_PREFIX="(" +ZSH_THEME_GIT_PROMPT_SUFFIX=")" +ZSH_THEME_GIT_PROMPT_SEPARATOR="|" +ZSH_THEME_GIT_PROMPT_BRANCH="%{$fg_bold[magenta]%}" +ZSH_THEME_GIT_PROMPT_STAGED="%{$fg[red]%}%{●%G%}" +ZSH_THEME_GIT_PROMPT_CONFLICTS="%{$fg[red]%}%{✖%G%}" +ZSH_THEME_GIT_PROMPT_CHANGED="%{$fg[blue]%}%{✚%G%}" +ZSH_THEME_GIT_PROMPT_BEHIND="%{↓%G%}" +ZSH_THEME_GIT_PROMPT_AHEAD="%{↑%G%}" +ZSH_THEME_GIT_PROMPT_UNTRACKED="%{…%G%}" +ZSH_THEME_GIT_PROMPT_CLEAN="%{$fg_bold[green]%}%{✔%G%}" + +# # Set the prompt. +# RPROMPT='$(git_super_status)' diff --git a/plugins/git-prompt-plugin/git-prompt-plugin.zsh.~1~ b/plugins/git-prompt-plugin/git-prompt-plugin.zsh.~1~ new file mode 100644 index 0000000..da674af --- /dev/null +++ b/plugins/git-prompt-plugin/git-prompt-plugin.zsh.~1~ @@ -0,0 +1,90 @@ +__GIT_PROMPT_DIR="${0:A:h}" + +## Hook function definitions +function chpwd_update_git_vars() { + update_current_git_vars +} + +function preexec_update_git_vars() { + case "$2" in + git*|hub*|gh*|stg*) + __EXECUTED_GIT_COMMAND=1 + ;; + esac +} + +function precmd_update_git_vars() { + if [ -n "$__EXECUTED_GIT_COMMAND" ] || [ ! -n "$ZSH_THEME_GIT_PROMPT_CACHE" ]; then + update_current_git_vars + unset __EXECUTED_GIT_COMMAND + fi +} + +autoload -U add-zsh-hook +add-zsh-hook chpwd chpwd_update_git_vars +add-zsh-hook precmd precmd_update_git_vars +add-zsh-hook preexec preexec_update_git_vars + + +## Function definitions +function update_current_git_vars() { + unset __CURRENT_GIT_STATUS + + local gitstatus="$__GIT_PROMPT_DIR/gitstatus.py" + _GIT_STATUS=$(python ${gitstatus} 2>/dev/null) + __CURRENT_GIT_STATUS=("${(@s: :)_GIT_STATUS}") + GIT_BRANCH=$__CURRENT_GIT_STATUS[1] + GIT_AHEAD=$__CURRENT_GIT_STATUS[2] + GIT_BEHIND=$__CURRENT_GIT_STATUS[3] + GIT_STAGED=$__CURRENT_GIT_STATUS[4] + GIT_CONFLICTS=$__CURRENT_GIT_STATUS[5] + GIT_CHANGED=$__CURRENT_GIT_STATUS[6] + GIT_UNTRACKED=$__CURRENT_GIT_STATUS[7] +} + +git_super_status() { + precmd_update_git_vars + if [ -n "$__CURRENT_GIT_STATUS" ]; then + STATUS="$ZSH_THEME_GIT_PROMPT_PREFIX$ZSH_THEME_GIT_PROMPT_BRANCH$GIT_BRANCH%{${reset_color}%}" + if [ "$GIT_BEHIND" -ne "0" ]; then + STATUS="$STATUS$ZSH_THEME_GIT_PROMPT_BEHIND$GIT_BEHIND%{${reset_color}%}" + fi + if [ "$GIT_AHEAD" -ne "0" ]; then + STATUS="$STATUS$ZSH_THEME_GIT_PROMPT_AHEAD$GIT_AHEAD%{${reset_color}%}" + fi + STATUS="$STATUS$ZSH_THEME_GIT_PROMPT_SEPARATOR" + if [ "$GIT_STAGED" -ne "0" ]; then + STATUS="$STATUS$ZSH_THEME_GIT_PROMPT_STAGED$GIT_STAGED%{${reset_color}%}" + fi + if [ "$GIT_CONFLICTS" -ne "0" ]; then + STATUS="$STATUS$ZSH_THEME_GIT_PROMPT_CONFLICTS$GIT_CONFLICTS%{${reset_color}%}" + fi + if [ "$GIT_CHANGED" -ne "0" ]; then + STATUS="$STATUS$ZSH_THEME_GIT_PROMPT_CHANGED$GIT_CHANGED%{${reset_color}%}" + fi + if [ "$GIT_UNTRACKED" -ne "0" ]; then + STATUS="$STATUS$ZSH_THEME_GIT_PROMPT_UNTRACKED%{${reset_color}%}" + fi + if [ "$GIT_CHANGED" -eq "0" ] && [ "$GIT_CONFLICTS" -eq "0" ] && [ "$GIT_STAGED" -eq "0" ] && [ "$GIT_UNTRACKED" -eq "0" ]; then + STATUS="$STATUS$ZSH_THEME_GIT_PROMPT_CLEAN" + fi + STATUS="$STATUS%{${reset_color}%}$ZSH_THEME_GIT_PROMPT_SUFFIX" + echo "$STATUS" + fi +} + +# Default values for the appearance of the prompt. +ZSH_THEME_GIT_PROMPT_PREFIX="(" +ZSH_THEME_GIT_PROMPT_SUFFIX=")" +ZSH_THEME_GIT_PROMPT_SEPARATOR="|" +ZSH_THEME_GIT_PROMPT_BRANCH="%{$fg_bold[magenta]%}" +ZSH_THEME_GIT_PROMPT_STAGED="%{$fg[red]%}%{●%G%}" +ZSH_THEME_GIT_PROMPT_CONFLICTS="%{$fg[red]%}%{✖%G%}" +ZSH_THEME_GIT_PROMPT_CHANGED="%{$fg[blue]%}%{✚%G%}" +ZSH_THEME_GIT_PROMPT_BEHIND="%{↓%G%}" +ZSH_THEME_GIT_PROMPT_AHEAD="%{↑%G%}" +ZSH_THEME_GIT_PROMPT_UNTRACKED="%{…%G%}" +ZSH_THEME_GIT_PROMPT_CLEAN="%{$fg_bold[green]%}%{✔%G%}" + +# Set the prompt. +RPROMPT='$(git_super_status)' diff --git a/plugins/git-prompt-plugin/gitstatus.py b/plugins/git-prompt-plugin/gitstatus.py new file mode 100644 index 0000000..d82cb9a --- /dev/null +++ b/plugins/git-prompt-plugin/gitstatus.py @@ -0,0 +1,97 @@ +#!/usr/bin/env python +from __future__ import print_function + +import os +import sys +import re +from subprocess import Popen, PIPE, check_output + + +def get_tagname_or_hash(): + """return tagname if exists else hash""" + # get hash + hash_cmd = ["git", "rev-parse", "--short", "HEAD"] + hash_ = check_output(hash_cmd).strip() + + # get tagname + tags_cmd = [ + "git", + "for-each-ref", + "--points-at=HEAD", + "--count=2", + "--sort=-version:refname", + "--format=%(refname:short)", + "refs/tags", + ] + tags = check_output(tags_cmd).split() + + if tags: + return tags[0] + ("+" if len(tags) > 1 else "") + elif hash_: + return hash_ + return None + + +# `git status --porcelain --branch` can collect all information +# branch, remote_branch, untracked, staged, changed, conflicts, ahead, behind +po = Popen( + ["git", "status", "--porcelain", "--branch"], + env=dict(os.environ, LANG="C"), + stdout=PIPE, + stderr=PIPE, +) +stdout, sterr = po.communicate() +if po.returncode != 0: + sys.exit(0) # Not a git repository + +# collect git status information +untracked, staged, changed, conflicts = [], [], [], [] +ahead, behind = 0, 0 +status = [(line[0], line[1], line[2:]) for line in stdout.decode("utf-8").splitlines()] +for st in status: + if st[0] == "#" and st[1] == "#": + if re.search("Initial commit on", st[2]) or re.search( + "No commits yet on", st[2] + ): + branch = st[2].split(" ")[-1] + elif re.search("no branch", st[2]): # detached status + branch = get_tagname_or_hash() + elif len(st[2].strip().split("...")) == 1: + branch = st[2].strip() + else: + # current and remote branch info + branch, rest = st[2].strip().split("...") + if len(rest.split(" ")) == 1: + # remote_branch = rest.split(' ')[0] + pass + else: + # ahead or behind + divergence = " ".join(rest.split(" ")[1:]) + divergence = divergence.lstrip("[").rstrip("]") + for div in divergence.split(", "): + if "ahead" in div: + ahead = int(div[len("ahead ") :].strip()) + elif "behind" in div: + behind = int(div[len("behind ") :].strip()) + elif st[0] == "?" and st[1] == "?": + untracked.append(st) + else: + if st[1] == "M": + changed.append(st) + if st[0] == "U": + conflicts.append(st) + elif st[0] != " ": + staged.append(st) + +out = " ".join( + [ + branch, + str(ahead), + str(behind), + str(len(staged)), + str(len(conflicts)), + str(len(changed)), + str(len(untracked)), + ] +) +print(out, end="") diff --git a/themes/damn-mac.zsh-theme b/themes/damn-mac.zsh-theme index 8c6c227..b8f9586 100644 --- a/themes/damn-mac.zsh-theme +++ b/themes/damn-mac.zsh-theme @@ -5,10 +5,11 @@ # # Created on: Apr 10, 2012 -function my_git_prompt_info() { +nfunction my_git_prompt_info() { ref=$(git symbolic-ref HEAD 2> /dev/null) || \ ref=$(git rev-parse --short HEAD 2> /dev/null) || return - echo "$ZSH_THEME_GIT_PROMPT_PREFIX %F{007}$(parse_git_dirty)%F{005}${ref#refs/heads/} %F{007}$ZSH_THEME_GIT_PROMPT_SUFFIX" + #echo "$ZSH_THEME_GIT_PROMPT_PREFIX %F{007}$(parse_git_dirty)%F{005}${ref#refs/heads/} %F{007}$ZSH_THEME_GIT_PROMPT_SUFFIX" + #echo "$(git_super_status)" } function get_pwd() { @@ -40,16 +41,14 @@ function spaces() { function user_prompt () { if [ $UID != 0 ]; then - echo "%F{007}$USER%F{002}> " + echo "%F{007}%F{002}> " else - echo "%F{001}$USER# " + echo "%F{001}# " fi } -PROMPT=' - %F{005}%~%F{008}$(spaces) $(my_git_prompt_info) - $(user_prompt)%f' +PROMPT='%F{005}%~%F{008} $(git_super_status)$(user_prompt)%f' # git settings ZSH_THEME_GIT_PROMPT_PREFIX="%F{002}[" diff --git a/themes/scott-estes.zsh b/themes/scott-estes.zsh new file mode 100644 index 0000000..b8f9586 --- /dev/null +++ b/themes/scott-estes.zsh @@ -0,0 +1,57 @@ +# damn-mac.zsh-theme +# +# Author: @lxsameer +# Repo: https://github.com/lxsameer/My.Zsh +# +# Created on: Apr 10, 2012 + +nfunction my_git_prompt_info() { + ref=$(git symbolic-ref HEAD 2> /dev/null) || \ + ref=$(git rev-parse --short HEAD 2> /dev/null) || return + #echo "$ZSH_THEME_GIT_PROMPT_PREFIX %F{007}$(parse_git_dirty)%F{005}${ref#refs/heads/} %F{007}$ZSH_THEME_GIT_PROMPT_SUFFIX" + #echo "$(git_super_status)" +} + +function get_pwd() { + echo "${PWD/$HOME/~}" +} +function spaces() { + local git=$(my_git_prompt_info) + + if [ ${#git} != 0 ]; then + local clean=$(parse_git_dirty) + if [ ${#clean} != 0 ]; then + (( git = ${#git} - 34 - ${#clean} + 1 )) + else + (( git = ${#git} - 34 )) + fi + else + git=0 + fi + + local termwidth + (( termwidth = ${COLUMNS} - 3 - ${#$(get_pwd)} - ${git} )) + + local spacing=" " + for i in {1..$termwidth}; do + spacing="${spacing}-" + done + echo $spacing +} + +function user_prompt () { + if [ $UID != 0 ]; then + echo "%F{007}%F{002}> " + else + echo "%F{001}# " + fi +} + + +PROMPT='%F{005}%~%F{008} $(git_super_status)$(user_prompt)%f' + +# git settings +ZSH_THEME_GIT_PROMPT_PREFIX="%F{002}[" +ZSH_THEME_GIT_PROMPT_CLEAN="" +ZSH_THEME_GIT_PROMPT_DIRTY="%F{003}*" +ZSH_THEME_GIT_PROMPT_SUFFIX="%F{002}]"