From ad8b9b96853c902bc716b491dfedf69756f93821 Mon Sep 17 00:00:00 2001 From: Clayton Parker Date: Wed, 6 Jun 2018 22:11:17 -0400 Subject: [PATCH] update git status zsh helper --- .zsh/git-prompt/gitstatus.py | 56 +++++++++++++++--------------- .zsh/git-prompt/gitstatus.sh | 67 ++++++++++++++++++++++-------------- 2 files changed, 69 insertions(+), 54 deletions(-) diff --git a/.zsh/git-prompt/gitstatus.py b/.zsh/git-prompt/gitstatus.py index 81ddf4e6..b6b33725 100755 --- a/.zsh/git-prompt/gitstatus.py +++ b/.zsh/git-prompt/gitstatus.py @@ -1,26 +1,32 @@ -#!/usr/bin/env python -# -*- coding: UTF-8 -*- +#!/usr/bin/env python3 + +# Taken from: +# https://github.com/olivierverdier/zsh-git-prompt from __future__ import print_function -# change those symbols to whatever you prefer -symbols = {'ahead of': '↑', 'behind': '↓', 'prehash':':'} +# change this symbol to whatever you prefer +prehash = ':' from subprocess import Popen, PIPE +import sys gitsym = Popen(['git', 'symbolic-ref', 'HEAD'], stdout=PIPE, stderr=PIPE) branch, error = gitsym.communicate() error_string = error.decode('utf-8') +error_string.lower() -if error_string.find('fatal: Not a git repository') != -1: - import sys +if 'fatal: not a git repository' in error_string: sys.exit(0) -branch = branch.strip()[11:] - +branch = branch.decode("utf-8").strip()[11:] -changed_files = [namestat[0] for namestat in Popen(['git','diff','--name-status'], stdout=PIPE).communicate()[0].splitlines()] +res, err = Popen(['git','diff','--name-status'], stdout=PIPE, stderr=PIPE).communicate() +err_string = err.decode('utf-8') +if 'fatal' in err_string: + sys.exit(0) +changed_files = [namestat[0] for namestat in res.decode("utf-8").splitlines()] staged_files = [namestat[0] for namestat in Popen(['git','diff', '--staged','--name-status'], stdout=PIPE).communicate()[0].splitlines()] nb_changed = len(changed_files) - changed_files.count('U') nb_U = staged_files.count('U') @@ -28,21 +34,17 @@ staged = str(nb_staged) conflicts = str(nb_U) changed = str(nb_changed) -nb_untracked = len(Popen(['git','ls-files','--others','--exclude-standard'],stdout=PIPE).communicate()[0].splitlines()) +nb_untracked = len([0 for status in Popen(['git','status','--porcelain',],stdout=PIPE).communicate()[0].decode("utf-8").splitlines() if status.startswith('??')]) untracked = str(nb_untracked) -if not nb_changed and not nb_staged and not nb_U and not nb_untracked: - clean = '1' -else: - clean = '0' -remote = '' +ahead, behind = 0,0 if not branch: # not on any branch - branch = symbols['prehash']+ Popen(['git','rev-parse','--short','HEAD'], stdout=PIPE).communicate()[0][:-1] + branch = prehash + Popen(['git','rev-parse','--short','HEAD'], stdout=PIPE).communicate()[0].decode("utf-8")[:-1] else: - remote_name = Popen(['git','config','branch.%s.remote' % branch], stdout=PIPE).communicate()[0].strip() + remote_name = Popen(['git','config','branch.%s.remote' % branch], stdout=PIPE).communicate()[0].decode("utf-8").strip() if remote_name: - merge_name = Popen(['git','config','branch.%s.merge' % branch], stdout=PIPE).communicate()[0].strip() + merge_name = Popen(['git','config','branch.%s.merge' % branch], stdout=PIPE).communicate()[0].decode("utf-8").strip() if remote_name == '.': # local remote_ref = merge_name else: @@ -51,21 +53,17 @@ revlist = revgit.communicate()[0] if revgit.poll(): # fallback to local revlist = Popen(['git', 'rev-list', '--left-right', '%s...HEAD' % merge_name],stdout=PIPE, stderr=PIPE).communicate()[0] - behead = revlist.splitlines() + behead = revlist.decode("utf-8").splitlines() ahead = len([x for x in behead if x[0]=='>']) behind = len(behead) - ahead - if behind: - remote += '%s%s' % (symbols['behind'], behind) - if ahead: - remote += '%s%s' % (symbols['ahead of'], ahead) -out = '\n'.join([ - str(branch), - remote, +out = ' '.join([ + branch, + str(ahead), + str(behind), staged, conflicts, changed, untracked, - clean]) -print(out) - + ]) +print(out, end='') diff --git a/.zsh/git-prompt/gitstatus.sh b/.zsh/git-prompt/gitstatus.sh index 10932646..e0a1c8e3 100755 --- a/.zsh/git-prompt/gitstatus.sh +++ b/.zsh/git-prompt/gitstatus.sh @@ -1,7 +1,15 @@ +# Taken from: +# https://github.com/olivierverdier/zsh-git-prompt + # To install source this file from your .zshrc file -# Change this to reflect your installation directory -export __GIT_PROMPT_DIR=~/.zsh/git-prompt +# see documentation at http://linux.die.net/man/1/zshexpn +# A: finds the absolute path, even if this is symlinked +# h: equivalent to dirname +export __GIT_PROMPT_DIR=${0:A:h} + +export GIT_PROMPT_EXECUTABLE=${GIT_PROMPT_EXECUTABLE:-"python"} + # Initialize colors. autoload -U colors colors @@ -18,14 +26,14 @@ add-zsh-hook precmd precmd_update_git_vars ## Function definitions function preexec_update_git_vars() { case "$2" in - git*) + git*|hub*|gh*|stg*) __EXECUTED_GIT_COMMAND=1 ;; esac } function precmd_update_git_vars() { - if [ -n "$__EXECUTED_GIT_COMMAND" ] || [ -n "$ZSH_THEME_GIT_PROMPT_NOCACHE" ]; then + if [ -n "$__EXECUTED_GIT_COMMAND" ] || [ ! -n "$ZSH_THEME_GIT_PROMPT_CACHE" ]; then update_current_git_vars unset __EXECUTED_GIT_COMMAND fi @@ -38,25 +46,33 @@ function chpwd_update_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}") + if [[ "$GIT_PROMPT_EXECUTABLE" == "python" ]]; then + local gitstatus="$__GIT_PROMPT_DIR/gitstatus.py" + _GIT_STATUS=`python ${gitstatus} 2>/dev/null` + fi + if [[ "$GIT_PROMPT_EXECUTABLE" == "haskell" ]]; then + _GIT_STATUS=`git status --porcelain --branch &> /dev/null | $__GIT_PROMPT_DIR/src/.bin/gitstatus` + fi + __CURRENT_GIT_STATUS=("${(@s: :)_GIT_STATUS}") GIT_BRANCH=$__CURRENT_GIT_STATUS[1] - GIT_REMOTE=$__CURRENT_GIT_STATUS[2] - GIT_STAGED=$__CURRENT_GIT_STATUS[3] - GIT_CONFLICTS=$__CURRENT_GIT_STATUS[4] - GIT_CHANGED=$__CURRENT_GIT_STATUS[5] - GIT_UNTRACKED=$__CURRENT_GIT_STATUS[6] - GIT_CLEAN=$__CURRENT_GIT_STATUS[7] + 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="($GIT_BRANCH" STATUS="$ZSH_THEME_GIT_PROMPT_PREFIX$ZSH_THEME_GIT_PROMPT_BRANCH$GIT_BRANCH%{${reset_color}%}" - if [ -n "$GIT_REMOTE" ]; then - STATUS="$STATUS$ZSH_THEME_GIT_PROMPT_REMOTE$GIT_REMOTE%{${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 @@ -69,9 +85,9 @@ git_super_status() { STATUS="$STATUS$ZSH_THEME_GIT_PROMPT_CHANGED$GIT_CHANGED%{${reset_color}%}" fi if [ "$GIT_UNTRACKED" -ne "0" ]; then - STATUS="$STATUS $GIT_UNTRACKED$ZSH_THEME_GIT_PROMPT_UNTRACKED%{${reset_color}%}" + STATUS="$STATUS$ZSH_THEME_GIT_PROMPT_UNTRACKED%{${reset_color}%}" fi - if [ "$GIT_CLEAN" -eq "1" ]; then + 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" @@ -82,13 +98,14 @@ git_super_status() { # Default values for the appearance of the prompt. Configure at will. ZSH_THEME_GIT_PROMPT_PREFIX="(" ZSH_THEME_GIT_PROMPT_SUFFIX=")" -ZSH_THEME_GIT_PROMPT_SEPARATOR=" |" +ZSH_THEME_GIT_PROMPT_SEPARATOR="|" ZSH_THEME_GIT_PROMPT_BRANCH="%{$fg_bold[magenta]%}" -ZSH_THEME_GIT_PROMPT_STAGED=" %{$fg[red]%}●" -ZSH_THEME_GIT_PROMPT_CONFLICTS=" %{$fg[red]%}x" -ZSH_THEME_GIT_PROMPT_CHANGED=" %{$fg[blue]%}+" -ZSH_THEME_GIT_PROMPT_REMOTE="" -ZSH_THEME_GIT_PROMPT_UNTRACKED="…" -ZSH_THEME_GIT_PROMPT_CLEAN=" %{$fg_bold[green]%}✔" +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%}"