diff options
author | romkatv <roman.perepelitsa@gmail.com> | 2019-03-07 01:04:06 +0300 |
---|---|---|
committer | romkatv <roman.perepelitsa@gmail.com> | 2019-03-07 01:04:06 +0300 |
commit | 1858bbdd20623aa99a48bbe2693a930a95c5f7a6 (patch) | |
tree | ec7a102d656dc4ba5002829cd28e1f9fad627ac4 /powerlevel9k.zsh-theme | |
parent | 00bc22e194ec1f2f6fd00f76218af182c600c505 (diff) |
wip
Diffstat (limited to 'powerlevel9k.zsh-theme')
-rwxr-xr-x | powerlevel9k.zsh-theme | 433 |
1 files changed, 268 insertions, 165 deletions
diff --git a/powerlevel9k.zsh-theme b/powerlevel9k.zsh-theme index 341985f3..907ef8b5 100755 --- a/powerlevel9k.zsh-theme +++ b/powerlevel9k.zsh-theme @@ -65,6 +65,10 @@ source "${p9k_directory}/functions/colors.zsh" source "${p9k_directory}/functions/vcs.zsh" +if [[ $POWERLEVEL9K_DISABLE_GITSTATUS != true ]]; then + source ${POWERLEVEL9K_GITSTATUS_DIR:-${p9k_directory}/gitstatus}/gitstatus.plugin.zsh +fi + # cleanup temporary variables. unset p9k_directory @@ -95,23 +99,12 @@ fi # this naming convention. ################################################################ -# The `CURRENT_BG` variable is used to remember what the last BG color used was -# when building a prompt segment. -CURRENT_BG=NONE -LAST_SEGMENT_INDEX=0 - # Specifies the maximum number of elements in the cache. When the cache grows over this limit, # it gets cleared. This is meant to avoid memory leaks when a rogue prompt is filling the cache # with data. set_default POWERLEVEL9K_MAX_CACHE_SIZE 10000 -# Functions producing left and right prompts are called from subshells, so any -# changes to the environment variables they do get wiped out after the prompt is -# printed. In order to cache the results of expensive computations in these functions, -# we use a temporary file to communicate with the parent shell and to ask it to -# change environment variables. -typeset -gAH _p9k_cache_data=() -typeset -gH _P9K_CACHE_CHANNEL=$(mktemp -u "${TMPDIR:-/tmp}"/p9k_cache_channel.$$.XXXXXXXXXX) +typeset -gAH _P9K_CACHE=() # Note: Several performance-critical functions return results to the caller via global # variable _P9K_RETVAL rather than stdout. This is faster. @@ -126,7 +119,7 @@ typeset -gH _P9K_CACHE_CHANNEL=$(mktemp -u "${TMPDIR:-/tmp}"/p9k_cache_channel.$ _p9k_cache_set() { # Uncomment to see cache misses. # echo "cache: ${(qq)1} => ${(qq)2}" >&2 - echo -E "_p9k_cache_data+=(${(qq)1} ${(qq)2})" >>! $_P9K_CACHE_CHANNEL + _P9K_CACHE[$1]=$2 _P9K_RETVAL=$2 } @@ -137,14 +130,14 @@ _p9k_cache_set() { # If there is value associated with the specified key, sets _P9K_RETVAL and returns 0. # Otherwise returns 1. _p9k_cache_get() { - _P9K_RETVAL=${_p9k_cache_data[$1]-__p9k_empty__} + _P9K_RETVAL=${_P9K_CACHE[$1]-__p9k_empty__} [[ $_P9K_RETVAL != __p9k_empty__ ]] } # Sets _P9K_RETVAL to icon whose name is supplied via $1. _p9k_get_icon() { local var_name=POWERLEVEL9K_$1 - _P9K_RETVAL=${${(P)var_name}-$icons[$1]} + _P9K_RETVAL=${(g::)${${(P)var_name}-$icons[$1]}} } typeset -gaH _p9k_left_join=(1) @@ -168,8 +161,8 @@ for ((i = 2; i <= $#POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS; ++i)); do done unset elem -_p9k_should_join_left() [[ $LAST_SEGMENT_INDEX -ge ${_p9k_left_join[$1]:-$1} ]] -_p9k_should_join_right() [[ $LAST_SEGMENT_INDEX -ge ${_p9k_right_join[$1]:-$1} ]] +_p9k_should_join_left() [[ $_P9K_LAST_SEGMENT_INDEX -ge ${_p9k_left_join[$1]:-$1} ]] +_p9k_should_join_right() [[ $_P9K_LAST_SEGMENT_INDEX -ge ${_p9k_right_join[$1]:-$1} ]] # Resolves a color to its numerical value, or an empty string. Communicates the result back # by setting _P9K_RETVAL. @@ -206,7 +199,7 @@ _p9k_foreground() { set_default POWERLEVEL9K_WHITESPACE_BETWEEN_LEFT_SEGMENTS " " left_prompt_segment() { _p9k_should_join_left $2 && local join=true || local join=false - local cache_key="${(q)0} ${(q)1} ${(q)3} ${(q)4} ${(q)5:+1} ${(q)6} ${(q)CURRENT_BG} $join" + local cache_key="${(q)0} ${(q)1} ${(q)3} ${(q)4} ${(q)5:+1} ${(q)6} ${(q)_P9K_CURRENT_BG} $join" if ! _p9k_cache_get $cache_key; then _p9k_color $3 $1 BACKGROUND local background_color=$_P9K_RETVAL @@ -219,11 +212,11 @@ left_prompt_segment() { _p9k_background $background_color local output=$_P9K_RETVAL - if [[ $CURRENT_BG == NONE ]]; then + if [[ $_P9K_CURRENT_BG == NONE ]]; then # The first segment on the line. output+=$POWERLEVEL9K_WHITESPACE_BETWEEN_LEFT_SEGMENTS elif [[ $join == false ]]; then - if [[ $background_color == $CURRENT_BG ]]; then + if [[ $background_color == $_P9K_CURRENT_BG ]]; then # Middle segment with same color as previous segment # We take the current foreground color as color for our # subsegment (or the default color). This should have @@ -237,7 +230,7 @@ left_prompt_segment() { _p9k_get_icon LEFT_SUBSEGMENT_SEPARATOR output+="${_P9K_RETVAL}${POWERLEVEL9K_WHITESPACE_BETWEEN_LEFT_SEGMENTS}" else - _p9k_foreground $CURRENT_BG + _p9k_foreground $_P9K_CURRENT_BG output+=$_P9K_RETVAL _p9k_get_icon LEFT_SEGMENT_SEPARATOR output+="${_P9K_RETVAL}${POWERLEVEL9K_WHITESPACE_BETWEEN_LEFT_SEGMENTS}" @@ -261,27 +254,27 @@ left_prompt_segment() { fi local tuple=("${(@Q)${(z)_P9K_RETVAL}}") - echo -n "${tuple[1]}${5}${POWERLEVEL9K_WHITESPACE_BETWEEN_LEFT_SEGMENTS}" - LAST_SEGMENT_INDEX=$2 - CURRENT_BG=$tuple[2] + _P9K_PROMPT+="${tuple[1]}${5}${POWERLEVEL9K_WHITESPACE_BETWEEN_LEFT_SEGMENTS}" + _P9K_LAST_SEGMENT_INDEX=$2 + _P9K_CURRENT_BG=$tuple[2] } # End the left prompt, closes the final segment. left_prompt_end() { - local cache_key="$0 ${(q)CURRENT_BG}" + local cache_key="$0 ${(q)_P9K_CURRENT_BG}" if ! _p9k_cache_get $cache_key; then local output="%k" - if [[ $CURRENT_BG != NONE ]]; then - _p9k_foreground $CURRENT_BG + if [[ $_P9K_CURRENT_BG != NONE ]]; then + _p9k_foreground $_P9K_CURRENT_BG output+=$_P9K_RETVAL _p9k_get_icon LEFT_SEGMENT_SEPARATOR output+="${_P9K_RETVAL}" fi _p9k_get_icon LEFT_SEGMENT_END_SEPARATOR - output+="%f${_P9K_RETVAL}" + output+="%f${_P9K_RETVAL}" _p9k_cache_set $cache_key $output fi - echo -n $_P9K_RETVAL + _P9K_PROMPT+=$_P9K_RETVAL } # Begin a right prompt segment @@ -297,7 +290,7 @@ left_prompt_end() { set_default POWERLEVEL9K_WHITESPACE_BETWEEN_RIGHT_SEGMENTS " " right_prompt_segment() { _p9k_should_join_right $2 && local join=true || local join=false - local cache_key="${(q)0} ${(q)1} ${(q)3} ${(q)4} ${(q)6} ${(q)CURRENT_BG} $join" + local cache_key="${(q)0} ${(q)1} ${(q)3} ${(q)4} ${(q)6} ${(q)_P9K_CURRENT_BG} $join" if ! _p9k_cache_get $cache_key; then _p9k_color $3 $1 BACKGROUND @@ -312,8 +305,8 @@ right_prompt_segment() { local output='' - if [[ $CURRENT_BG == NONE || $join == false ]]; then - if [[ $background_color == $CURRENT_BG ]]; then + if [[ $_P9K_CURRENT_BG == NONE || $join == false ]]; then + if [[ $background_color == $_P9K_CURRENT_BG ]]; then # Middle segment with same color as previous segment # We take the current foreground color as color for our # subsegment (or the default color). This should have @@ -356,10 +349,10 @@ right_prompt_segment() { fi local tuple=("${(@Q)${(z)_P9K_RETVAL}}") - echo -n "${tuple[1]}${5}${5:+ }${tuple[3]}" + _P9K_PROMPT+="${tuple[1]}${5}${5:+ }${tuple[3]}" - CURRENT_BG=$tuple[2] - LAST_SEGMENT_INDEX=$2 + _P9K_CURRENT_BG=$tuple[2] + _P9K_LAST_SEGMENT_INDEX=$2 } ################################################################ @@ -431,7 +424,7 @@ prompt_newline() { "$0" \ "$2" \ "" "" "${newline}" - CURRENT_BG=NONE + _P9K_CURRENT_BG=NONE POWERLEVEL9K_WHITESPACE_BETWEEN_LEFT_SEGMENTS=$lws } @@ -1011,25 +1004,21 @@ prompt_dir() { # save state of path for highlighting and bold options local path_opt=$current_path - - typeset -AH dir_states - dir_states=( - "DEFAULT" "FOLDER_ICON" - "HOME" "HOME_ICON" - "HOME_SUBFOLDER" "HOME_SUB_ICON" - "NOT_WRITABLE" "LOCK_ICON" - "ETC" "ETC_ICON" - ) local state_path="$(print -P '%~')" local current_state="DEFAULT" + local icon="FOLDER_ICON" if [[ $state_path == '/etc'* ]]; then current_state='ETC' + icon='ETC_ICON' elif [[ "${POWERLEVEL9K_DIR_SHOW_WRITABLE}" == true && ! -w "$PWD" ]]; then current_state="NOT_WRITABLE" + icon='LOCK_ICON' elif [[ $state_path == '~' ]]; then current_state="HOME" + icon='HOME_ICON' elif [[ $state_path == '~'* ]]; then current_state="HOME_SUBFOLDER" + icon='HOME_SUB_ICON' fi # declare variables used for bold and state colors @@ -1101,7 +1090,7 @@ prompt_dir() { current_path=${current_path:s/~/$POWERLEVEL9K_HOME_FOLDER_ABBREVIATION} fi - _p9k_cache_set $cache_key "$0_$current_state ${(qq)2} blue ${(qq)DEFAULT_COLOR} ${(qq)current_path} ${(qq)dir_states[$current_state]}" + _p9k_cache_set $cache_key "$0_$current_state ${(qq)2} blue ${(qq)DEFAULT_COLOR} ${(qq)current_path} ${(qq)icon}" fi "$1_prompt_segment" "${(@Q)${(z)_P9K_RETVAL}}" @@ -1441,14 +1430,10 @@ set_default POWERLEVEL9K_STATUS_OK_IN_NON_VERBOSE false exit_code_or_status() { local ec=$1 - if [[ "$POWERLEVEL9K_STATUS_HIDE_SIGNAME" = true ]]; then - echo "$ec" - elif (( ec <= 128 )); then - echo "$ec" + if [[ "$POWERLEVEL9K_STATUS_HIDE_SIGNAME" = true ]] || (( ec <= 128 )); then + _P9K_RETVAL=$ec else - local sig=$(( ec - 128 )) - local idx=$(( sig + 1 )) - echo "SIG${signals[$idx]}(${sig})" + _P9K_RETVAL="SIG${signals[$((sig + 1))]}($((ec - 128)))" fi } @@ -1461,22 +1446,25 @@ prompt_status() { if [[ $POWERLEVEL9K_STATUS_SHOW_PIPESTATUS == true ]]; then if (( $#RETVALS > 1 )); then - ec_text=$(exit_code_or_status "${RETVALS[1]}") ec_sum=${RETVALS[1]} + exit_code_or_status "${RETVALS[1]}" + else - ec_text=$(exit_code_or_status "${RETVAL}") ec_sum=${RETVAL} + exit_code_or_status "${RETVAL}" fi - + ec_text=$_P9K_RETVAL for ec in "${(@)RETVALS[2,-1]}"; do - ec_text="${ec_text}|$(exit_code_or_status "$ec")" - ec_sum=$(( $ec_sum + $ec )) + (( ec_sum += ec )) + exit_code_or_status "$ec" + ec_text+="|$_P9K_RETVAL" done else + ec_sum=${RETVAL} # We use RETVAL instead of the right-most RETVALS item because # PIPE_FAIL may be set. - ec_text=$(exit_code_or_status "${RETVAL}") - ec_sum=${RETVAL} + exit_code_or_status "${RETVAL}" + ec_text=$_P9K_RETVAL fi if (( ec_sum > 0 )); then @@ -1566,8 +1554,8 @@ build_test_stats() { # System time prompt_time() { set_default POWERLEVEL9K_TIME_FORMAT "%D{%H:%M:%S}" - - "$1_prompt_segment" "$0" "$2" "$DEFAULT_COLOR_INVERTED" "$DEFAULT_COLOR" "$POWERLEVEL9K_TIME_FORMAT" "TIME_ICON" + [[ -v _P9K_REFRESH_PROMPT ]] || typeset -gH _P9K_TIME=${(%)POWERLEVEL9K_TIME_FORMAT} + "$1_prompt_segment" "$0" "$2" "$DEFAULT_COLOR_INVERTED" "$DEFAULT_COLOR" "$_P9K_TIME" "TIME_ICON" } ################################################################ @@ -1595,6 +1583,7 @@ prompt_todo() { set_default POWERLEVEL9K_VCS_ACTIONFORMAT_FOREGROUND "red" # Default: Just display the first 8 characters of our changeset-ID. set_default POWERLEVEL9K_VCS_INTERNAL_HASH_LENGTH "8" + powerlevel9k_vcs_init() { if [[ -n "$POWERLEVEL9K_CHANGESET_HASH_LENGTH" ]]; then POWERLEVEL9K_VCS_INTERNAL_HASH_LENGTH="$POWERLEVEL9K_CHANGESET_HASH_LENGTH" @@ -1612,6 +1601,7 @@ powerlevel9k_vcs_init() { 'clean' 'green' 'modified' 'yellow' 'untracked' 'green' + 'loading' 'grey' ) VCS_CHANGESET_PREFIX='' @@ -1619,7 +1609,6 @@ powerlevel9k_vcs_init() { VCS_CHANGESET_PREFIX="$(print_icon 'VCS_COMMIT_ICON')%0.$POWERLEVEL9K_VCS_INTERNAL_HASH_LENGTH""i " fi - zstyle ':vcs_info:*' enable git hg svn zstyle ':vcs_info:*' check-for-changes true VCS_DEFAULT_FORMAT="$VCS_CHANGESET_PREFIX%b%c%u%m" @@ -1655,22 +1644,182 @@ powerlevel9k_vcs_init() { fi } +# git workdir => the last prompt we've shown for it +typeset -gAH _P9K_LAST_GIT_PROMPT + +# git workdir => 1 if gitstatus is slow on it, 0 if it's fast. +typeset -gAH _P9K_GIT_SLOW + +typeset -fH _p9k_vcs_render() { + if [[ -v _P9K_NEXT_VCS_DIR ]]; then + local prompt + local dir=$PWD + while true; do + prompt=${_P9K_LAST_GIT_PROMPT[$dir]} + [[ -n $prompt || $dir == / ]] && break + dir=${dir:h} + done + $2_prompt_segment $1_LOADING $3 "${vcs_states[loading]}" "$DEFAULT_COLOR" ${prompt:-loading} + return 0 + fi + + [[ $VCS_STATUS_RESULT == ok-* ]] || return 1 + local cache_key="$0 + ${(q)VCS_STATUS_LOCAL_BRANCH} + ${(q)VCS_STATUS_REMOTE_BRANCH} + ${(q)VCS_STATUS_REMOTE_URL} + ${(q)VCS_STATUS_ACTION} + ${(q)VCS_STATUS_HAS_STAGED} + ${(q)VCS_STATUS_HAS_UNSTAGED} + ${(q)VCS_STATUS_HAS_UNTRACKED} + ${(q)VCS_STATUS_COMMITS_AHEAD} + ${(q)VCS_STATUS_COMMITS_BEHIND} + ${(q)VCS_STATUS_STASHES}" + if ! _p9k_cache_get $cache_key; then + local state + if [[ $VCS_STATUS_HAS_STAGED != 0 || $VCS_STATUS_HAS_UNSTAGED != 0 ]]; then + state='modified' + elif [[ $VCS_STATUS_HAS_UNTRACKED != 0 ]]; then + state='untracked' + else + state='clean' + fi + + local vcs_prompt + if [[ "$VCS_STATUS_REMOTE_URL" == *github* ]] then + _p9k_get_icon VCS_GIT_GITHUB_ICON + vcs_prompt+=$_P9K_RETVAL + elif [[ "$VCS_STATUS_REMOTE_URL" == *bitbucket* ]] then + _p9k_get_icon VCS_GIT_BITBUCKET_ICON + vcs_prompt+=$_P9K_RETVAL + elif [[ "$VCS_STATUS_REMOTE_URL" == *stash* ]] then + _p9k_get_icon VCS_GIT_GITHUB_ICON + vcs_prompt+=$_P9K_RETVAL + elif [[ "$VCS_STATUS_REMOTE_URL" == *gitlab* ]] then + _p9k_get_icon VCS_GIT_GITLAB_ICON + vcs_prompt+=$_P9K_RETVAL + else + _p9k_get_icon VCS_GIT_ICON + vcs_prompt+=$_P9K_RETVAL + fi + + _p9k_get_icon VCS_BRANCH_ICON + vcs_prompt+="$_P9K_RETVAL$VCS_STATUS_LOCAL_BRANCH" + if [[ -n $VCS_STATUS_ACTION ]]; then + vcs_prompt+=" %F{${POWERLEVEL9K_VCS_ACTIONFORMAT_FOREGROUND}}| $VCS_STATUS_ACTION%f" + else + if [[ -n $VCS_STATUS_REMOTE_BRANCH && + $VCS_STATUS_LOCAL_BRANCH != $VCS_STATUS_REMOTE_BRANCH ]]; then + _p9k_get_icon VCS_REMOTE_BRANCH_ICON + vcs_prompt+=" $_P9K_RETVAL$VCS_STATUS_REMOTE_BRANCH" + fi + if [[ $VCS_STATUS_HAS_STAGED == 1 ]]; then + _p9k_get_icon VCS_STAGED_ICON + vcs_prompt+=" $_P9K_RETVAL" + fi + if [[ $VCS_STATUS_HAS_UNSTAGED == 1 ]]; then + _p9k_get_icon VCS_UNSTAGED_ICON + vcs_prompt+=" $_P9K_RETVAL" + fi + if [[ $VCS_STATUS_HAS_UNTRACKED == 1 ]]; then + _p9k_get_icon VCS_UNTRACKED_ICON + vcs_prompt+=" $_P9K_RETVAL" + fi + if [[ $VCS_STATUS_COMMITS_AHEAD -gt 0 ]]; then + _p9k_get_icon VCS_OUTGOING_CHANGES_ICON + vcs_prompt+=" $_P9K_RETVAL$VCS_STATUS_COMMITS_AHEAD" + fi + if [[ $VCS_STATUS_COMMITS_BEHIND -gt 0 ]]; then + _p9k_get_icon VCS_INCOMING_CHANGES_ICON + vcs_prompt+=" $_P9K_RETVAL$VCS_STATUS_COMMITS_BEHIND" + fi + if [[ $VCS_STATUS_STASHES -gt 0 ]]; then + _p9k_get_icon VCS_STASH_ICON + vcs_prompt+=" $_P9K_RETVAL$VCS_STATUS_STASHES" + fi + fi + + _p9k_cache_set $cache_key "${1}_${(U)state} ${(qq)vcs_states[$state]} ${(qq)vcs_prompt}" + fi + + local tuple=("${(@Q)${(z)_P9K_RETVAL}}") + _P9K_LAST_GIT_PROMPT[$VCS_STATUS_WORKDIR]="${tuple[3]}" + "$2_prompt_segment" "${tuple[1]}" $3 "${tuple[2]}" "$DEFAULT_COLOR" "${tuple[3]}" + return 0 +} + +typeset -fH _p9k_vcs_resume() { + if [[ $VCS_STATUS_RESULT == ok-async ]]; then + local slow=$((EPOCHREALTIME - _P9K_GITSTATUS_START_TIME > POWERLEVEL9K_VCS_MAX_SYNC_LATENCY_SECONDS)) + _P9K_GIT_SLOW[$VCS_STATUS_WORKDIR]=$slow + fi + + if [[ -z $_P9K_NEXT_VCS_DIR ]]; then + unset _P9K_NEXT_VCS_DIR + _p9k_reset_prompts + else + typeset -gFH _P9K_GITSTATUS_START_TIME=$EPOCHREALTIME + if ! gitstatus_query -d $_P9K_NEXT_VCS_DIR -t 0 -c _p9k_vcs_resume POWERLEVEL9K; then + unset _P9K_NEXT_VCS_DIR + return + fi + case $VCS_STATUS_RESULT in + *-sync) + unset _P9K_NEXT_VCS_DIR + _p9k_reset_prompts + ;; + tout) + typeset -gH _P9K_NEXT_VCS_DIR="" + ;; + esac + fi +} + +typeset -fH _p9k_vcs_gitstatus() { + [[ $POWERLEVEL9K_DISABLE_GITSTATUS == true ]] && return 1 + if [[ ! -v _P9K_REFRESH_PROMPT ]]; then + if [[ -v _P9K_NEXT_VCS_DIR ]]; then + typeset -gH _P9K_NEXT_VCS_DIR=$PWD + else + local dir=$PWD + local -F timeout=$POWERLEVEL9K_VCS_MAX_SYNC_LATENCY_SECONDS + while true; do + case "$_P9K_GIT_SLOW[$dir]" in + "") [[ $dir == / ]] && break; dir=${dir:h};; + 0) break;; + 1) timeout=0; break;; + esac + done + typeset -gFH _P9K_GITSTATUS_START_TIME=$EPOCHREALTIME + gitstatus_query -t $timeout -c _p9k_vcs_resume POWERLEVEL9K || return 1 + [[ $VCS_STATUS_RESULT == tout ]] && typeset -gH _P9K_NEXT_VCS_DIR="" + fi + fi + return 0 +} + ################################################################ # Segment to show VCS information + +# If it takes longer than this to fetch git repo status, display the prompt with a greyed out +# vcs segment and fix it asynchronously when the results come it. +[ -v POWERLEVEL9K_VCS_MAX_SYNC_LATENCY_SECONDS ] || typeset -gF POWERLEVEL9K_VCS_MAX_SYNC_LATENCY_SECONDS=0.05 + prompt_vcs() { - # If POWERLEVEL9K_VCS_STATUS_COMMAND isn't empty, it should be a command that provides vcs info - # in the format of gitstatus. See https://github.com/romkatv/gitstatus. If you enable gitstatus, - # it'll define POWERLEVEL9K_VCS_STATUS_COMMAND for you. To disable, you can explicitly set - # POWERLEVEL9K_VCS_STATUS_COMMAND="". - if [[ -z $POWERLEVEL9K_VCS_STATUS_COMMAND ]]; then + local -a backends + [[ -v POWERLEVEL9K_VCS_BACKENDS ]] && backends=($POWERLEVEL9K_VCS_BACKENDS) || backends=(git) + if (( ${backends[(I)git]} )) && _p9k_vcs_gitstatus; then + _p9k_vcs_render $0 $1 $2 && return + backends=(${backends:#git}) + fi + if (( #backends )); then VCS_WORKDIR_DIRTY=false VCS_WORKDIR_HALF_DIRTY=false local current_state="" - # Actually invoke vcs_info manually to gather all information. + zstyle ':vcs_info:*' enable ${backends} vcs_info local vcs_prompt="${vcs_info_msg_0_}" - if [[ -n "$vcs_prompt" ]]; then if [[ "$VCS_WORKDIR_DIRTY" == true ]]; then # $vcs_visual_identifier gets set in +vi-vcs-detect-changes in functions/vcs.zsh, @@ -1685,71 +1834,6 @@ prompt_vcs() { fi "$1_prompt_segment" "${0}_${(U)current_state}" "$2" "${vcs_states[$current_state]}" "$DEFAULT_COLOR" "$vcs_prompt" "$vcs_visual_identifier" fi - else - "${(@Q)${(z)POWERLEVEL9K_VCS_STATUS_COMMAND}}" || return - local cache_key="$0 ${(@q)VCS_STATUS_ALL}" - if ! _p9k_cache_get $cache_key; then - local current_state - if [[ $VCS_STATUS_HAS_STAGED != 0 || $VCS_STATUS_HAS_UNSTAGED != 0 ]]; then - current_state='modified' - elif [[ $VCS_STATUS_HAS_UNTRACKED != 0 ]]; then - current_state='untracked' - else - current_state='clean' - fi - - local vcs_prompt - if [[ "$VCS_STATUS_REMOTE_URL" =~ "github" ]] then - _p9k_get_icon VCS_GIT_GITHUB_ICON - vcs_prompt+=$_P9K_RETVAL - elif [[ "$VCS_STATUS_REMOTE_URL" =~ "bitbucket" ]] then - _p9k_get_icon VCS_GIT_BITBUCKET_ICON - vcs_prompt+=$_P9K_RETVAL - elif [[ "$VCS_STATUS_REMOTE_URL" =~ "stash" ]] then - _p9k_get_icon VCS_GIT_GITHUB_ICON - vcs_prompt+=$_P9K_RETVAL - elif [[ "$VCS_STATUS_REMOTE_URL" =~ "gitlab" ]] then - _p9k_get_icon VCS_GIT_GITLAB_ICON - vcs_prompt+=$_P9K_RETVAL - else - _p9k_get_icon VCS_GIT_ICON - vcs_prompt+=$_P9K_RETVAL - fi - - _p9k_get_icon VCS_BRANCH_ICON - vcs_prompt+="$_P9K_RETVAL$VCS_STATUS_LOCAL_BRANCH" - if [[ -n $VCS_STATUS_ACTION ]]; then - vcs_prompt+=" %F{${POWERLEVEL9K_VCS_ACTIONFORMAT_FOREGROUND}}| $VCS_STATUS_ACTION%f" - else - if [[ -n $VCS_STATUS_REMOTE_BRANCH && - $VCS_STATUS_LOCAL_BRANCH != $VCS_STATUS_REMOTE_BRANCH ]]; then - _p9k_get_icon VCS_REMOTE_BRANCH_ICON - vcs_prompt+=" $_P9K_RETVAL$VCS_STATUS_REMOTE_BRANCH" - fi - if [[ $VCS_STATUS_HAS_STAGED == 1 ]]; then - _p9k_get_icon VCS_STAGED_ICON && vcs_prompt+=" $_P9K_RETVAL" - fi - if [[ $VCS_STATUS_HAS_UNSTAGED == 1 ]]; then - _p9k_get_icon VCS_UNSTAGED_ICON && vcs_prompt+=" $_P9K_RETVAL" - fi - if [[ $VCS_STATUS_HAS_UNTRACKED == 1 ]]; then - _p9k_get_icon VCS_UNTRACKED_ICON && vcs_prompt+=" $_P9K_RETVAL" - fi - if [[ $VCS_STATUS_COMMITS_AHEAD -gt 0 ]]; then - _p9k_get_icon VCS_OUTGOING_CHANGES_ICON && vcs_prompt+=" $_P9K_RETVAL$VCS_STATUS_COMMITS_AHEAD" - fi - if [[ $VCS_STATUS_COMMITS_BEHIND -gt 0 ]]; then - _p9k_get_icon VCS_INCOMING_CHANGES_ICON && vcs_prompt+=" $_P9K_RETVAL$VCS_STATUS_COMMITS_BEHIND" - fi - if [[ $VCS_STATUS_STASHES -gt 0 ]]; then - _p9k_get_icon VCS_STASH_ICON && vcs_prompt+=" $_P9K_RETVAL$VCS_STATUS_STASHES" - fi - fi - - _p9k_cache_set $cache_key "${0}_${(U)current_state} $2 ${(qq)vcs_states[$current_state]} ${(qq)DEFAULT_COLOR} ${(qq)vcs_prompt}" - fi - - "$1_prompt_segment" "${(@Q)${(z)_P9K_RETVAL}}" fi } @@ -1896,6 +1980,9 @@ prompt_java_version() { ################################################################ # Main prompt build_left_prompt() { + typeset -gH _P9K_CURRENT_BG=NONE + typeset -gH _P9K_LAST_SEGMENT_INDEX=0 + local index=1 local element for element in "${POWERLEVEL9K_LEFT_PROMPT_ELEMENTS[@]}"; do @@ -1914,12 +2001,18 @@ build_left_prompt() { done left_prompt_end + + unset _P9K_CURRENT_BG _P9K_LAST_SEGMENT_INDEX } # Right prompt build_right_prompt() { + typeset -gH _P9K_CURRENT_BG=NONE + typeset -gH _P9K_LAST_SEGMENT_INDEX=0 + local index=1 local element + for element in "${POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS[@]}"; do # Remove joined information in direct calls element=${element%_joined} @@ -1936,7 +2029,9 @@ build_right_prompt() { done # Clear to the end of the line - echo -n "%E" + _P9K_PROMPT+="%E" + + unset _P9K_CURRENT_BG _P9K_LAST_SEGMENT_INDEX } powerlevel9k_preexec() { @@ -1946,35 +2041,19 @@ powerlevel9k_preexec() { _P9K_MULTILINE_FIRST_PROMPT_PREFIX=$(print_icon MULTILINE_FIRST_PROMPT_PREFIX) _P9K_MULTILINE_LAST_PROMPT_PREFIX=$(print_icon MULTILINE_LAST_PROMPT_PREFIX) -set_default POWERLEVEL9K_PROMPT_ADD_NEWLINE false -powerlevel9k_prepare_prompts() { - # Return values. These need to be global, because - # they are used in prompt_status. Also, we need - # to get the return value of the last command at - # very first in this function. Do not move the - # lines down, otherwise the last command is not - # what you expected it to be. - RETVAL=$? - RETVALS=( "$pipestatus[@]" ) - - local RPROMPT_SUFFIX RPROMPT_PREFIX - _P9K_COMMAND_DURATION=$((EPOCHREALTIME - _P9K_TIMER_START)) - - # Reset start time - _P9K_TIMER_START=0x7FFFFFFF - - if [[ -s $_P9K_CACHE_CHANNEL ]]; then - eval $(<$_P9K_CACHE_CHANNEL) - rm -f $_P9K_CACHE_CHANNEL - if [[ -n $POWERLEVEL9K_MAX_CACHE_SIZE && $#_p9k_cache_data -gt $POWERLEVEL9K_MAX_CACHE_SIZE ]]; then - _p9k_cache_data=() - fi - fi +typeset -fH _p9k_set_prompts() { + typeset -gH _P9K_PROMPT='' + build_left_prompt + local left=$_P9K_PROMPT + _P9K_PROMPT='' + build_right_prompt + local right=$_P9K_PROMPT + unset _P9K_PROMPT local NEWLINE=$'\n' - + local RPROMPT_SUFFIX RPROMPT_PREFIX if [[ "$POWERLEVEL9K_PROMPT_ON_NEWLINE" == true ]]; then - PROMPT="$_P9K_MULTILINE_FIRST_PROMPT_PREFIX%f%b%k\$(build_left_prompt)$NEWLINE$_P9K_MULTILINE_LAST_PROMPT_PREFIX" + PROMPT="$_P9K_MULTILINE_FIRST_PROMPT_PREFIX%f%b%k$left$NEWLINE$_P9K_MULTILINE_LAST_PROMPT_PREFIX" if [[ "$POWERLEVEL9K_RPROMPT_ON_NEWLINE" != true ]]; then # The right prompt should be on the same line as the first line of the left # prompt. To do so, there is just a quite ugly workaround: Before zsh draws @@ -1989,17 +2068,17 @@ powerlevel9k_prepare_prompts() { RPROMPT_SUFFIX='' fi else - PROMPT='%f%b%k$(build_left_prompt)' + PROMPT="%f%b%k$left" RPROMPT_PREFIX='' RPROMPT_SUFFIX='' fi if [[ "$POWERLEVEL9K_DISABLE_RPROMPT" != true ]]; then - RPROMPT="${RPROMPT_PREFIX}"'%f%b%k$(build_right_prompt)%{$reset_color%}'"${RPROMPT_SUFFIX}" + RPROMPT="${RPROMPT_PREFIX}%f%b%k$right%{$reset_color%}${RPROMPT_SUFFIX}" fi if [[ $POWERLEVEL9K_PROMPT_ADD_NEWLINE == true ]]; then - NEWLINES="" + local NEWLINES="" repeat ${POWERLEVEL9K_PROMPT_ADD_NEWLINE_COUNT:-1} { NEWLINES+=$NEWLINE } PROMPT="$NEWLINES$PROMPT" fi @@ -2008,6 +2087,28 @@ powerlevel9k_prepare_prompts() { [[ $ITERM_SHELL_INTEGRATION_INSTALLED == "Yes" ]] && PROMPT="%{$(iterm2_prompt_mark)%}$PROMPT" } +typeset -fH _p9k_reset_prompts() { + typeset -gH _P9K_REFRESH_PROMPT='' + _p9k_set_prompts + unset _P9K_REFRESH_PROMPT + zle && zle .reset-prompt +} + +set_default POWERLEVEL9K_PROMPT_ADD_NEWLINE false +powerlevel9k_prepare_prompts() { + # Return values. These need to be global, because + # they are used in prompt_status. Also, we need + # to get the return value of the last command at + # very first in this function. Do not move the + # lines down, otherwise the last command is not + # what you expected it to be. + RETVAL=$? + RETVALS=( "$pipestatus[@]" ) + _P9K_COMMAND_DURATION=$((EPOCHREALTIME - _P9K_TIMER_START)) + _P9K_TIMER_START=0x7FFFFFFF + _p9k_set_prompts +} + zle-keymap-select () { zle reset-prompt zle -R @@ -2078,6 +2179,8 @@ prompt_powerlevel9k_setup() { add-zsh-hook preexec powerlevel9k_preexec zle -N zle-keymap-select + + [[ $POWERLEVEL9K_DISABLE_GITSTATUS == true ]] || gitstatus_start POWERLEVEL9K } prompt_powerlevel9k_teardown() { |