浏览代码

Merge pull request #306 from jtriley/git-prompt

add git-prompt plugin from olivierverdier/zsh-git-prompt
Robby Russell 10 年之前
父节点
当前提交
3d6f9d78c5
共有 2 个文件被更改,包括 128 次插入0 次删除
  1. 60 0
      plugins/git-prompt/git-prompt.plugin.zsh
  2. 68 0
      plugins/git-prompt/gitstatus.py

+ 60 - 0
plugins/git-prompt/git-prompt.plugin.zsh

@@ -0,0 +1,60 @@
+# ZSH Git Prompt Plugin from:
+# http://github.com/olivierverdier/zsh-git-prompt
+#
+export __GIT_PROMPT_DIR=$ZSH/plugins/git-prompt
+# Initialize colors.
+autoload -U colors
+colors
+
+# Allow for functions in the prompt.
+setopt PROMPT_SUBST
+
+## Enable auto-execution of functions.
+typeset -ga preexec_functions
+typeset -ga precmd_functions
+typeset -ga chpwd_functions
+
+# Append git functions needed for prompt.
+preexec_functions+='preexec_update_git_vars'
+precmd_functions+='precmd_update_git_vars'
+chpwd_functions+='chpwd_update_git_vars'
+
+## Function definitions
+function preexec_update_git_vars() {
+    case "$2" in
+        git*)
+        __EXECUTED_GIT_COMMAND=1
+        ;;
+    esac
+}
+
+function precmd_update_git_vars() {
+    if [ -n "$__EXECUTED_GIT_COMMAND" ]; then
+        update_current_git_vars
+        unset __EXECUTED_GIT_COMMAND
+    fi
+}
+
+function chpwd_update_git_vars() {
+    update_current_git_vars
+}
+
+function update_current_git_vars() {
+    unset __CURRENT_GIT_STATUS
+
+    local gitstatus="$__GIT_PROMPT_DIR/gitstatus.py"
+    _GIT_STATUS=`python ${gitstatus}`
+    __CURRENT_GIT_STATUS=("${(f)_GIT_STATUS}")
+}
+
+function prompt_git_info() {
+    if [ -n "$__CURRENT_GIT_STATUS" ]; then
+        echo "(%{${fg[red]}%}$__CURRENT_GIT_STATUS[1]%{${fg[default]}%}$__CURRENT_GIT_STATUS[2]%{${fg[magenta]}%}$__CURRENT_GIT_STATUS[3]%{${fg[default]}%})"
+    fi
+}
+
+# Set the prompt.
+#PROMPT='%B%m%~%b$(prompt_git_info) %# '
+# for a right prompt:
+#RPROMPT='%b$(prompt_git_info)'
+RPROMPT='$(prompt_git_info)'

+ 68 - 0
plugins/git-prompt/gitstatus.py

@@ -0,0 +1,68 @@
+#!/usr/bin/env python
+# -*- coding: UTF-8 -*-
+
+# change those symbols to whatever you prefer
+symbols = {'ahead of': '↑', 'behind': '↓', 'staged':'♦', 'changed':'‣', 'untracked':'…', 'clean':'⚡', 'unmerged':'≠', 'sha1':':'}
+
+from subprocess import Popen, PIPE
+
+output,error = Popen(['git','status'], stdout=PIPE, stderr=PIPE).communicate()
+
+if error:
+	import sys
+	sys.exit(0)
+lines = output.splitlines()
+
+import re
+behead_re = re.compile(r"^# Your branch is (ahead of|behind) '(.*)' by (\d+) commit")
+diverge_re = re.compile(r"^# and have (\d+) and (\d+) different")
+
+status = ''
+staged = re.compile(r'^# Changes to be committed:$', re.MULTILINE)
+changed = re.compile(r'^# Changed but not updated:$', re.MULTILINE)
+untracked = re.compile(r'^# Untracked files:$', re.MULTILINE)
+unmerged = re.compile(r'^# Unmerged paths:$', re.MULTILINE)
+
+def execute(*command):
+	out, err = Popen(stdout=PIPE, stderr=PIPE, *command).communicate()
+	if not err:
+		nb = len(out.splitlines())
+	else:
+		nb = '?'
+	return nb
+
+if staged.search(output):
+	nb = execute(['git','diff','--staged','--name-only','--diff-filter=ACDMRT'])
+	status += '%s%s' % (symbols['staged'], nb)
+if unmerged.search(output):
+	nb = execute(['git','diff', '--staged','--name-only', '--diff-filter=U'])
+	status += '%s%s' % (symbols['unmerged'], nb)
+if changed.search(output):
+	nb = execute(['git','diff','--name-only', '--diff-filter=ACDMRT'])
+	status += '%s%s' % (symbols['changed'], nb)
+if untracked.search(output):
+## 		nb = len(Popen(['git','ls-files','--others','--exclude-standard'],stdout=PIPE).communicate()[0].splitlines())
+## 		status += "%s" % (symbols['untracked']*(nb//3 + 1), )
+	status += symbols['untracked']
+if status == '':
+	status = symbols['clean']
+
+remote = ''
+
+bline = lines[0]
+if bline.find('Not currently on any branch') != -1:
+	branch = symbols['sha1']+ Popen(['git','rev-parse','--short','HEAD'], stdout=PIPE).communicate()[0][:-1]
+else:
+	branch = bline.split(' ')[3]
+	bstatusline = lines[1]
+	match = behead_re.match(bstatusline)
+	if match:
+		remote = symbols[match.groups()[0]]
+		remote += match.groups()[2]
+	elif lines[2:]:
+		div_match = diverge_re.match(lines[2])
+	 	if div_match:
+			remote = "{behind}{1}{ahead of}{0}".format(*div_match.groups(), **symbols)
+
+print '\n'.join([branch,remote,status])
+