From fe71e0d80b91239abf5b5e9e3c1e633a0e594a0b Mon Sep 17 00:00:00 2001 From: Andrea Mistrali Date: Wed, 12 Feb 2020 17:22:56 +0100 Subject: [PATCH 1/5] Test for new version --- zsh.d/prompts/pure/pure.zsh | 1209 ++++++++++++++++++----------------- 1 file changed, 608 insertions(+), 601 deletions(-) diff --git a/zsh.d/prompts/pure/pure.zsh b/zsh.d/prompts/pure/pure.zsh index 0a8a700..6d8fdab 100644 --- a/zsh.d/prompts/pure/pure.zsh +++ b/zsh.d/prompts/pure/pure.zsh @@ -28,94 +28,94 @@ # 165392 => 1d 21h 56m 32s # https://github.com/sindresorhus/pretty-time-zsh prompt_pure_human_time_to_var() { - local human total_seconds=$1 var=$2 - local days=$(( total_seconds / 60 / 60 / 24 )) - local hours=$(( total_seconds / 60 / 60 % 24 )) - local minutes=$(( total_seconds / 60 % 60 )) - local seconds=$(( total_seconds % 60 )) - (( days > 0 )) && human+="${days}d " - (( hours > 0 )) && human+="${hours}h " - (( minutes > 0 )) && human+="${minutes}m " - human+="${seconds}s" + local human total_seconds=$1 var=$2 + local days=$(( total_seconds / 60 / 60 / 24 )) + local hours=$(( total_seconds / 60 / 60 % 24 )) + local minutes=$(( total_seconds / 60 % 60 )) + local seconds=$(( total_seconds % 60 )) + (( days > 0 )) && human+="${days}d " + (( hours > 0 )) && human+="${hours}h " + (( minutes > 0 )) && human+="${minutes}m " + human+="${seconds}s" - # Store human readable time in a variable as specified by the caller - typeset -g "${var}"="${human}" + # Store human readable time in a variable as specified by the caller + typeset -g "${var}"="${human}" } # Stores (into prompt_pure_cmd_exec_time) the execution # time of the last command if set threshold was exceeded. prompt_pure_check_cmd_exec_time() { - integer elapsed - (( elapsed = EPOCHSECONDS - ${prompt_pure_cmd_timestamp:-$EPOCHSECONDS} )) - typeset -g prompt_pure_cmd_exec_time= - (( elapsed > ${PURE_CMD_MAX_EXEC_TIME:-5} )) && { - prompt_pure_human_time_to_var $elapsed "prompt_pure_cmd_exec_time" - } + integer elapsed + (( elapsed = EPOCHSECONDS - ${prompt_pure_cmd_timestamp:-$EPOCHSECONDS} )) + typeset -g prompt_pure_cmd_exec_time= + (( elapsed > ${PURE_CMD_MAX_EXEC_TIME:-20} )) && { + prompt_pure_human_time_to_var $elapsed "prompt_pure_cmd_exec_time" + } } prompt_pure_set_title() { - setopt localoptions noshwordsplit + setopt localoptions noshwordsplit - # Emacs terminal does not support settings the title. - (( ${+EMACS} || ${+INSIDE_EMACS} )) && return + # Emacs terminal does not support settings the title. + (( ${+EMACS} || ${+INSIDE_EMACS} )) && return - case $TTY in - # Don't set title over serial console. - /dev/ttyS[0-9]*) return;; - esac + case $TTY in + # Don't set title over serial console. + /dev/ttyS[0-9]*) return;; + esac - # Show hostname if connected via SSH. - local hostname= - if [[ -n $prompt_pure_state[username] ]]; then - # Expand in-place in case ignore-escape is used. - hostname="${(%):-(%m) }" - fi + # Show hostname if connected via SSH. + local hostname= + if [[ -n $prompt_pure_state[username] ]]; then + # Expand in-place in case ignore-escape is used. + hostname="${(%):-(%m) }" + fi - local -a opts - case $1 in - expand-prompt) opts=(-P);; - ignore-escape) opts=(-r);; - esac + local -a opts + case $1 in + expand-prompt) opts=(-P);; + ignore-escape) opts=(-r);; + esac - # Set title atomically in one print statement so that it works when XTRACE is enabled. - print -n $opts $'\e]0;'${hostname}${2}$'\a' + # Set title atomically in one print statement so that it works when XTRACE is enabled. + print -n $opts $'\e]0;'${hostname}${2}$'\a' } prompt_pure_preexec() { - if [[ -n $prompt_pure_git_fetch_pattern ]]; then - # Detect when Git is performing pull/fetch, including Git aliases. - local -H MATCH MBEGIN MEND match mbegin mend - if [[ $2 =~ (git|hub)\ (.*\ )?($prompt_pure_git_fetch_pattern)(\ .*)?$ ]]; then - # We must flush the async jobs to cancel our git fetch in order - # to avoid conflicts with the user issued pull / fetch. - async_flush_jobs 'prompt_pure' - fi - fi + if [[ -n $prompt_pure_git_fetch_pattern ]]; then + # Detect when Git is performing pull/fetch, including Git aliases. + local -H MATCH MBEGIN MEND match mbegin mend + if [[ $2 =~ (git|hub)\ (.*\ )?($prompt_pure_git_fetch_pattern)(\ .*)?$ ]]; then + # We must flush the async jobs to cancel our git fetch in order + # to avoid conflicts with the user issued pull / fetch. + async_flush_jobs 'prompt_pure' + fi + fi - typeset -g prompt_pure_cmd_timestamp=$EPOCHSECONDS + typeset -g prompt_pure_cmd_timestamp=$EPOCHSECONDS - # Shows the current directory and executed command in the title while a process is active. - prompt_pure_set_title 'ignore-escape' "$PWD:t: $2" + # Shows the current directory and executed command in the title while a process is active. + prompt_pure_set_title 'ignore-escape' "$PWD:t: $2" - # Disallow Python virtualenv from updating the prompt. Set it to 12 if - # untouched by the user to indicate that Pure modified it. Here we use - # the magic number 12, same as in `psvar`. - export VIRTUAL_ENV_DISABLE_PROMPT=${VIRTUAL_ENV_DISABLE_PROMPT:-12} + # Disallow Python virtualenv from updating the prompt. Set it to 12 if + # untouched by the user to indicate that Pure modified it. Here we use + # the magic number 12, same as in `psvar`. + export VIRTUAL_ENV_DISABLE_PROMPT=${VIRTUAL_ENV_DISABLE_PROMPT:-12} } # Change the colors if their value are different from the current ones. prompt_pure_set_colors() { - local color_temp key value - for key value in ${(kv)prompt_pure_colors}; do - zstyle -t ":prompt:pure:$key" color "$value" - case $? in - 1) # The current style is different from the one from zstyle. - zstyle -s ":prompt:pure:$key" color color_temp - prompt_pure_colors[$key]=$color_temp ;; - 2) # No style is defined. - prompt_pure_colors[$key]=$prompt_pure_colors_default[$key] ;; - esac - done + local color_temp key value + for key value in ${(kv)prompt_pure_colors}; do + zstyle -t ":prompt:pure:$key" color "$value" + case $? in + 1) # The current style is different from the one from zstyle. + zstyle -s ":prompt:pure:$key" color color_temp + prompt_pure_colors[$key]=$color_temp ;; + 2) # No style is defined. + prompt_pure_colors[$key]=$prompt_pure_colors_default[$key] ;; + esac + done } prompt_pure_set_aws() { @@ -137,693 +137,700 @@ prompt_pure_set_aws() { } prompt_pure_preprompt_render() { - setopt localoptions noshwordsplit + setopt localoptions noshwordsplit - # Set color for Git branch/dirty status and change color if dirty checking has been delayed. - local git_color=$prompt_pure_colors[git:branch] - local git_dirty_color=$prompt_pure_colors[git:dirty] - [[ -n ${prompt_pure_git_last_dirty_check_timestamp+x} ]] && git_color=$prompt_pure_colors[git:branch:cached] + # Set color for Git branch/dirty status and change color if dirty checking has been delayed. + local git_color=$prompt_pure_colors[git:branch] + local git_dirty_color=$prompt_pure_colors[git:dirty] + [[ -n ${prompt_pure_git_last_dirty_check_timestamp+x} ]] && git_color=$prompt_pure_colors[git:branch:cached] - # Initialize the preprompt array. - local -a preprompt_parts + # Initialize the preprompt array. + local -a preprompt_parts - prompt_pure_set_aws - if [[ ! -z $prompt_pure_aws ]]; then - if [[ $prompt_pure_aws_prod -eq 1 ]];then - preprompt_parts+="%F{$prompt_pure_colors[aws:prod]}"'$prompt_pure_aws' - else - preprompt_parts+="%F{$prompt_pure_colors[aws]}"'$prompt_pure_aws' - fi + [[ $UID -eq 0 ]] && preprompt_parts+='%F{$prompt_pure_colors[user:root]}'"⚡" + + [[ ! -z $SSH_CONNECTION ]] && preprompt_parts+='%F{$prompt_pure_colors[host]}'"@%m" + + prompt_pure_set_aws + if [[ ! -z $prompt_pure_aws ]]; then + if [[ $prompt_pure_aws_prod -eq 1 ]];then + preprompt_parts+="%F{$prompt_pure_colors[aws:prod]}"'$prompt_pure_aws' + else + preprompt_parts+="%F{$prompt_pure_colors[aws]}"'$prompt_pure_aws' fi + fi - # Set the path. - preprompt_parts+=('%F{${prompt_pure_colors[path]}}%3.%f') + # Set the path. + preprompt_parts+=('%F{${prompt_pure_colors[path]}}%3.%f') - # Add Git branch and dirty status info. - typeset -gA prompt_pure_vcs_info - if [[ -n $prompt_pure_vcs_info[branch] ]]; then - local branch="%F{$git_color}"'${prompt_pure_vcs_info[branch]}' - if [[ -n $prompt_pure_vcs_info[action] ]]; then - branch+="|%F{$prompt_pure_colors[git:action]}"'$prompt_pure_vcs_info[action]'"%F{$git_color}" - fi - preprompt_parts+=("$branch""%F{$git_dirty_color}"'${prompt_pure_git_dirty}%f') - fi - # Git pull/push arrows. - if [[ -n $prompt_pure_git_arrows ]]; then - preprompt_parts+=('%F{$prompt_pure_colors[git:arrow]}${prompt_pure_git_arrows}%f') - fi + # Add Git branch and dirty status info. + typeset -gA prompt_pure_vcs_info + if [[ -n $prompt_pure_vcs_info[branch] ]]; then + local branch="%F{$git_color}"'${prompt_pure_vcs_info[branch]}' + if [[ -n $prompt_pure_vcs_info[action] ]]; then + branch+="|%F{$prompt_pure_colors[git:action]}"'$prompt_pure_vcs_info[action]'"%F{$git_color}" + fi + preprompt_parts+=("$branch""%F{$git_dirty_color}"'${prompt_pure_git_dirty}%f') + fi + # Git pull/push arrows. + if [[ -n $prompt_pure_git_arrows ]]; then + preprompt_parts+=('%F{$prompt_pure_colors[git:arrow]}${prompt_pure_git_arrows}%f') + fi - # Username and machine, if applicable. - [[ -n $prompt_pure_state[username] ]] && preprompt_parts+=($prompt_pure_state[username]) - # Execution time. - [[ -n $prompt_pure_cmd_exec_time ]] && preprompt_parts+=('%F{$prompt_pure_colors[execution_time]}${prompt_pure_cmd_exec_time}%f') + # # Username and machine, if applicable. + # [[ -n $prompt_pure_state[username] ]] && preprompt_parts+=($prompt_pure_state[username]) + # Execution time. + [[ -n $prompt_pure_cmd_exec_time ]] && preprompt_parts+=('%F{$prompt_pure_colors[execution_time]}${prompt_pure_cmd_exec_time}%f') - local cleaned_ps1=$PROMPT - local -H MATCH MBEGIN MEND - if [[ $PROMPT = *$prompt_newline* ]]; then - # Remove everything from the prompt until the newline. This - # removes the preprompt and only the original PROMPT remains. - cleaned_ps1=${PROMPT##*${prompt_newline}} - fi - unset MATCH MBEGIN MEND + local cleaned_ps1=$PROMPT + local -H MATCH MBEGIN MEND + if [[ $PROMPT = *$prompt_newline* ]]; then + # Remove everything from the prompt until the newline. This + # removes the preprompt and only the original PROMPT remains. + cleaned_ps1=${PROMPT##*${prompt_newline}} + fi + unset MATCH MBEGIN MEND - # Construct the new prompt with a clean preprompt. - local -ah ps1 - ps1=( - ${(j. .)preprompt_parts} # Join parts, space separated. - $prompt_newline # Separate preprompt and prompt. - $cleaned_ps1 - ) + # Construct the new prompt with a clean preprompt. + local -ah ps1 + ps1=( + ${(j. .)preprompt_parts} # Join parts, space separated. + $prompt_newline # Separate preprompt and prompt. + $cleaned_ps1 + ) - PROMPT="${(j..)ps1}" + PROMPT="${(j..)ps1}" - # Expand the prompt for future comparision. - local expanded_prompt - expanded_prompt="${(S%%)PROMPT}" + # Expand the prompt for future comparision. + local expanded_prompt + expanded_prompt="${(S%%)PROMPT}" - # if [[ $1 == precmd ]]; then - # Initial newline, for spaciousness. - # print - # elif [[ $prompt_pure_last_prompt != $expanded_prompt ]]; then - # Redraw the prompt. - prompt_pure_reset_prompt - # fi + # if [[ $1 == precmd ]]; then + # Initial newline, for spaciousness. + # print + # elif [[ $prompt_pure_last_prompt != $expanded_prompt ]]; then + # Redraw the prompt. + prompt_pure_reset_prompt + # fi - typeset -g prompt_pure_last_prompt=$expanded_prompt + typeset -g prompt_pure_last_prompt=$expanded_prompt } prompt_pure_precmd() { - # Check execution time and store it in a variable. - prompt_pure_check_cmd_exec_time - unset prompt_pure_cmd_timestamp + # Check execution time and store it in a variable. + prompt_pure_check_cmd_exec_time + unset prompt_pure_cmd_timestamp - # Shows the full path in the title. - prompt_pure_set_title 'expand-prompt' '%2.' + # Shows the full path in the title. + prompt_pure_set_title 'expand-prompt' '%2.' - # Modify the colors if some have changed.. - prompt_pure_set_colors + # Modify the colors if some have changed.. + prompt_pure_set_colors - # Perform async Git dirty check and fetch. - prompt_pure_async_tasks + # Perform async Git dirty check and fetch. + prompt_pure_async_tasks - # Check if we should display the virtual env. We use a sufficiently high - # index of psvar (12) here to avoid collisions with user defined entries. - psvar[12]= - # Check if a Conda environment is active and display its name. - if [[ -n $CONDA_DEFAULT_ENV ]]; then - psvar[12]="${CONDA_DEFAULT_ENV//[$'\t\r\n']}" - fi - # When VIRTUAL_ENV_DISABLE_PROMPT is empty, it was unset by the user and - # Pure should take back control. - if [[ -n $VIRTUAL_ENV ]] && [[ -z $VIRTUAL_ENV_DISABLE_PROMPT || $VIRTUAL_ENV_DISABLE_PROMPT = 12 ]]; then - psvar[12]="${VIRTUAL_ENV:t}" - export VIRTUAL_ENV_DISABLE_PROMPT=12 - fi + # Check if we should display the virtual env. We use a sufficiently high + # index of psvar (12) here to avoid collisions with user defined entries. + psvar[12]= + # Check if a Conda environment is active and display its name. + if [[ -n $CONDA_DEFAULT_ENV ]]; then + psvar[12]="${CONDA_DEFAULT_ENV//[$'\t\r\n']}" + fi + # When VIRTUAL_ENV_DISABLE_PROMPT is empty, it was unset by the user and + # Pure should take back control. + if [[ -n $VIRTUAL_ENV ]] && [[ -z $VIRTUAL_ENV_DISABLE_PROMPT || $VIRTUAL_ENV_DISABLE_PROMPT = 12 ]]; then + psvar[12]="${VIRTUAL_ENV:t}" + export VIRTUAL_ENV_DISABLE_PROMPT=12 + fi - # Make sure VIM prompt is reset. - prompt_pure_reset_prompt_symbol + # Make sure VIM prompt is reset. + prompt_pure_reset_prompt_symbol - # Print the preprompt. - prompt_pure_preprompt_render "precmd" + # Print the preprompt. + prompt_pure_preprompt_render "precmd" - if [[ -n $ZSH_THEME ]]; then - print "WARNING: Oh My Zsh themes are enabled (ZSH_THEME='${ZSH_THEME}'). Pure might not be working correctly." - print "For more information, see: https://github.com/sindresorhus/pure#oh-my-zsh" - unset ZSH_THEME # Only show this warning once. - fi + if [[ -n $ZSH_THEME ]]; then + print "WARNING: Oh My Zsh themes are enabled (ZSH_THEME='${ZSH_THEME}'). Pure might not be working correctly." + print "For more information, see: https://github.com/sindresorhus/pure#oh-my-zsh" + unset ZSH_THEME # Only show this warning once. + fi } prompt_pure_async_git_aliases() { - setopt localoptions noshwordsplit - local -a gitalias pullalias + setopt localoptions noshwordsplit + local -a gitalias pullalias - # List all aliases and split on newline. - gitalias=(${(@f)"$(command git config --get-regexp "^alias\.")"}) - for line in $gitalias; do - parts=(${(@)=line}) # Split line on spaces. - aliasname=${parts[1]#alias.} # Grab the name (alias.[name]). - shift parts # Remove `aliasname` + # List all aliases and split on newline. + gitalias=(${(@f)"$(command git config --get-regexp "^alias\.")"}) + for line in $gitalias; do + parts=(${(@)=line}) # Split line on spaces. + aliasname=${parts[1]#alias.} # Grab the name (alias.[name]). + shift parts # Remove `aliasname` - # Check alias for pull or fetch. Must be exact match. - if [[ $parts =~ ^(.*\ )?(pull|fetch)(\ .*)?$ ]]; then - pullalias+=($aliasname) - fi - done + # Check alias for pull or fetch. Must be exact match. + if [[ $parts =~ ^(.*\ )?(pull|fetch)(\ .*)?$ ]]; then + pullalias+=($aliasname) + fi + done - print -- ${(j:|:)pullalias} # Join on pipe, for use in regex. + print -- ${(j:|:)pullalias} # Join on pipe, for use in regex. } prompt_pure_async_vcs_info() { - setopt localoptions noshwordsplit + setopt localoptions noshwordsplit - # Configure `vcs_info` inside an async task. This frees up `vcs_info` - # to be used or configured as the user pleases. - zstyle ':vcs_info:*' enable git - zstyle ':vcs_info:*' use-simple true - # Only export three message variables from `vcs_info`. - zstyle ':vcs_info:*' max-exports 3 - # Export branch (%b), Git toplevel (%R), and action (rebase/cherry-pick) (%a). - zstyle ':vcs_info:git*' formats '%b' '%R' - zstyle ':vcs_info:git*' actionformats '%b' '%R' '%a' + # Configure `vcs_info` inside an async task. This frees up `vcs_info` + # to be used or configured as the user pleases. + zstyle ':vcs_info:*' enable git + zstyle ':vcs_info:*' use-simple true + # Only export three message variables from `vcs_info`. + zstyle ':vcs_info:*' max-exports 3 + # Export branch (%b), Git toplevel (%R), and action (rebase/cherry-pick) (%a). + zstyle ':vcs_info:git*' formats '%b' '%R' + zstyle ':vcs_info:git*' actionformats '%b' '%R' '%a' - vcs_info + vcs_info - local -A info - info[pwd]=$PWD - info[top]=$vcs_info_msg_1_ - info[branch]=$vcs_info_msg_0_ - info[action]=$vcs_info_msg_2_ + local -A info + info[pwd]=$PWD + info[top]=$vcs_info_msg_1_ + info[branch]=$vcs_info_msg_0_ + info[action]=$vcs_info_msg_2_ - print -r - ${(@kvq)info} + print -r - ${(@kvq)info} } # Fastest possible way to check if a Git repo is dirty. prompt_pure_async_git_dirty() { - setopt localoptions noshwordsplit - local untracked_dirty=$1 + setopt localoptions noshwordsplit + local untracked_dirty=$1 - if [[ $untracked_dirty = 0 ]]; then - command git diff --no-ext-diff --quiet --exit-code - else - test -z "$(command git status --porcelain --ignore-submodules -unormal)" - fi + if [[ $untracked_dirty = 0 ]]; then + command git diff --no-ext-diff --quiet --exit-code + else + test -z "$(command git status --porcelain --ignore-submodules -unormal)" + fi - return $? + return $? } prompt_pure_async_git_fetch() { - setopt localoptions noshwordsplit + setopt localoptions noshwordsplit - # Sets `GIT_TERMINAL_PROMPT=0` to disable authentication prompt for Git fetch (Git 2.3+). - export GIT_TERMINAL_PROMPT=0 - # Set SSH `BachMode` to disable all interactive SSH password prompting. - export GIT_SSH_COMMAND="${GIT_SSH_COMMAND:-"ssh"} -o BatchMode=yes" + # Sets `GIT_TERMINAL_PROMPT=0` to disable authentication prompt for Git fetch (Git 2.3+). + export GIT_TERMINAL_PROMPT=0 + # Set SSH `BachMode` to disable all interactive SSH password prompting. + export GIT_SSH_COMMAND="${GIT_SSH_COMMAND:-"ssh"} -o BatchMode=yes" - local ref - ref=$(command git symbolic-ref -q HEAD) - local -a remote - remote=($(command git for-each-ref --format='%(upstream:remotename) %(refname)' $ref)) + local ref + ref=$(command git symbolic-ref -q HEAD) + local -a remote + remote=($(command git for-each-ref --format='%(upstream:remotename) %(refname)' $ref)) - if [[ -z $remote[1] ]]; then - # No remote specified for this branch, skip fetch. - return 97 - fi + if [[ -z $remote[1] ]]; then + # No remote specified for this branch, skip fetch. + return 97 + fi - # Default return code, which indicates Git fetch failure. - local fail_code=99 + # Default return code, which indicates Git fetch failure. + local fail_code=99 - # Guard against all forms of password prompts. By setting the shell into - # MONITOR mode we can notice when a child process prompts for user input - # because it will be suspended. Since we are inside an async worker, we - # have no way of transmitting the password and the only option is to - # kill it. If we don't do it this way, the process will corrupt with the - # async worker. - setopt localtraps monitor + # Guard against all forms of password prompts. By setting the shell into + # MONITOR mode we can notice when a child process prompts for user input + # because it will be suspended. Since we are inside an async worker, we + # have no way of transmitting the password and the only option is to + # kill it. If we don't do it this way, the process will corrupt with the + # async worker. + setopt localtraps monitor - # Make sure local HUP trap is unset to allow for signal propagation when - # the async worker is flushed. - trap - HUP + # Make sure local HUP trap is unset to allow for signal propagation when + # the async worker is flushed. + trap - HUP - trap ' - # Unset trap to prevent infinite loop - trap - CHLD - if [[ $jobstates = suspended* ]]; then - # Set fail code to password prompt and kill the fetch. - fail_code=98 - kill %% - fi - ' CHLD + trap ' + # Unset trap to prevent infinite loop + trap - CHLD + if [[ $jobstates = suspended* ]]; then + # Set fail code to password prompt and kill the fetch. + fail_code=98 + kill %% + fi + ' CHLD - # Only fetch information for the current branch and avoid - # fetching tags or submodules to speed up the process. - command git -c gc.auto=0 fetch \ - --quiet \ - --no-tags \ - --recurse-submodules=no \ - $remote &>/dev/null & - wait $! || return $fail_code + # Only fetch information for the current branch and avoid + # fetching tags or submodules to speed up the process. + command git -c gc.auto=0 fetch \ + --quiet \ + --no-tags \ + --recurse-submodules=no \ + $remote &>/dev/null & + wait $! || return $fail_code - unsetopt monitor + unsetopt monitor - # Check arrow status after a successful `git fetch`. - prompt_pure_async_git_arrows + # Check arrow status after a successful `git fetch`. + prompt_pure_async_git_arrows } prompt_pure_async_git_arrows() { - setopt localoptions noshwordsplit - command git rev-list --left-right --count HEAD...@'{u}' + setopt localoptions noshwordsplit + command git rev-list --left-right --count HEAD...@'{u}' } # Try to lower the priority of the worker so that disk heavy operations # like `git status` has less impact on the system responsivity. prompt_pure_async_renice() { - setopt localoptions noshwordsplit + setopt localoptions noshwordsplit - if command -v renice >/dev/null; then - command renice +15 -p $$ - fi + if command -v renice >/dev/null; then + command renice +15 -p $$ + fi - if command -v ionice >/dev/null; then - command ionice -c 3 -p $$ - fi + if command -v ionice >/dev/null; then + command ionice -c 3 -p $$ + fi } prompt_pure_async_tasks() { - setopt localoptions noshwordsplit + setopt localoptions noshwordsplit - # Initialize the async worker. - ((!${prompt_pure_async_init:-0})) && { - async_start_worker "prompt_pure" -u -n - async_register_callback "prompt_pure" prompt_pure_async_callback - typeset -g prompt_pure_async_init=1 - async_job "prompt_pure" prompt_pure_async_renice - } + # Initialize the async worker. + ((!${prompt_pure_async_init:-0})) && { + async_start_worker "prompt_pure" -u -n + async_register_callback "prompt_pure" prompt_pure_async_callback + typeset -g prompt_pure_async_init=1 + async_job "prompt_pure" prompt_pure_async_renice + } - # Update the current working directory of the async worker. - async_worker_eval "prompt_pure" builtin cd -q $PWD + # Update the current working directory of the async worker. + async_worker_eval "prompt_pure" builtin cd -q $PWD - typeset -gA prompt_pure_vcs_info + typeset -gA prompt_pure_vcs_info - local -H MATCH MBEGIN MEND - if [[ $PWD != ${prompt_pure_vcs_info[pwd]}* ]]; then - # Stop any running async jobs. - async_flush_jobs "prompt_pure" + local -H MATCH MBEGIN MEND + if [[ $PWD != ${prompt_pure_vcs_info[pwd]}* ]]; then + # Stop any running async jobs. + async_flush_jobs "prompt_pure" - # Reset Git preprompt variables, switching working tree. - unset prompt_pure_git_dirty - unset prompt_pure_git_last_dirty_check_timestamp - unset prompt_pure_git_arrows - unset prompt_pure_git_fetch_pattern - prompt_pure_vcs_info[branch]= - prompt_pure_vcs_info[top]= - fi - unset MATCH MBEGIN MEND + # Reset Git preprompt variables, switching working tree. + unset prompt_pure_git_dirty + unset prompt_pure_git_last_dirty_check_timestamp + unset prompt_pure_git_arrows + unset prompt_pure_git_fetch_pattern + prompt_pure_vcs_info[branch]= + prompt_pure_vcs_info[top]= + fi + unset MATCH MBEGIN MEND - async_job "prompt_pure" prompt_pure_async_vcs_info + async_job "prompt_pure" prompt_pure_async_vcs_info - # Only perform tasks inside a Git working tree. - [[ -n $prompt_pure_vcs_info[top] ]] || return + # Only perform tasks inside a Git working tree. + [[ -n $prompt_pure_vcs_info[top] ]] || return - prompt_pure_async_refresh + prompt_pure_async_refresh } prompt_pure_async_refresh() { - setopt localoptions noshwordsplit + setopt localoptions noshwordsplit - if [[ -z $prompt_pure_git_fetch_pattern ]]; then - # We set the pattern here to avoid redoing the pattern check until the - # working three has changed. Pull and fetch are always valid patterns. - typeset -g prompt_pure_git_fetch_pattern="pull|fetch" - async_job "prompt_pure" prompt_pure_async_git_aliases - fi + if [[ -z $prompt_pure_git_fetch_pattern ]]; then + # We set the pattern here to avoid redoing the pattern check until the + # working three has changed. Pull and fetch are always valid patterns. + typeset -g prompt_pure_git_fetch_pattern="pull|fetch" + async_job "prompt_pure" prompt_pure_async_git_aliases + fi - async_job "prompt_pure" prompt_pure_async_git_arrows + async_job "prompt_pure" prompt_pure_async_git_arrows - # Do not preform `git fetch` if it is disabled or in home folder. - if (( ${PURE_GIT_PULL:-1} )) && [[ $prompt_pure_vcs_info[top] != $HOME ]]; then - # Tell the async worker to do a `git fetch`. - async_job "prompt_pure" prompt_pure_async_git_fetch - fi + # Do not preform `git fetch` if it is disabled or in home folder. + if (( ${PURE_GIT_PULL:-1} )) && [[ $prompt_pure_vcs_info[top] != $HOME ]]; then + # Tell the async worker to do a `git fetch`. + async_job "prompt_pure" prompt_pure_async_git_fetch + fi - # If dirty checking is sufficiently fast, - # tell the worker to check it again, or wait for timeout. - integer time_since_last_dirty_check=$(( EPOCHSECONDS - ${prompt_pure_git_last_dirty_check_timestamp:-0} )) - if (( time_since_last_dirty_check > ${PURE_GIT_DELAY_DIRTY_CHECK:-1800} )); then - unset prompt_pure_git_last_dirty_check_timestamp - # Check check if there is anything to pull. - async_job "prompt_pure" prompt_pure_async_git_dirty ${PURE_GIT_UNTRACKED_DIRTY:-1} - fi + # If dirty checking is sufficiently fast, + # tell the worker to check it again, or wait for timeout. + integer time_since_last_dirty_check=$(( EPOCHSECONDS - ${prompt_pure_git_last_dirty_check_timestamp:-0} )) + if (( time_since_last_dirty_check > ${PURE_GIT_DELAY_DIRTY_CHECK:-1800} )); then + unset prompt_pure_git_last_dirty_check_timestamp + # Check check if there is anything to pull. + async_job "prompt_pure" prompt_pure_async_git_dirty ${PURE_GIT_UNTRACKED_DIRTY:-1} + fi } prompt_pure_check_git_arrows() { - setopt localoptions noshwordsplit - local arrows left=${1:-0} right=${2:-0} + setopt localoptions noshwordsplit + local arrows left=${1:-0} right=${2:-0} - (( right > 0 )) && arrows+=${PURE_GIT_DOWN_ARROW:-⇣} - (( left > 0 )) && arrows+=${PURE_GIT_UP_ARROW:-⇡} + (( right > 0 )) && arrows+=${PURE_GIT_DOWN_ARROW:-⇣} + (( left > 0 )) && arrows+=${PURE_GIT_UP_ARROW:-⇡} - [[ -n $arrows ]] || return - typeset -g REPLY=$arrows + [[ -n $arrows ]] || return + typeset -g REPLY=$arrows } prompt_pure_async_callback() { - setopt localoptions noshwordsplit - local job=$1 code=$2 output=$3 exec_time=$4 next_pending=$6 - local do_render=0 + setopt localoptions noshwordsplit + local job=$1 code=$2 output=$3 exec_time=$4 next_pending=$6 + local do_render=0 - case $job in - \[async]) - # Code is 1 for corrupted worker output and 2 for dead worker. - if [[ $code -eq 2 ]]; then - # Our worker died unexpectedly. - typeset -g prompt_pure_async_init=0 - fi - ;; - prompt_pure_async_vcs_info) - local -A info - typeset -gA prompt_pure_vcs_info + case $job in + \[async]) + # Code is 1 for corrupted worker output and 2 for dead worker. + if [[ $code -eq 2 ]]; then + # Our worker died unexpectedly. + typeset -g prompt_pure_async_init=0 + fi + ;; + prompt_pure_async_vcs_info) + local -A info + typeset -gA prompt_pure_vcs_info - # Parse output (z) and unquote as array (Q@). - info=("${(Q@)${(z)output}}") - local -H MATCH MBEGIN MEND - if [[ $info[pwd] != $PWD ]]; then - # The path has changed since the check started, abort. - return - fi - # Check if Git top-level has changed. - if [[ $info[top] = $prompt_pure_vcs_info[top] ]]; then - # If the stored pwd is part of $PWD, $PWD is shorter and likelier - # to be top-level, so we update pwd. - if [[ $prompt_pure_vcs_info[pwd] = ${PWD}* ]]; then - prompt_pure_vcs_info[pwd]=$PWD - fi - else - # Store $PWD to detect if we (maybe) left the Git path. - prompt_pure_vcs_info[pwd]=$PWD - fi - unset MATCH MBEGIN MEND + # Parse output (z) and unquote as array (Q@). + info=("${(Q@)${(z)output}}") + local -H MATCH MBEGIN MEND + if [[ $info[pwd] != $PWD ]]; then + # The path has changed since the check started, abort. + return + fi + # Check if Git top-level has changed. + if [[ $info[top] = $prompt_pure_vcs_info[top] ]]; then + # If the stored pwd is part of $PWD, $PWD is shorter and likelier + # to be top-level, so we update pwd. + if [[ $prompt_pure_vcs_info[pwd] = ${PWD}* ]]; then + prompt_pure_vcs_info[pwd]=$PWD + fi + else + # Store $PWD to detect if we (maybe) left the Git path. + prompt_pure_vcs_info[pwd]=$PWD + fi + unset MATCH MBEGIN MEND - # The update has a Git top-level set, which means we just entered a new - # Git directory. Run the async refresh tasks. - [[ -n $info[top] ]] && [[ -z $prompt_pure_vcs_info[top] ]] && prompt_pure_async_refresh + # The update has a Git top-level set, which means we just entered a new + # Git directory. Run the async refresh tasks. + [[ -n $info[top] ]] && [[ -z $prompt_pure_vcs_info[top] ]] && prompt_pure_async_refresh - # Always update branch and top-level. - prompt_pure_vcs_info[branch]=$info[branch] - prompt_pure_vcs_info[top]=$info[top] - prompt_pure_vcs_info[action]=$info[action] + # Always update branch and top-level. + prompt_pure_vcs_info[branch]=$info[branch] + prompt_pure_vcs_info[top]=$info[top] + prompt_pure_vcs_info[action]=$info[action] - do_render=1 - ;; - prompt_pure_async_git_aliases) - if [[ -n $output ]]; then - # Append custom Git aliases to the predefined ones. - prompt_pure_git_fetch_pattern+="|$output" - fi - ;; - prompt_pure_async_git_dirty) - local prev_dirty=$prompt_pure_git_dirty - if (( code == 0 )); then - unset prompt_pure_git_dirty - else - typeset -g prompt_pure_git_dirty="*" - fi + do_render=1 + ;; + prompt_pure_async_git_aliases) + if [[ -n $output ]]; then + # Append custom Git aliases to the predefined ones. + prompt_pure_git_fetch_pattern+="|$output" + fi + ;; + prompt_pure_async_git_dirty) + local prev_dirty=$prompt_pure_git_dirty + if (( code == 0 )); then + unset prompt_pure_git_dirty + else + typeset -g prompt_pure_git_dirty="*" + fi - [[ $prev_dirty != $prompt_pure_git_dirty ]] && do_render=1 + [[ $prev_dirty != $prompt_pure_git_dirty ]] && do_render=1 - # When `prompt_pure_git_last_dirty_check_timestamp` is set, the Git info is displayed - # in a different color. To distinguish between a "fresh" and a "cached" result, the - # preprompt is rendered before setting this variable. Thus, only upon the next - # rendering of the preprompt will the result appear in a different color. - (( $exec_time > 5 )) && prompt_pure_git_last_dirty_check_timestamp=$EPOCHSECONDS - ;; - prompt_pure_async_git_fetch|prompt_pure_async_git_arrows) - # `prompt_pure_async_git_fetch` executes `prompt_pure_async_git_arrows` - # after a successful fetch. - case $code in - 0) - local REPLY - prompt_pure_check_git_arrows ${(ps:\t:)output} - if [[ $prompt_pure_git_arrows != $REPLY ]]; then - typeset -g prompt_pure_git_arrows=$REPLY - do_render=1 - fi - ;; - 97) - # No remote available, make sure to clear git arrows if set. - if [[ -n $prompt_pure_git_arrows ]]; then - typeset -g prompt_pure_git_arrows= - do_render=1 - fi - ;; - 99|98) - # Git fetch failed. - ;; - *) - # Non-zero exit status from `prompt_pure_async_git_arrows`, - # indicating that there is no upstream configured. - if [[ -n $prompt_pure_git_arrows ]]; then - unset prompt_pure_git_arrows - do_render=1 - fi - ;; - esac - ;; - prompt_pure_async_renice) - ;; - esac + # When `prompt_pure_git_last_dirty_check_timestamp` is set, the Git info is displayed + # in a different color. To distinguish between a "fresh" and a "cached" result, the + # preprompt is rendered before setting this variable. Thus, only upon the next + # rendering of the preprompt will the result appear in a different color. + (( $exec_time > 5 )) && prompt_pure_git_last_dirty_check_timestamp=$EPOCHSECONDS + ;; + prompt_pure_async_git_fetch|prompt_pure_async_git_arrows) + # `prompt_pure_async_git_fetch` executes `prompt_pure_async_git_arrows` + # after a successful fetch. + case $code in + 0) + local REPLY + prompt_pure_check_git_arrows ${(ps:\t:)output} + if [[ $prompt_pure_git_arrows != $REPLY ]]; then + typeset -g prompt_pure_git_arrows=$REPLY + do_render=1 + fi + ;; + 97) + # No remote available, make sure to clear git arrows if set. + if [[ -n $prompt_pure_git_arrows ]]; then + typeset -g prompt_pure_git_arrows= + do_render=1 + fi + ;; + 99|98) + # Git fetch failed. + ;; + *) + # Non-zero exit status from `prompt_pure_async_git_arrows`, + # indicating that there is no upstream configured. + if [[ -n $prompt_pure_git_arrows ]]; then + unset prompt_pure_git_arrows + do_render=1 + fi + ;; + esac + ;; + prompt_pure_async_renice) + ;; + esac - if (( next_pending )); then - (( do_render )) && typeset -g prompt_pure_async_render_requested=1 - return - fi + if (( next_pending )); then + (( do_render )) && typeset -g prompt_pure_async_render_requested=1 + return + fi - [[ ${prompt_pure_async_render_requested:-$do_render} = 1 ]] && prompt_pure_preprompt_render - unset prompt_pure_async_render_requested + [[ ${prompt_pure_async_render_requested:-$do_render} = 1 ]] && prompt_pure_preprompt_render + unset prompt_pure_async_render_requested } prompt_pure_reset_prompt() { - if [[ $CONTEXT == cont ]]; then - # When the context is "cont", PS2 is active and calling - # reset-prompt will have no effect on PS1, but it will - # reset the execution context (%_) of PS2 which we don't - # want. Unfortunately, we can't save the output of "%_" - # either because it is only ever rendered as part of the - # prompt, expanding in-place won't work. - return - fi + if [[ $CONTEXT == cont ]]; then + # When the context is "cont", PS2 is active and calling + # reset-prompt will have no effect on PS1, but it will + # reset the execution context (%_) of PS2 which we don't + # want. Unfortunately, we can't save the output of "%_" + # either because it is only ever rendered as part of the + # prompt, expanding in-place won't work. + return + fi - zle && zle .reset-prompt + zle && zle .reset-prompt } prompt_pure_reset_prompt_symbol() { - prompt_pure_state[prompt]=${PURE_PROMPT_SYMBOL:-❯} + prompt_pure_state[prompt]=${PURE_PROMPT_SYMBOL:-❯} } prompt_pure_update_vim_prompt_widget() { - setopt localoptions noshwordsplit - prompt_pure_state[prompt]=${${KEYMAP/vicmd/${PURE_PROMPT_VICMD_SYMBOL:-❮}}/(main|viins)/${PURE_PROMPT_SYMBOL:-❯}} + setopt localoptions noshwordsplit + prompt_pure_state[prompt]=${${KEYMAP/vicmd/${PURE_PROMPT_VICMD_SYMBOL:-❮}}/(main|viins)/${PURE_PROMPT_SYMBOL:-❯}} - prompt_pure_reset_prompt + prompt_pure_reset_prompt } prompt_pure_reset_vim_prompt_widget() { - setopt localoptions noshwordsplit - prompt_pure_reset_prompt_symbol + setopt localoptions noshwordsplit + prompt_pure_reset_prompt_symbol - # We can't perform a prompt reset at this point because it - # removes the prompt marks inserted by macOS Terminal. + # We can't perform a prompt reset at this point because it + # removes the prompt marks inserted by macOS Terminal. } prompt_pure_state_setup() { - setopt localoptions noshwordsplit + # setopt localoptions noshwordsplit - # Check SSH_CONNECTION and the current state. - local ssh_connection=${SSH_CONNECTION:-$PROMPT_PURE_SSH_CONNECTION} - local username hostname - if [[ -z $ssh_connection ]] && (( $+commands[who] )); then - # When changing user on a remote system, the $SSH_CONNECTION - # environment variable can be lost. Attempt detection via `who`. - local who_out - who_out=$(who -m 2>/dev/null) - if (( $? )); then - # Who am I not supported, fallback to plain who. - local -a who_in - who_in=( ${(f)"$(who 2>/dev/null)"} ) - who_out="${(M)who_in:#*[[:space:]]${TTY#/dev/}[[:space:]]*}" - fi + # # Check SSH_CONNECTION and the current state. + # local ssh_connection=${SSH_CONNECTION:-$PROMPT_PURE_SSH_CONNECTION} + # local username hostname + # if [[ -z $ssh_connection ]] && (( $+commands[who] )); then + # # When changing user on a remote system, the $SSH_CONNECTION + # # environment variable can be lost. Attempt detection via `who`. + # local who_out + # who_out=$(who -m 2>/dev/null) + # if (( $? )); then + # # Who am I not supported, fallback to plain who. + # local -a who_in + # who_in=( ${(f)"$(who 2>/dev/null)"} ) + # who_out="${(M)who_in:#*[[:space:]]${TTY#/dev/}[[:space:]]*}" + # fi - local reIPv6='(([0-9a-fA-F]+:)|:){2,}[0-9a-fA-F]+' # Simplified, only checks partial pattern. - local reIPv4='([0-9]{1,3}\.){3}[0-9]+' # Simplified, allows invalid ranges. - # Here we assume two non-consecutive periods represents a - # hostname. This matches `foo.bar.baz`, but not `foo.bar`. - local reHostname='([.][^. ]+){2}' + # local reIPv6='(([0-9a-fA-F]+:)|:){2,}[0-9a-fA-F]+' # Simplified, only checks partial pattern. + # local reIPv4='([0-9]{1,3}\.){3}[0-9]+' # Simplified, allows invalid ranges. + # # Here we assume two non-consecutive periods represents a + # # hostname. This matches `foo.bar.baz`, but not `foo.bar`. + # local reHostname='([.][^. ]+){2}' - # Usually the remote address is surrounded by parenthesis, but - # not on all systems (e.g. busybox). - local -H MATCH MBEGIN MEND - if [[ $who_out =~ "\(?($reIPv4|$reIPv6|$reHostname)\)?\$" ]]; then - ssh_connection=$MATCH + # # Usually the remote address is surrounded by parenthesis, but + # # not on all systems (e.g. busybox). + # local -H MATCH MBEGIN MEND + # if [[ $who_out =~ "\(?($reIPv4|$reIPv6|$reHostname)\)?\$" ]]; then + # ssh_connection=$MATCH - # Export variable to allow detection propagation inside - # shells spawned by this one (e.g. tmux does not always - # inherit the same tty, which breaks detection). - export PROMPT_PURE_SSH_CONNECTION=$ssh_connection - fi - unset MATCH MBEGIN MEND - fi + # # Export variable to allow detection propagation inside + # # shells spawned by this one (e.g. tmux does not always + # # inherit the same tty, which breaks detection). + # export PROMPT_PURE_SSH_CONNECTION=$ssh_connection + # fi + # unset MATCH MBEGIN MEND + # fi - hostname='%F{$prompt_pure_colors[host]}@%m%f' - # Show `username@host` if logged in through SSH. - [[ -n $ssh_connection ]] && username='%F{$prompt_pure_colors[user]}%n%f'"$hostname" + # hostname='%F{$prompt_pure_colors[host]}@%m%f' + # # Show `username@host` if logged in through SSH. + # [[ -n $ssh_connection ]] && username='%F{$prompt_pure_colors[user]}%n%f'"$hostname" - # Show `username@host` if root, with username in default color. - [[ $UID -eq 0 ]] && username='%F{$prompt_pure_colors[user:root]}%n%f'"$hostname" + # # Show `username@host` if root, with username in default color. + # [[ $UID -eq 0 ]] && username='%F{$prompt_pure_colors[user:root]}%n%f'"$hostname" - typeset -gA prompt_pure_state - prompt_pure_state[version]="1.11.0" - prompt_pure_state+=( - username "$username" - prompt "${PURE_PROMPT_SYMBOL:-❯}" - ) + typeset -gA prompt_pure_state + prompt_pure_state[version]="1.11.0" + prompt_pure_state+=( + username "$username" + prompt "${PURE_PROMPT_SYMBOL:-❯}" + ) } -prompt_pure_system_report() { - setopt localoptions noshwordsplit - - print - "- Zsh: $($SHELL --version) ($SHELL)" - print -n - "- Operating system: " - case "$(uname -s)" in - Darwin) print "$(sw_vers -productName) $(sw_vers -productVersion) ($(sw_vers -buildVersion))";; - *) print "$(uname -s) ($(uname -v))";; - esac - print - "- Terminal program: ${TERM_PROGRAM:-unknown} (${TERM_PROGRAM_VERSION:-unknown})" - print -n - "- Tmux: " - [[ -n $TMUX ]] && print "yes" || print "no" - - local git_version - git_version=($(git --version)) # Remove newlines, if hub is present. - print - "- Git: $git_version" - - print - "- Pure state:" - for k v in "${(@kv)prompt_pure_state}"; do - print - " - $k: \`${(q)v}\`" - done - print - "- PROMPT: \`$(typeset -p PROMPT)\`" - print - "- Colors: \`$(typeset -p prompt_pure_colors)\`" - print - "- Virtualenv: \`$(typeset -p VIRTUAL_ENV_DISABLE_PROMPT)\`" - print - "- Conda: \`$(typeset -p CONDA_CHANGEPS1)\`" - - local ohmyzsh=0 - typeset -la frameworks - (( $+ANTIBODY_HOME )) && frameworks+=("Antibody") - (( $+ADOTDIR )) && frameworks+=("Antigen") - (( $+ANTIGEN_HS_HOME )) && frameworks+=("Antigen-hs") - (( $+functions[upgrade_oh_my_zsh] )) && { - ohmyzsh=1 - frameworks+=("Oh My Zsh") - } - (( $+ZPREZTODIR )) && frameworks+=("Prezto") - (( $+ZPLUG_ROOT )) && frameworks+=("Zplug") - (( $+ZPLGM )) && frameworks+=("Zplugin") - - (( $#frameworks == 0 )) && frameworks+=("None") - print - "- Detected frameworks: ${(j:, :)frameworks}" - - if (( ohmyzsh )); then - print - " - Oh My Zsh:" - print - " - Plugins: ${(j:, :)plugins}" - fi -} prompt_pure_setup() { - # Prevent percentage showing up if output doesn't end with a newline. - export PROMPT_EOL_MARK='' + # Prevent percentage showing up if output doesn't end with a newline. + export PROMPT_EOL_MARK='' - prompt_opts=(subst percent) + prompt_opts=(subst percent) - # Borrowed from `promptinit`. Sets the prompt options in case Pure was not - # initialized via `promptinit`. - setopt noprompt{bang,cr,percent,subst} "prompt${^prompt_opts[@]}" + # Borrowed from `promptinit`. Sets the prompt options in case Pure was not + # initialized via `promptinit`. + setopt noprompt{bang,cr,percent,subst} "prompt${^prompt_opts[@]}" - if [[ -z $prompt_newline ]]; then - # This variable needs to be set, usually set by promptinit. - typeset -g prompt_newline=$'\n%{\r%}' - fi + if [[ -z $prompt_newline ]]; then + # This variable needs to be set, usually set by promptinit. + typeset -g prompt_newline=$'\n%{\r%}' + fi - zmodload zsh/datetime - zmodload zsh/zle - zmodload zsh/parameter - zmodload zsh/zutil + zmodload zsh/datetime + zmodload zsh/zle + zmodload zsh/parameter + zmodload zsh/zutil - autoload -Uz add-zsh-hook - autoload -Uz vcs_info - autoload -Uz async && async + autoload -Uz add-zsh-hook + autoload -Uz vcs_info + autoload -Uz async && async - # The `add-zle-hook-widget` function is not guaranteed to be available. - # It was added in Zsh 5.3. - autoload -Uz +X add-zle-hook-widget 2>/dev/null + # The `add-zle-hook-widget` function is not guaranteed to be available. + # It was added in Zsh 5.3. + autoload -Uz +X add-zle-hook-widget 2>/dev/null - # Set the colors. - typeset -gA prompt_pure_colors_default prompt_pure_colors - prompt_pure_colors_default=( - execution_time yellow - git:arrow cyan - git:branch 242 - git:branch:cached red - git:action 242 - git:dirty 218 - host 242 - path blue - prompt:error red - prompt:success magenta - prompt:continuation 242 - user 242 - user:root default - virtualenv 242 - aws yellow - aws:prod red + # Set the colors. + typeset -gA prompt_pure_colors_default prompt_pure_colors + prompt_pure_colors_default=( + execution_time yellow + git:arrow cyan + git:branch 242 + git:branch:cached red + git:action 242 + git:dirty 218 + host 242 + path blue + prompt:error red + prompt:success magenta + prompt:continuation 242 + user 242 + user:root default + virtualenv 242 + aws yellow + aws:prod red - ) - prompt_pure_colors=("${(@kv)prompt_pure_colors_default}") + ) + prompt_pure_colors=("${(@kv)prompt_pure_colors_default}") - add-zsh-hook precmd prompt_pure_precmd - add-zsh-hook preexec prompt_pure_preexec + add-zsh-hook precmd prompt_pure_precmd + add-zsh-hook preexec prompt_pure_preexec - prompt_pure_state_setup + prompt_pure_state_setup - zle -N prompt_pure_reset_prompt - zle -N prompt_pure_update_vim_prompt_widget - zle -N prompt_pure_reset_vim_prompt_widget - if (( $+functions[add-zle-hook-widget] )); then - add-zle-hook-widget zle-line-finish prompt_pure_reset_vim_prompt_widget - add-zle-hook-widget zle-keymap-select prompt_pure_update_vim_prompt_widget - fi + zle -N prompt_pure_reset_prompt + zle -N prompt_pure_update_vim_prompt_widget + zle -N prompt_pure_reset_vim_prompt_widget + if (( $+functions[add-zle-hook-widget] )); then + add-zle-hook-widget zle-line-finish prompt_pure_reset_vim_prompt_widget + add-zle-hook-widget zle-keymap-select prompt_pure_update_vim_prompt_widget + fi - # If a virtualenv is activated, display it in grey. - PROMPT='%(12V.%F{$prompt_pure_colors[virtualenv]}%12v%f .)' + # If a virtualenv is activated, display it in grey. + PROMPT='%(12V.%F{$prompt_pure_colors[virtualenv]}%12v%f .)' - # Prompt turns red if the previous command didn't exit with 0. - local prompt_indicator='%(?.%F{$prompt_pure_colors[prompt:success]}.%F{$prompt_pure_colors[prompt:error]})${prompt_pure_state[prompt]}%f ' - PROMPT+=$prompt_indicator + # Prompt turns red if the previous command didn't exit with 0. + local prompt_indicator='%(?.%F{$prompt_pure_colors[prompt:success]}.%F{$prompt_pure_colors[prompt:error]})${prompt_pure_state[prompt]}%f ' + PROMPT+=$prompt_indicator - # Indicate continuation prompt by … and use a darker color for it. - PROMPT2='%F{$prompt_pure_colors[prompt:continuation]}… %(1_.%_ .%_)%f'$prompt_indicator + # Indicate continuation prompt by … and use a darker color for it. + PROMPT2='%F{$prompt_pure_colors[prompt:continuation]}… %(1_.%_ .%_)%f'$prompt_indicator - # Store prompt expansion symbols for in-place expansion via (%). For - # some reason it does not work without storing them in a variable first. - typeset -ga prompt_pure_debug_depth - prompt_pure_debug_depth=('%e' '%N' '%x') + # Store prompt expansion symbols for in-place expansion via (%). For + # some reason it does not work without storing them in a variable first. + typeset -ga prompt_pure_debug_depth + prompt_pure_debug_depth=('%e' '%N' '%x') - # Compare is used to check if %N equals %x. When they differ, the main - # prompt is used to allow displaying both filename and function. When - # they match, we use the secondary prompt to avoid displaying duplicate - # information. - local -A ps4_parts - ps4_parts=( - depth '%F{yellow}${(l:${(%)prompt_pure_debug_depth[1]}::+:)}%f' - compare '${${(%)prompt_pure_debug_depth[2]}:#${(%)prompt_pure_debug_depth[3]}}' - main '%F{blue}${${(%)prompt_pure_debug_depth[3]}:t}%f%F{242}:%I%f %F{242}@%f%F{blue}%N%f%F{242}:%i%f' - secondary '%F{blue}%N%f%F{242}:%i' - prompt '%F{242}>%f ' - ) - # Combine the parts with conditional logic. First the `:+` operator is - # used to replace `compare` either with `main` or an ampty string. Then - # the `:-` operator is used so that if `compare` becomes an empty - # string, it is replaced with `secondary`. - local ps4_symbols='${${'${ps4_parts[compare]}':+"'${ps4_parts[main]}'"}:-"'${ps4_parts[secondary]}'"}' + # Compare is used to check if %N equals %x. When they differ, the main + # prompt is used to allow displaying both filename and function. When + # they match, we use the secondary prompt to avoid displaying duplicate + # information. + local -A ps4_parts + ps4_parts=( + depth '%F{yellow}${(l:${(%)prompt_pure_debug_depth[1]}::+:)}%f' + compare '${${(%)prompt_pure_debug_depth[2]}:#${(%)prompt_pure_debug_depth[3]}}' + main '%F{blue}${${(%)prompt_pure_debug_depth[3]}:t}%f%F{242}:%I%f %F{242}@%f%F{blue}%N%f%F{242}:%i%f' + secondary '%F{blue}%N%f%F{242}:%i' + prompt '%F{242}>%f ' + ) + # Combine the parts with conditional logic. First the `:+` operator is + # used to replace `compare` either with `main` or an ampty string. Then + # the `:-` operator is used so that if `compare` becomes an empty + # string, it is replaced with `secondary`. + local ps4_symbols='${${'${ps4_parts[compare]}':+"'${ps4_parts[main]}'"}:-"'${ps4_parts[secondary]}'"}' - # Improve the debug prompt (PS4), show depth by repeating the +-sign and - # add colors to highlight essential parts like file and function name. - PROMPT4="${ps4_parts[depth]} ${ps4_symbols}${ps4_parts[prompt]}" + # Improve the debug prompt (PS4), show depth by repeating the +-sign and + # add colors to highlight essential parts like file and function name. + PROMPT4="${ps4_parts[depth]} ${ps4_symbols}${ps4_parts[prompt]}" - # Guard against Oh My Zsh themes overriding Pure. - unset ZSH_THEME + # Guard against Oh My Zsh themes overriding Pure. + unset ZSH_THEME - # Guard against (ana)conda changing the PS1 prompt - # (we manually insert the env when it's available). - export CONDA_CHANGEPS1=no + # Guard against (ana)conda changing the PS1 prompt + # (we manually insert the env when it's available). + export CONDA_CHANGEPS1=no } prompt_pure_setup "$@" + + +# Utils +prompt_pure_system_report() { + setopt localoptions noshwordsplit + + print - "- Zsh: $($SHELL --version) ($SHELL)" + print -n - "- Operating system: " + case "$(uname -s)" in + Darwin) print "$(sw_vers -productName) $(sw_vers -productVersion) ($(sw_vers -buildVersion))";; + *) print "$(uname -s) ($(uname -v))";; + esac + print - "- Terminal program: ${TERM_PROGRAM:-unknown} (${TERM_PROGRAM_VERSION:-unknown})" + print -n - "- Tmux: " + [[ -n $TMUX ]] && print "yes" || print "no" + + local git_version + git_version=($(git --version)) # Remove newlines, if hub is present. + print - "- Git: $git_version" + + print - "- Pure state:" + for k v in "${(@kv)prompt_pure_state}"; do + print - " - $k: \`${(q)v}\`" + done + print - "- PROMPT: \`$(typeset -p PROMPT)\`" + print - "- Colors: \`$(typeset -p prompt_pure_colors)\`" + print - "- Virtualenv: \`$(typeset -p VIRTUAL_ENV_DISABLE_PROMPT)\`" + print - "- Conda: \`$(typeset -p CONDA_CHANGEPS1)\`" + + local ohmyzsh=0 + typeset -la frameworks + (( $+ANTIBODY_HOME )) && frameworks+=("Antibody") + (( $+ADOTDIR )) && frameworks+=("Antigen") + (( $+ANTIGEN_HS_HOME )) && frameworks+=("Antigen-hs") + (( $+functions[upgrade_oh_my_zsh] )) && { + ohmyzsh=1 + frameworks+=("Oh My Zsh") + } + (( $+ZPREZTODIR )) && frameworks+=("Prezto") + (( $+ZPLUG_ROOT )) && frameworks+=("Zplug") + (( $+ZPLGM )) && frameworks+=("Zplugin") + + (( $#frameworks == 0 )) && frameworks+=("None") + print - "- Detected frameworks: ${(j:, :)frameworks}" + + if (( ohmyzsh )); then + print - " - Oh My Zsh:" + print - " - Plugins: ${(j:, :)plugins}" + fi +} From 1a4362c446d1a429f8d6a97bb2e7065833375e1a Mon Sep 17 00:00:00 2001 From: Andrea Mistrali Date: Thu, 13 Feb 2020 10:53:47 +0100 Subject: [PATCH 2/5] Improvements --- zsh.d/prompts/pure/pure.zsh | 58 +++++-------------------------------- 1 file changed, 7 insertions(+), 51 deletions(-) diff --git a/zsh.d/prompts/pure/pure.zsh b/zsh.d/prompts/pure/pure.zsh index 6d8fdab..f62a67a 100644 --- a/zsh.d/prompts/pure/pure.zsh +++ b/zsh.d/prompts/pure/pure.zsh @@ -132,7 +132,7 @@ prompt_pure_set_aws() { if [[ "$AWS_PROFILE" == "$_aws_prod_profile" ]]; then prompt_pure_aws_prod=1 fi - prompt_pure_aws="$AWS_PROFILE>" + prompt_pure_aws="/$AWS_PROFILE/" fi } @@ -621,50 +621,6 @@ prompt_pure_reset_vim_prompt_widget() { } prompt_pure_state_setup() { - # setopt localoptions noshwordsplit - - # # Check SSH_CONNECTION and the current state. - # local ssh_connection=${SSH_CONNECTION:-$PROMPT_PURE_SSH_CONNECTION} - # local username hostname - # if [[ -z $ssh_connection ]] && (( $+commands[who] )); then - # # When changing user on a remote system, the $SSH_CONNECTION - # # environment variable can be lost. Attempt detection via `who`. - # local who_out - # who_out=$(who -m 2>/dev/null) - # if (( $? )); then - # # Who am I not supported, fallback to plain who. - # local -a who_in - # who_in=( ${(f)"$(who 2>/dev/null)"} ) - # who_out="${(M)who_in:#*[[:space:]]${TTY#/dev/}[[:space:]]*}" - # fi - - # local reIPv6='(([0-9a-fA-F]+:)|:){2,}[0-9a-fA-F]+' # Simplified, only checks partial pattern. - # local reIPv4='([0-9]{1,3}\.){3}[0-9]+' # Simplified, allows invalid ranges. - # # Here we assume two non-consecutive periods represents a - # # hostname. This matches `foo.bar.baz`, but not `foo.bar`. - # local reHostname='([.][^. ]+){2}' - - # # Usually the remote address is surrounded by parenthesis, but - # # not on all systems (e.g. busybox). - # local -H MATCH MBEGIN MEND - # if [[ $who_out =~ "\(?($reIPv4|$reIPv6|$reHostname)\)?\$" ]]; then - # ssh_connection=$MATCH - - # # Export variable to allow detection propagation inside - # # shells spawned by this one (e.g. tmux does not always - # # inherit the same tty, which breaks detection). - # export PROMPT_PURE_SSH_CONNECTION=$ssh_connection - # fi - # unset MATCH MBEGIN MEND - # fi - - # hostname='%F{$prompt_pure_colors[host]}@%m%f' - # # Show `username@host` if logged in through SSH. - # [[ -n $ssh_connection ]] && username='%F{$prompt_pure_colors[user]}%n%f'"$hostname" - - # # Show `username@host` if root, with username in default color. - # [[ $UID -eq 0 ]] && username='%F{$prompt_pure_colors[user:root]}%n%f'"$hostname" - typeset -gA prompt_pure_state prompt_pure_state[version]="1.11.0" prompt_pure_state+=( @@ -707,22 +663,22 @@ prompt_pure_setup() { prompt_pure_colors_default=( execution_time yellow git:arrow cyan - git:branch 242 + git:branch 246 git:branch:cached red git:action 242 - git:dirty 218 - host 242 + git:dirty red + host 015 path blue prompt:error red prompt:success magenta prompt:continuation 242 user 242 - user:root default + user:root 190 virtualenv 242 - aws yellow + aws green aws:prod red - ) + prompt_pure_colors=("${(@kv)prompt_pure_colors_default}") add-zsh-hook precmd prompt_pure_precmd From ac211c4db0cd387394a3ac67ccbcd1651cf53667 Mon Sep 17 00:00:00 2001 From: Andrea Mistrali Date: Thu, 13 Feb 2020 11:17:51 +0100 Subject: [PATCH 3/5] SSH title support --- zsh.d/prompts/pure/pure.zsh | 45 +++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/zsh.d/prompts/pure/pure.zsh b/zsh.d/prompts/pure/pure.zsh index f62a67a..2a4a79b 100644 --- a/zsh.d/prompts/pure/pure.zsh +++ b/zsh.d/prompts/pure/pure.zsh @@ -621,6 +621,51 @@ prompt_pure_reset_vim_prompt_widget() { } prompt_pure_state_setup() { + setopt localoptions noshwordsplit + + # Check SSH_CONNECTION and the current state. + local ssh_connection=${SSH_CONNECTION:-$PROMPT_PURE_SSH_CONNECTION} + local username hostname + + if [[ -z $ssh_connection ]] && (( $+commands[who] )); then + # When changing user on a remote system, the $SSH_CONNECTION + # environment variable can be lost. Attempt detection via `who`. + local who_out + who_out=$(who -m 2>/dev/null) + if (( $? )); then + # Who am I not supported, fallback to plain who. + local -a who_in + who_in=( ${(f)"$(who 2>/dev/null)"} ) + who_out="${(M)who_in:#*[[:space:]]${TTY#/dev/}[[:space:]]*}" + fi + + local reIPv6='(([0-9a-fA-F]+:)|:){2,}[0-9a-fA-F]+' # Simplified, only checks partial pattern. + local reIPv4='([0-9]{1,3}\.){3}[0-9]+' # Simplified, allows invalid ranges. + # Here we assume two non-consecutive periods represents a + # hostname. This matches `foo.bar.baz`, but not `foo.bar`. + local reHostname='([.][^. ]+){2}' + + # Usually the remote address is surrounded by parenthesis, but + # not on all systems (e.g. busybox). + local -H MATCH MBEGIN MEND + if [[ $who_out =~ "\(?($reIPv4|$reIPv6|$reHostname)\)?\$" ]]; then + ssh_connection=$MATCH + + # Export variable to allow detection propagation inside + # shells spawned by this one (e.g. tmux does not always + # inherit the same tty, which breaks detection). + export PROMPT_PURE_SSH_CONNECTION=$ssh_connection + fi + unset MATCH MBEGIN MEND + fi + + hostname='%F{$prompt_pure_colors[host]}@%m%f' + # Show `username@host` if logged in through SSH. + [[ -n $ssh_connection ]] && username='%F{$prompt_pure_colors[user]}%n%f'"$hostname" + + # # Show `username@host` if root, with username in default color. + # [[ $UID -eq 0 ]] && username='%F{$prompt_pure_colors[user:root]}%n%f'"$hostname" + typeset -gA prompt_pure_state prompt_pure_state[version]="1.11.0" prompt_pure_state+=( From 336ec45d1f4669a2bdd175803a6d8643a5be9046 Mon Sep 17 00:00:00 2001 From: Andrea Mistrali Date: Thu, 13 Feb 2020 11:21:04 +0100 Subject: [PATCH 4/5] SSH title support, 2nd --- zsh.d/prompts/pure/pure.zsh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/zsh.d/prompts/pure/pure.zsh b/zsh.d/prompts/pure/pure.zsh index 2a4a79b..007518d 100644 --- a/zsh.d/prompts/pure/pure.zsh +++ b/zsh.d/prompts/pure/pure.zsh @@ -149,7 +149,8 @@ prompt_pure_preprompt_render() { [[ $UID -eq 0 ]] && preprompt_parts+='%F{$prompt_pure_colors[user:root]}'"⚡" - [[ ! -z $SSH_CONNECTION ]] && preprompt_parts+='%F{$prompt_pure_colors[host]}'"@%m" + [[ -n $prompt_pure_state[username] ]] && preprompt_parts+='%F{$prompt_pure_colors[host]}'"@%m" + # [[ ! -z $SSH_CONNECTION ]] && preprompt_parts+='%F{$prompt_pure_colors[host]}'"@%m" prompt_pure_set_aws if [[ ! -z $prompt_pure_aws ]]; then From bed12353a990cc775aa9c0653dea1eabc821cbf6 Mon Sep 17 00:00:00 2001 From: Andrea Mistrali Date: Thu, 13 Feb 2020 11:25:25 +0100 Subject: [PATCH 5/5] Title and host --- zsh.d/prompts/pure/pure.zsh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zsh.d/prompts/pure/pure.zsh b/zsh.d/prompts/pure/pure.zsh index 007518d..feccea8 100644 --- a/zsh.d/prompts/pure/pure.zsh +++ b/zsh.d/prompts/pure/pure.zsh @@ -149,7 +149,7 @@ prompt_pure_preprompt_render() { [[ $UID -eq 0 ]] && preprompt_parts+='%F{$prompt_pure_colors[user:root]}'"⚡" - [[ -n $prompt_pure_state[username] ]] && preprompt_parts+='%F{$prompt_pure_colors[host]}'"@%m" + [[ -n $prompt_pure_state[username] ]] && preprompt_parts+='%F{$prompt_pure_colors[host]}'"|%m|" # [[ ! -z $SSH_CONNECTION ]] && preprompt_parts+='%F{$prompt_pure_colors[host]}'"@%m" prompt_pure_set_aws