From eca10c50450eefd506daec8cc1a326e06411e2e5 Mon Sep 17 00:00:00 2001 From: Gek Siong Low Date: Sun, 19 Apr 2020 20:28:35 +0800 Subject: [PATCH 1/3] Add support for zsh --- git-prompt-help.sh | 8 +++--- gitprompt.sh | 26 ++++++++++++-------- gitstatus.sh | 8 +++--- prompt-colors.sh | 54 ++++++++++++++++++++++++++++++++++------- themes/Default.bgptheme | 6 +++++ 5 files changed, 75 insertions(+), 27 deletions(-) diff --git a/git-prompt-help.sh b/git-prompt-help.sh index ffa3da57..efcda947 100755 --- a/git-prompt-help.sh +++ b/git-prompt-help.sh @@ -67,10 +67,10 @@ git_prompt_color_samples() { local x=0 while (( x < 8 )) ; do - showColor "${ColorNames[x]}" - showColor "Dim${ColorNames[x]}" - showColor "Bold${ColorNames[x]}" - showColor "Bright${ColorNames[x]}" + showColor "${ColorNames[@]:$x:1}" + showColor "Dim${ColorNames[@]:$x:1}" + showColor "Bold${ColorNames[@]:$x:1}" + showColor "Bright${ColorNames[@]:$x:1}" (( x++ )) done } diff --git a/gitprompt.sh b/gitprompt.sh index 8f3a45d7..c486a2c2 100755 --- a/gitprompt.sh +++ b/gitprompt.sh @@ -1,5 +1,8 @@ #!/usr/bin/env bash +# bash/zsh cross compatibility notes: +# - always use ${array[@]:offset:length} syntax for array indexing + function async_run() { { eval "$@" &> /dev/null @@ -484,6 +487,9 @@ function updatePrompt() { local PROMPT_END local EMPTY_PROMPT local Blue="\[\033[0;34m\]" + if [ -n $ZSH_VERSION ]; then + Blue='%{fg[blue]%}' + fi git_prompt_config @@ -502,30 +508,30 @@ function updatePrompt() { local -a git_status_fields while IFS=$'\n' read -r line; do git_status_fields+=("${line}"); done < <("${__GIT_STATUS_CMD}" 2>/dev/null) - export GIT_BRANCH=$(replaceSymbols "${git_status_fields[0]}") - local GIT_REMOTE="$(replaceSymbols "${git_status_fields[1]}")" + export GIT_BRANCH=$(replaceSymbols "${git_status_fields[@]:0:1}") + local GIT_REMOTE="$(replaceSymbols "${git_status_fields[@]:1:1}")" if [[ "." == "${GIT_REMOTE}" ]]; then unset GIT_REMOTE fi - local GIT_REMOTE_USERNAME_REPO="$(replaceSymbols "${git_status_fields[2]}")" + local GIT_REMOTE_USERNAME_REPO="$(replaceSymbols "${git_status_fields[@]:2:1}")" if [[ "." == "${GIT_REMOTE_USERNAME_REPO}" ]]; then unset GIT_REMOTE_USERNAME_REPO fi local GIT_FORMATTED_UPSTREAM - local GIT_UPSTREAM_PRIVATE="${git_status_fields[3]}" + local GIT_UPSTREAM_PRIVATE="${git_status_fields[@]:3:1}" if [[ "${__GIT_PROMPT_SHOW_UPSTREAM:-0}" != "1" || "^" == "${GIT_UPSTREAM_PRIVATE}" ]]; then unset GIT_FORMATTED_UPSTREAM else GIT_FORMATTED_UPSTREAM="${GIT_PROMPT_UPSTREAM//_UPSTREAM_/${GIT_UPSTREAM_PRIVATE}}" fi - local GIT_STAGED="${git_status_fields[4]}" - local GIT_CONFLICTS="${git_status_fields[5]}" - local GIT_CHANGED="${git_status_fields[6]}" - local GIT_UNTRACKED="${git_status_fields[7]}" - local GIT_STASHED="${git_status_fields[8]}" - local GIT_CLEAN="${git_status_fields[9]}" + local GIT_STAGED="${git_status_fields[@]:4:1}" + local GIT_CONFLICTS="${git_status_fields[@]:5:1}" + local GIT_CHANGED="${git_status_fields[@]:6:1}" + local GIT_UNTRACKED="${git_status_fields[@]:7:1}" + local GIT_STASHED="${git_status_fields[@]:8:1}" + local GIT_CLEAN="${git_status_fields[@]:9:1}" local NEW_PROMPT="${EMPTY_PROMPT}" diff --git a/gitstatus.sh b/gitstatus.sh index 7cbda63a..a349999b 100755 --- a/gitstatus.sh +++ b/gitstatus.sh @@ -132,18 +132,18 @@ if (( num_changed == 0 && num_staged == 0 && num_untracked == 0 && num_stashed = fi IFS="^" read -ra branch_fields <<< "${branch_line/\#\# }" -branch="${branch_fields[0]}" +branch="${branch_fields[@]:0:1}" remote="" upstream="" if [[ "${branch}" == *"Initial commit on"* ]]; then IFS=" " read -ra fields <<< "${branch}" - branch="${fields[3]}" + branch="${fields[@]:3:1}" remote="_NO_REMOTE_TRACKING_" remote_url='.' elif [[ "${branch}" == *"No commits yet on"* ]]; then IFS=" " read -ra fields <<< "${branch}" - branch="${fields[4]}" + branch="${fields[@]:4:1}" remote="_NO_REMOTE_TRACKING_" remote_url='.' elif [[ "${branch}" == *"no branch"* ]]; then @@ -159,7 +159,7 @@ else remote_url='.' else IFS="[,]" read -ra remote_fields <<< "${branch_fields[1]}" - upstream="${remote_fields[0]}" + upstream="${remote_fields[@]:0:1}" for remote_field in "${remote_fields[@]}"; do if [[ "${remote_field}" == "ahead "* ]]; then num_ahead="${remote_field:6}" diff --git a/prompt-colors.sh b/prompt-colors.sh index c8794a68..ac282255 100644 --- a/prompt-colors.sh +++ b/prompt-colors.sh @@ -4,6 +4,10 @@ # source this file to get color definitions # are also printed to STDERR. +# bash/zsh cross compatibility notes: +# - using colors modules to set colors in zsh, please autoload it +# - Dim colors, Intense Black not supported in zsh + define_color_names() { ColorNames=( Black Red Green Yellow Blue Magenta Cyan White ) @@ -34,13 +38,23 @@ define_color_names() { local attrname="${1}" local attrcode="${2}" while (( x < 8 )) ; do - local colorname="${ColorNames[x]}" - local fgcolorcode="${FgColors[x]}" - local bgcolorcode="${BgColors[x]}" + local colorname="${ColorNames[@]:$x:1}" + local fgcolorcode="${FgColors[@]:$x:1}" + local bgcolorcode="${BgColors[@]:$x:1}" longcolorname="${attrname}${colorname}" - _def_color "${longcolorname}" "${attrcode}" "${fgcolorcode}" - _def_color "${longcolorname}Fg" "${attrcode}" "${fgcolorcode}" - _def_color "${longcolorname}Bg" "${attrcode}" "${bgcolorcode}" + + if [ -n "$ZSH_VERSION" ]; then + # zsh + lowercolorname=$(echo $colorname | tr '[A-Z]' '[a-z]') + _def_color_zsh "${longcolorname}" "${attrcode}" "${lowercolorname}" "fg" + _def_color_zsh "${longcolorname}Fg" "${attrcode}" "${lowercolorname}" "fg" + _def_color_zsh "${longcolorname}Bg" "${attrcode}" "${lowercolorname}" "bg" + else + # bash + _def_color "${longcolorname}" "${attrcode}" "${fgcolorcode}" + _def_color "${longcolorname}Fg" "${attrcode}" "${fgcolorcode}" + _def_color "${longcolorname}Bg" "${attrcode}" "${bgcolorcode}" + fi (( x++ )) done } @@ -62,14 +76,36 @@ define_color_names() { eval "${def}" } + # def_color_zsh NAME ATTRCODE COLORNAME FG|BG + _def_color_zsh() { + if [ "${3}" = "0" ]; then + local def="${1}=\"%{\$reset_color%}\"" + else + case ${2} in + 1) # bold color + local def="${1}=\"%{\$${4}_bold[${3}]%}\"" + ;; + *) + local def="${1}=\"%{\$${4}[${3}]%}\"" + ;; + esac + fi + eval "${def}" + } + + _map_colors Bold ${AttrBright} _map_colors Bright ${AttrBright} _map_colors Dim ${AttrDim} _map_colors '' ${AttrNorm} - _def_color IntenseBlack 0 90 - _def_color ResetColor 0 0 - + if [ -n "$ZSH_VERSION" ]; then + _def_color_zsh IntenseBlack 0 90 + _def_color_zsh ResetColor 0 0 + else + _def_color IntenseBlack 0 90 + _def_color ResetColor 0 0 + fi } # do the color definitions only once diff --git a/themes/Default.bgptheme b/themes/Default.bgptheme index a43a5f17..c0c4d00a 100644 --- a/themes/Default.bgptheme +++ b/themes/Default.bgptheme @@ -31,6 +31,12 @@ unset_git_prompt_colors() { define_helpers() { Time12a="\$(date +%H:%M)" PathShort="\w"; + NewLine="\n" + + if [ -n "$ZSH_VERSION" ]; then + PathShort="%~" + NewLine=$'\n' + fi } define_undefined_git_prompt_colors() { From 13ee95539ba4d17c394bfd5d93af3cee8aea9b43 Mon Sep 17 00:00:00 2001 From: Gek Siong Low Date: Fri, 8 May 2020 18:19:43 +0800 Subject: [PATCH 2/3] Fix 'can't manipulate jobs in subshell' error in zsh --- gitprompt.sh | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/gitprompt.sh b/gitprompt.sh index c486a2c2..5ec64596 100755 --- a/gitprompt.sh +++ b/gitprompt.sh @@ -9,6 +9,13 @@ function async_run() { }& } +function async_run_zsh() { + { + eval "$@" &> /dev/null + }&! +} + + function git_prompt_dir() { # assume the gitstatus.sh is in the same directory as this script # code thanks to http://stackoverflow.com/questions/59895 @@ -441,8 +448,12 @@ function checkUpstream() { then if [[ -n $(git remote show) ]]; then ( - async_run "GIT_TERMINAL_PROMPT=0 git fetch --quiet" - disown -h + if [ -n $ZSH_VERSION ]; then + async_run_zsh "GIT_TERMINAL_PROMPT=0 git fetch --quiet" + else + async_run "GIT_TERMINAL_PROMPT=0 git fetch --quiet" + disown -h + fi ) fi fi From 75bc41fcce58d4f66caf373ebd56ac74efa1d4ab Mon Sep 17 00:00:00 2001 From: Mike Lewis Date: Mon, 18 May 2020 16:56:23 -0700 Subject: [PATCH 3/3] Correct issues with default theme on zsh - Use added `NewLine` variable for zsh-specific newline - `Time12a` variant added for zsh --- themes/Default.bgptheme | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/themes/Default.bgptheme b/themes/Default.bgptheme index c0c4d00a..e21ff51b 100644 --- a/themes/Default.bgptheme +++ b/themes/Default.bgptheme @@ -34,6 +34,7 @@ define_helpers() { NewLine="\n" if [ -n "$ZSH_VERSION" ]; then + Time12a="%T" PathShort="%~" NewLine=$'\n' fi @@ -87,8 +88,8 @@ define_undefined_git_prompt_colors() { # _LAST_COMMAND_INDICATOR_ will be replaced by the appropriate GIT_PROMPT_COMMAND_OK OR GIT_PROMPT_COMMAND_FAIL if [ -z "${GIT_PROMPT_START_USER+x}" ]; then GIT_PROMPT_START_USER="_LAST_COMMAND_INDICATOR_ ${Yellow}${PathShort}${ResetColor}"; fi if [ -z "${GIT_PROMPT_START_ROOT+x}" ]; then GIT_PROMPT_START_ROOT="${GIT_PROMPT_START_USER}"; fi - if [ -z "${GIT_PROMPT_END_USER+x}" ]; then GIT_PROMPT_END_USER=" \n${White}${Time12a}${ResetColor} $ "; fi - if [ -z "${GIT_PROMPT_END_ROOT+x}" ]; then GIT_PROMPT_END_ROOT=" \n${White}${Time12a}${ResetColor} # "; fi + if [ -z "${GIT_PROMPT_END_USER+x}" ]; then GIT_PROMPT_END_USER=" ${NewLine}${White}${Time12a}${ResetColor} $ "; fi + if [ -z "${GIT_PROMPT_END_ROOT+x}" ]; then GIT_PROMPT_END_ROOT=" ${NewLine}${White}${Time12a}${ResetColor} # "; fi # Please do not add colors to these symbols if [ -z ${GIT_PROMPT_SYMBOLS_AHEAD+x} ]; then GIT_PROMPT_SYMBOLS_AHEAD="↑·"; fi # The symbol for "n versions ahead of origin"