From c5e63fec2cda9dce6f867a51af1991b175f66baa Mon Sep 17 00:00:00 2001 From: Michael Lamparski Date: Sat, 24 Jul 2021 20:52:02 -0400 Subject: [PATCH] refactor prompt, work around pyenv perf nightmares --- shell/bashrc.include | 47 ++++++++++++++++++++++--------------- shell/bashrc.prompt.d/git | 3 +-- shell/bashrc.prompt.d/pyenv | 13 +++++----- shell/colors.include | 12 ---------- shell/colors.ps1.include | 22 +++++++++++++++++ shell/common.include | 15 ++++++++++++ 6 files changed, 73 insertions(+), 39 deletions(-) delete mode 100644 shell/colors.include create mode 100644 shell/colors.ps1.include diff --git a/shell/bashrc.include b/shell/bashrc.include index 188ef2d..eb3267c 100644 --- a/shell/bashrc.include +++ b/shell/bashrc.include @@ -2,10 +2,18 @@ # To be source'd in .bashrc +# running 'which' can actually get pretty expensive (especially on wsl2) so we cache these +which git 1>/dev/null 2>/dev/null && __EXPHP_BASH_PROMPT__HAS_GIT=1 + +# FIXME: this currently always fails due to initialization order (common.include runs after this) +which pyenv 1>/dev/null 2>/dev/null && __EXPHP_BASH_PROMPT__HAS_PYENV=1 + # Wrap in a function so that `local` can be used. # Awkwardly long name to avoid collision. -doTheSpecialPromptyThing() {( # scope the colors - . $HOME/dotfiles/shell/colors.include +__exphpBashrcPromptCommand() { + local __PREV_EXIT_CODE="$?" # This needs to be first + + . $HOME/dotfiles/shell/colors.ps1.include --local local lbrace="$white[" local rbrace="$white]" @@ -25,10 +33,15 @@ doTheSpecialPromptyThing() {( # scope the colors dd-win10\ ; do [[ $HOSTNAME == $tmp ]] && my_machine=1; done - # == STATIC REGION == - # no command substitutions may be used before the error indicator, - # to ensure that the value of $? is preserved. + # == RESET == PS1="" + + # == PYENV == + if [[ $__EXPHP_BASH_PROMPT__HAS_PYENV ]]; then + PS1+="$($HOME/dotfiles/shell/bashrc.prompt.d/pyenv)" + fi + + # == MAIN STUFF == PS1+="$lbrace " if [[ $my_machine ]]; then # Username & Time @@ -46,15 +59,15 @@ doTheSpecialPromptyThing() {( # scope the colors PS1+=" $rbrace " # == ERROR INDICATOR == - PS1+="\$(if [[ \$? != 0 ]];" - PS1+="then echo \"($red!!!$white) \"; " - PS1+="fi)" + if [[ $__PREV_EXIT_CODE -ne 0 ]]; then + PS1+="($red!!!$white) " + fi # == DYNAMIC REGION == - PS1+="\$( - \$HOME/dotfiles/shell/bashrc.prompt.d/pyenv - \$HOME/dotfiles/shell/bashrc.prompt.d/git - )" + # Git branch + if [[ $__EXPHP_BASH_PROMPT__HAS_GIT ]]; then + PS1+="$($HOME/dotfiles/shell/bashrc.prompt.d/git)" + fi # Current directory PS1+="$green\w$none" @@ -62,13 +75,9 @@ doTheSpecialPromptyThing() {( # scope the colors # Prompt on newline PS1+="\n" PS1+="${white}\\\$${none} " - echo "$PS1" # let it escape the subshell -)} - -PS1=$(doTheSpecialPromptyThing) +} -# cleanup -unset -f doTheSpecialPromptyThing +PROMPT_COMMAND=__exphpBashrcPromptCommand __bashrc__is_bash_ge() { local maj @@ -105,5 +114,5 @@ else # Add to the history after each command finishes NEWLINE=$'\n' - PROMPT_COMMAND="history -a $NEWLINE $PROMPT_COMMAND" + PROMPT_COMMAND="$PROMPT_COMMAND $NEWLINE history -a" fi diff --git a/shell/bashrc.prompt.d/git b/shell/bashrc.prompt.d/git index 205055d..7288b99 100755 --- a/shell/bashrc.prompt.d/git +++ b/shell/bashrc.prompt.d/git @@ -1,7 +1,6 @@ #!/usr/bin/env bash -which git 1>/dev/null 2>/dev/null || exit 0 -. $HOME/dotfiles/shell/colors.include +. $HOME/dotfiles/shell/colors.ps1.include . $HOME/dotfiles/shell/gittool.ps1.include # compute git status into GITTOOL variables if [[ $EXPHP_GITTOOL_BRANCH ]]; then echo -n "$none(" diff --git a/shell/bashrc.prompt.d/pyenv b/shell/bashrc.prompt.d/pyenv index ffdbc26..4b3c70e 100755 --- a/shell/bashrc.prompt.d/pyenv +++ b/shell/bashrc.prompt.d/pyenv @@ -1,10 +1,11 @@ #!/usr/bin/env bash -which pyenv 1>/dev/null 2>/dev/null || exit 0 +. $HOME/dotfiles/shell/colors.ps1.include -. $HOME/dotfiles/shell/colors.include - -version=$(pyenv version-name) -if [[ "$version" != 'system' ]]; then - echo -n "(${cyan}$version${none}${bold}) ${none}" +# DO NOT USE 'pyenv version-name' +# IT IS SO SLOW +# YOU WILL MAKE YOUR PROMPT SO SLOW +version=$PYENV_VERSION +if [[ $version && "$version" != 'system' ]]; then + echo -n "(${cyan}$version${none}) ${none}" fi diff --git a/shell/colors.include b/shell/colors.include deleted file mode 100644 index a8df076..0000000 --- a/shell/colors.include +++ /dev/null @@ -1,12 +0,0 @@ -# these will be global so you should probably be in a subshell or a non-sourced script when -# you source this - -none=$'\033[00m' -bold=$'\033[01m' -red=$'\033[01;31m' -green=$'\033[01;32m' -yellow=$'\033[01;33m' -blue=$'\033[01;34m' -purple=$'\033[01;35m' -cyan=$'\033[01;36m' -white=$'\033[01;37m' diff --git a/shell/colors.ps1.include b/shell/colors.ps1.include new file mode 100644 index 0000000..d282e52 --- /dev/null +++ b/shell/colors.ps1.include @@ -0,0 +1,22 @@ +if [[ $1 == "--local" ]]; then + # Note: The \[ and \] are PS1 stuff to fix the positioning when using escape codes. + local none='\['$'\033[00m''\]' + local bold='\['$'\033[01m''\]' + local red='\['$'\033[01;31m''\]' + local green='\['$'\033[01;32m''\]' + local yellow='\['$'\033[01;33m''\]' + local blue='\['$'\033[01;34m''\]' + local purple='\['$'\033[01;35m''\]' + local cyan='\['$'\033[01;36m''\]' + local white='\['$'\033[01;37m''\]' +else + none='\['$'\033[00m''\]' + bold='\['$'\033[01m''\]' + red='\['$'\033[01;31m''\]' + green='\['$'\033[01;32m''\]' + yellow='\['$'\033[01;33m''\]' + blue='\['$'\033[01;34m''\]' + purple='\['$'\033[01;35m''\]' + cyan='\['$'\033[01;36m''\]' + white='\['$'\033[01;37m''\]' +fi diff --git a/shell/common.include b/shell/common.include index 93e5f6b..b8d22e6 100644 --- a/shell/common.include +++ b/shell/common.include @@ -173,8 +173,23 @@ if [ -e $HOME/asd/manage/pyenv ]; then # pyenv startup part 2: The part that actually belongs in .bashrc eval "$(pyenv init -)" eval "$(pyenv virtualenv-init -)" + + # _pyenv_virtualenv_hook makes the shell absurdly slow so get rid of it + # https://github.com/pyenv/pyenv-virtualenv/issues/259 + # + # Warning: unloading the following hook breaks command + # `pyenv activate/deactivate`. Please switch to + # `pyenv shell env_name`, `pyenv shell --unset` instead. + if [[ -n $ZSH_VERSION ]]; then + autoload -Uz add-zsh-hook + add-zsh-hook -D precmd _pyenv_virtualenv_hook + fi + if [[ -n $BASH_VERSION ]]; then + PROMPT_COMMAND="${PROMPT_COMMAND/_pyenv_virtualenv_hook;/}" + fi fi + # # Bumper rail. # # Limit memory for interactive bash prompts, because thrashing sucks. # # To bypass, invoke 'nolimit' from *outside* of a bash process.