From 0772e1850820e5e1bac2dbff880b0ac17386c9c9 Mon Sep 17 00:00:00 2001 From: Iain Patterson Date: Sat, 12 May 2018 16:06:47 +0100 Subject: [PATCH] Split PS1 components into .ps1 files. --- .profile.d/ps1.bashrc | 156 +++++++++++++++++++++++++----------------- .ps1.d/git.ps1 | 16 +++++ .ps1.d/p4.ps1 | 15 ++++ .ps1.d/svn.ps1 | 15 ++++ 4 files changed, 141 insertions(+), 61 deletions(-) create mode 100644 .ps1.d/git.ps1 create mode 100644 .ps1.d/p4.ps1 create mode 100644 .ps1.d/svn.ps1 diff --git a/.profile.d/ps1.bashrc b/.profile.d/ps1.bashrc index 991095b..e7d3658 100644 --- a/.profile.d/ps1.bashrc +++ b/.profile.d/ps1.bashrc @@ -1,29 +1,57 @@ #!bash Coloured prompts. # profile-required: TERM.bashrc # -# The prompt comprises multiple parts, some of which may be hidden by unsetting +# The prompt comprises multiple parts, some of which may be hidden by unsetting # shell variables or using the ``prompt'' function. # -# The first part of the prompt is user@host where host is highlighted in +# The first part of the prompt is user@host where host is highlighted in # green if the last command exited 0 or in red otherwise. # This part will be shown only if __ps1_user is 1. By default it is 1. -# The success and failure colours can be changed by modifying +# The success and failure colours can be changed by modifying # $PROMPT_OK_COLOUR and $PROMPT_FAILED_COLOUR respectively. # -# The second part of the prompt is taken from git-completion.bashrc. -# It is shown only if __ps1_git is 1. By default it is 0. +# Subsequent parts are taken from *.ps1 files in the .ps1.d directory. +# Each file .ps1 should contain: +# * A line __ps1_=${__ps1_:-X} where X is 0 or 1 to activate +# the plugin by default (or not). +# * A function __ps1_() which returns the text to be displayed. +# The function will be passed the return code of the last command as its +# first argument and should return the same code. +# The function should print nothing unless __ps1_ is 1. +# The function should call "__ps1_prefix $1 __ps1_" to retrieve a +# prefix string. When the string is non-empty, it should be printed before +# any output from the plugin itself. Doing so will ensure that the text is +# formatted correctly regardless of whether other parts of the prompt are +# being shown. +# * One to three lines __ps1__colour256, __ps1__colour88 and +# __ps1__colour setting the colour for the plugin. +# The plugin should not emit ANSI colour sequences itself. PS1 needs to wrap +# all escape sequences with the literal strings \[ and \] but these must be +# embedded directly into the prompt and not evaluated programmatically. +# Omitting them will cause the terminal to redraw incorrectly under certain +# circumstances. Trying to include them in a function will not work. +# Instead the plugin should define at least __ps1__colour. The +# colour will be generated before any text from the plugin is printed. +# To handle 88- and 256-colour terminals, the plugin may also declare +# __ps1__colour88 and/or __ps1__colour256. # -# The third part of the prompt is taken from p4-completion.bashrc. -# It is shown only if __ps1_p4 is 1. By default it is 0. +# Example plugin code: # -# The fourth part of the prompt is taken from svn-completion.bashrc. -# It is shown only if __ps1_svn is 1. By default it is 0. +# __ps1_example_colour='0;33' # -# The fifth part of the prompt is the exit status of the last command. -# This part will be shown only if __ps1_user is set and the exit status is +# function __ps1_example() { +# if [ -n "$__ps1_example" ]; then +# echo -n "$(__ps1_prefix $1 __ps1_example)" +# echo -n "example!" +# fi +# return $1 +# } +# +# The next part of the prompt is the exit status of the last command. +# This part will be shown only if __ps1_user is set and the exit status is # non-zero. # -# The sixth part of the prompt is the number of background jobs managed +# The penultimate part of the prompt is the number of background jobs managed # by the shell, in square brackets. If all background jobs are running, # their number will be shown as [n]. If some are stopped, the number of # running (r) and total (t) jobs will be shown as [r/t]. @@ -34,66 +62,89 @@ # modifying $ROOT_OK_COLOUR and $ROOT_FAILED_COLOUR. # # Colouring is performed by the __ps1_col() and __ps1_ret() functions. -# We redirect stderr to /dev/null when calling these functions to prevent -# bash complaining about not knowing them when you su to another user, +# We redirect stderr to /dev/null when calling these functions to prevent +# bash complaining about not knowing them when you su to another user, # retaining PS1 but not the function definitions. # -# Note that $? is passed as an argument to - and is returned from - all -# functions. As $? is set following any shell activity it is only guaranteed +# Note that $? is passed as an argument to - and is returned from - all +# functions. As $? is set following any shell activity it is only guaranteed # to represent the return code of the last command at the beginning of __ps1(). -# By passing between subsequent functions we ensure that it is available for +# By passing between subsequent functions we ensure that it is available for # __ps1_ret(). # # Pick a colour based on the terminal capabilities. # OK: dark green. # Failed: dark red. -# Git: royal blue. -# P4: yellow. -# SVN: magenta. case $(tput colors) in 256) + __ps1_colours=256 PROMPT_BACKGROUND_COLOUR="0;48;5;26" PROMPT_OK_COLOUR="1;38;5;34" PROMPT_FAILED_COLOUR="1;38;5;160" ROOT_OK_COLOUR="0" ROOT_FAILED_COLOUR="0" - GIT_COLOUR="0;38;5;33" - SVN_COLOUR="0;38;5;127" - P4_COLOUR="0;38;5;142" ;; 88) + __ps1_colours=88 PROMPT_BACKGROUND_COLOUR="0;48;5;18" PROMPT_OK_COLOUR="1;38;5;24" PROMPT_FAILED_COLOUR="1;38;5;48" ROOT_OK_COLOUR="0" ROOT_FAILED_COLOUR="0" - GIT_COLOUR="0;38;5;23" - SVN_COLOUR="0;38;5;49" - P4_COLOUR="0;38;5;56" ;; *) + __ps1_colours= PROMPT_BACKGROUND_COLOUR="0;44" PROMPT_OK_COLOUR="1;32" PROMPT_FAILED_COLOUR="1;31" ROOT_OK_COLOUR="0" ROOT_FAILED_COLOUR="0" - GIT_COLOUR="0;36" - SVN_COLOUR="0;35" - P4_COLOUR="0;33" ;; esac +__ps1_all='$__ps1_user' + function __ps1() { # Default __ps1_user to 1. [ -z "$__ps1_user" ] && __ps1_user=1 - PS1='\[\033[$(__ps1_background $?)m\]$(__ps1_user $? \u@)\[\033[$(__ps1_col $? 2>/dev/null)m\]$(__ps1_user $? \h)\[\033[$(__ps1_colour_escape $? $GIT_COLOUR $PROMPT_BACKGROUND_COLOUR)m\]$(__ps1_git $? 2>/dev/null)\[\033[0m\]\[\033[$(__ps1_colour_escape $? $P4_COLOUR $PROMPT_BACKGROUND_COLOUR)m\]$(__ps1_p4 $? 2>/dev/null)\[\033[0m\]\[\033[$(__ps1_colour_escape $? $SVN_COLOUR $PROMPT_BACKGROUND_COLOUR)m\]$(__ps1_svn $? 2>/dev/null)\[\033[$(__ps1_background $?)m\]$(__ps1_ret $? 2>/dev/null)$(__ps1_bg $?)$(__ps1_colon $?)$(__ps1_short $?)\[\033[$(__ps1_root $? 2>/dev/null)m\]\$\[\033[0m\] ' + local pre='\[\033[$(__ps1_background $?)m\]$(__ps1_user $? \u@)\[\033[$(__ps1_col $? 2>/dev/null)m\]$(__ps1_user $? \h)\[\033[0m\]' + local post='\[\033[$(__ps1_background $?)m\]$(__ps1_ret $? 2>/dev/null)$(__ps1_bg $?)$(__ps1_colon $?)$(__ps1_short $?)\[\033[$(__ps1_root $? 2>/dev/null)m\]\$\[\033[0m\] ' + local snippets='' + local snippet= + for snippet in ${PROFILE_HOME:-~}/.ps1.d/*.ps1; do + . $snippet + local name=${snippet##*/} + name=__ps1_${name%.ps1} + __ps1_all="$__ps1_all\$$name" + snippets="$snippets"'\[$(__ps1_colour_start $? '"$name"')\]$('"$name"' $? $__ps1_all 2>/dev/null)\[$(__ps1_colour_end $? '"$name"')\]' + done + PS1=$pre$snippets$post + return 0 } +function __ps1_colour_for() { + local colour= + local ret= + for colour in "${1}_colour${__ps1_colours}" "${1}_colour"; do + ret=$(eval echo -n "\$$colour") + [ -n "$ret" ] && break + done + echo -n $ret +} + +function __ps1_prefix() { + local var=\$${2#\$} + local prefix=${__ps1_all%$var*} + local all="$(eval echo $prefix)" + [ "${all/1/}" = "$all" ] || echo -n " " + return $1 +} + # iTerm doesn't like it if you set bold and colour at the same time. function __ps1_colour_escape() { local ret=$1; shift @@ -106,6 +157,19 @@ function __ps1_colour_escape() { return $ret } +function __ps1_colour_start() { + local colour=$(__ps1_colour_for $2) + echo -en '\033[' + __ps1_colour_escape 0 "$colour" "$PROMPT_BACKGROUND_COLOUR" + echo -n m + return $1 +} + +function __ps1_colour_end() { + [ -n "$(__ps1_colour_for $2)" ] && echo -en '\033[0m' + return $1 +} + function __ps1_background() { local ret=$1; shift echo -n "0" @@ -146,36 +210,6 @@ function __ps1_user() { return $ret } -function __ps1_git() { - [ "$__ps1_git" = "1" ] || return $1 - if [ "$__ps1_user" = "1" ]; then - __git_ps1 ' %s' - else - __git_ps1 '%s' - fi - return $1 -} - -function __ps1_p4() { - [ "$__ps1_p4" = "1" ] || return $1 - if [ "$__ps1_user" = "1" -o "$__ps1_git" = "1" ]; then - __p4_ps1 ' %s' - else - __p4_ps1 '%s' - fi - return $1 -} - -function __ps1_svn() { - [ "$__ps1_svn" = "1" ] || return $1 - if [ "$__ps1_user" = "1" -o "$__ps1_git" = "1" -o "$__ps1_p4" = "1" ]; then - __svn_ps1 ' %s' - else - __svn_ps1 '%s' - fi - return $1 -} - function __ps1_bg() { [ "$__ps1_bg" = "1" ] || return $1 local job @@ -194,7 +228,7 @@ function __ps1_bg() { } function __ps1_colon() { - local all="$__ps1_user$__ps1_git$__ps1_p4$__ps1_svn$(__ps1_bg $1 1)" + local all="$__ps1_user$(eval echo $__ps1_all)$(__ps1_bg $1 1)" [ "${all/1/}" = "$all" ] || echo -n ":" return $1 } diff --git a/.ps1.d/git.ps1 b/.ps1.d/git.ps1 new file mode 100644 index 0000000..64e2fa7 --- /dev/null +++ b/.ps1.d/git.ps1 @@ -0,0 +1,16 @@ +#!bash + +# This part of the prompt is taken from git-completion.bashrc. +# It is shown only if __ps1_git is 1. By default it is 0. + +__ps1_git=${__ps1_git:-0} +__ps1_git_colour256="0;38;5;33" +__ps1_git_colour88="0;38;5;23" +__ps1_git_colour="0;36" + +function __ps1_git() { + [ "$__ps1_git" = "1" ] || return $1 + __git_ps1 "$(__ps1_prefix $1 __ps1_git)"'%s' + return $1 +} + diff --git a/.ps1.d/p4.ps1 b/.ps1.d/p4.ps1 new file mode 100644 index 0000000..109eb34 --- /dev/null +++ b/.ps1.d/p4.ps1 @@ -0,0 +1,15 @@ +#!/bash + +# This part of the prompt is taken from p4-completion.bashrc. +# It is shown only if __ps1_p4 is 1. By default it is 0. + +__ps1_p4=${__ps1_p4:-0} +__ps1_p4_colour256="0;38;5;142" +__ps1_p4_colour88="0;38;5;56" +__ps1_p4_colour="0;33" + +function __ps1_p4() { + [ "$__ps1_p4" = "1" ] || return $1 + __p4_ps1 "$(__ps1_prefix $1 __ps1_p4)"'%s' + return $1 +} diff --git a/.ps1.d/svn.ps1 b/.ps1.d/svn.ps1 new file mode 100644 index 0000000..0f93a37 --- /dev/null +++ b/.ps1.d/svn.ps1 @@ -0,0 +1,15 @@ +#!/bash + +# This part of the prompt is taken from svn-completion.bashrc. +# It is shown only if __ps1_svn is 1. By default it is 0. + +__ps1_svn=${__ps1_svn:-0} +__ps1_svn_colour256="0;38;5;127" +__ps1_svn_colour88="0;38;5;49" +__ps1_svn_colour="0;35" + +function __ps1_svn() { + [ "$__ps1_svn" = "1" ] || return $1 + __svn_ps1 "$(__ps1_prefix $1 __ps1_svn)"'%s' + return $1 +} -- 2.20.1