prompt 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. ##### My (demuredemeanor) bashrc sub source prompt script
  2. # Uses tabstop=4; shiftwidth=4 tabs; foldmarker={{{,}}};
  3. # https://notabug.org/demure/dotfiles/
  4. # legacy repo http://github.com/demure/dotfiles
  5. # vim:set syntax=sh:
  6. ### This Changes The PS1 ### {{{
  7. export PROMPT_COMMAND=__prompt_command # Func to gen PS1 after CMDs
  8. function __prompt_command() {
  9. local EXIT="$?" # This needs to be first
  10. PS1=""
  11. ### Colors to Vars ### {{{
  12. ## Inspired by http://wiki.archlinux.org/index.php/Color_Bash_Prompt#List_of_colors_for_prompt_and_Bash
  13. ## Terminal Control Escape Sequences: http://www.termsys.demon.co.uk/vtansi.htm
  14. ## Consider using some of: https://gist.github.com/bcap/5682077#file-terminal-control-sh
  15. ## Can unset with `unset -v {,B,U,I,BI,On_,On_I}{Bla,Red,Gre,Yel,Blu,Pur,Cya,Whi} RCol`
  16. local RCol='\[\e[0m\]' # Text Reset
  17. # Regular Bold Underline High Intensity BoldHigh Intensity Background High Intensity Backgrounds
  18. local Bla='\[\e[0;30m\]'; local BBla='\[\e[1;30m\]'; local UBla='\[\e[4;30m\]'; local IBla='\[\e[0;90m\]'; local BIBla='\[\e[1;90m\]'; local On_Bla='\e[40m'; local On_IBla='\[\e[0;100m\]';
  19. local Red='\[\e[0;31m\]'; local BRed='\[\e[1;31m\]'; local URed='\[\e[4;31m\]'; local IRed='\[\e[0;91m\]'; local BIRed='\[\e[1;91m\]'; local On_Red='\e[41m'; local On_IRed='\[\e[0;101m\]';
  20. local Gre='\[\e[0;32m\]'; local BGre='\[\e[1;32m\]'; local UGre='\[\e[4;32m\]'; local IGre='\[\e[0;92m\]'; local BIGre='\[\e[1;92m\]'; local On_Gre='\e[42m'; local On_IGre='\[\e[0;102m\]';
  21. local Yel='\[\e[0;33m\]'; local BYel='\[\e[1;33m\]'; local UYel='\[\e[4;33m\]'; local IYel='\[\e[0;93m\]'; local BIYel='\[\e[1;93m\]'; local On_Yel='\e[43m'; local On_IYel='\[\e[0;103m\]';
  22. local Blu='\[\e[0;34m\]'; local BBlu='\[\e[1;34m\]'; local UBlu='\[\e[4;34m\]'; local IBlu='\[\e[0;94m\]'; local BIBlu='\[\e[1;94m\]'; local On_Blu='\e[44m'; local On_IBlu='\[\e[0;104m\]';
  23. local Pur='\[\e[0;35m\]'; local BPur='\[\e[1;35m\]'; local UPur='\[\e[4;35m\]'; local IPur='\[\e[0;95m\]'; local BIPur='\[\e[1;95m\]'; local On_Pur='\e[45m'; local On_IPur='\[\e[0;105m\]';
  24. local Cya='\[\e[0;36m\]'; local BCya='\[\e[1;36m\]'; local UCya='\[\e[4;36m\]'; local ICya='\[\e[0;96m\]'; local BICya='\[\e[1;96m\]'; local On_Cya='\e[46m'; local On_ICya='\[\e[0;106m\]';
  25. local Whi='\[\e[0;37m\]'; local BWhi='\[\e[1;37m\]'; local UWhi='\[\e[4;37m\]'; local IWhi='\[\e[0;97m\]'; local BIWhi='\[\e[1;97m\]'; local On_Whi='\e[47m'; local On_IWhi='\[\e[0;107m\]';
  26. ### End Color Vars ### }}}
  27. if [ $UID -eq "0" ];then
  28. PS1+="${Red}\h \W ->${RCol} " ## Set prompt for root
  29. else
  30. local PSCol="" ## Declare so null var fine
  31. local PSOpt="" ## Above, and fixes repeat issue
  32. if [ $EXIT != 0 ]; then
  33. ## can add `kill -l $?` to test to filter backgrounded
  34. PS1+="${Red}${EXIT}${RCol}" ## Add exit code, if non 0
  35. fi
  36. ### Machine Test ### {{{
  37. if [ $HOSTNAME == 'moving-computer-of-doom' ]; then
  38. local PSCol="$Cya" ## For Main Computer
  39. elif [ $HOSTNAME == 'vps-of-doom' ]; then
  40. local PSCol="$Blu" ## For VPS
  41. elif [ $HOSTNAME == 'ma.sdf.org' ]; then
  42. local PSCol="${Yel}" #@ For MetaArray
  43. local PSOpt="\h "
  44. elif [ $HOSTNAME == 'fencepost.gnu.org' ]; then
  45. local PSCol="${On_Pur}" ## For Gnu
  46. local PSOpt="\h "
  47. elif [ $HOSTTYPE == 'arm' ]; then
  48. local PSCol="$Gre" #@ For pi
  49. elif [[ $MACHTYPE =~ arm-apple-darwin ]]; then
  50. local PSCol="$Gre" ## For iOS
  51. elif [ $MACHTYPE == 'i486-pc-linux-gnu' ]; then
  52. local PSCol="$BBla" ## For Netbook
  53. elif [[ "$MACHTYPE" == "x86_64--netbsd" && "$OSTYPE" == "netbsd" ]]; then
  54. local PSCol="${Yel}" ## For Main Cluster
  55. local PSOpt="\h "
  56. elif [ "$MACHTYPE" == "mips-openwrt-linux-gnu" ]; then
  57. local PSCol="${On_Pur}" ## For OpenWrt
  58. local PSOpt="\h "
  59. else
  60. local PSCol="${Pur}" ## Un-designated catch-all
  61. local PSOpt="\h "
  62. MISSING_ITEMS+="machine-prompt, "
  63. fi
  64. ### End Machine Test ### }}}
  65. PS1+="${PSCol}${PSOpt}\W${RCol}" ## Current working dir
  66. ### Check Jobs ### {{{
  67. type jobs &>/dev/null
  68. if [ $? == "0" ]; then
  69. ## Backgrounded running jobs
  70. local BKGJBS=$(jobs -r | wc -l | tr -d ' ')
  71. if [ ${BKGJBS} -gt 2 ]; then
  72. PS1+=" ${Red}[bg:${BKGJBS}]${RCol}"
  73. elif [ ${BKGJBS} -gt 0 ]; then
  74. PS1+=" ${Yel}[bg:${BKGJBS}]${RCol}"
  75. fi
  76. ## Stopped Jobs
  77. local STPJBS=$(jobs -s | wc -l | tr -d ' ')
  78. if [ ${STPJBS} -gt 2 ]; then
  79. PS1+=" ${Red}[stp:${STPJBS}]${RCol}"
  80. elif [ ${STPJBS} -gt 0 ]; then
  81. PS1+=" ${Yel}[stp:${STPJBS}]${RCol}"
  82. fi
  83. fi
  84. ### End Jobs ### }}}
  85. ### Add Git Status ### {{{
  86. ## Inspired by http://www.terminally-incoherent.com/blog/2013/01/14/whats-in-your-bash-prompt/
  87. if [[ $(command -v git) ]]; then
  88. local GStat="$(git status --porcelain -b 2>/dev/null | tr '\n' ':')"
  89. if [ "$GStat" ]; then
  90. ### Fetch Time Check ### {{{
  91. local LAST=$(stat -c %Y $(git rev-parse --git-dir 2>/dev/null)/FETCH_HEAD 2>/dev/null)
  92. if [ "${LAST}" ]; then
  93. local TIME=$(echo $(date +"%s") - ${LAST} | bc)
  94. ## Check if more than 60 minutes since last
  95. if [ "${TIME}" -gt "3600" ]; then
  96. git fetch 2>/dev/null
  97. PS1+=' +'
  98. ## Refresh var
  99. local GStat="$(git status --porcelain -b 2>/dev/null | tr '\n' ':')"
  100. fi
  101. fi
  102. ### End Fetch Check ### }}}
  103. ### Test For Changes ### {{{
  104. ## Change this to test for 'ahead' or 'behind'!
  105. local GChanges="$(echo ${GStat} | tr ':' '\n' | grep -v "^$" | grep -v "^\#\#" | wc -l | tr -d ' ')"
  106. if [ "$GChanges" == "0" ]; then
  107. local GitCol=$Gre
  108. else
  109. local GitCol=$Red
  110. fi
  111. ### End Test Changes ### }}}
  112. ### Find Branch ### {{{
  113. local GBra="$(echo ${GStat} | tr ':' '\n' | grep "^##" | cut -c4- | grep -o "^[a-zA-Z0-9_-]\{1,\}[^\.]")"
  114. if [ "$GBra" ]; then
  115. if [ "$GBra" == "master" ]; then
  116. local GBra="M" ## Because why waste space
  117. fi
  118. else
  119. local GBra="ERROR" ## It could happen supposedly?
  120. fi
  121. ### End Branch ### }}}
  122. PS1+=" ${GitCol}[$GBra]${RCol}" ## Add result to prompt
  123. ### Find Commit Status ### {{{
  124. ## Test Modified and Untracked for "0"
  125. # local GDel="$(echo ${GStat} | tr ':' '\n' | grep -c "^[ MARC]D")"
  126. local GAhe="$(echo ${GStat} | tr ':' '\n' | grep "^##" | grep -o "ahead [0-9]\{1,\}" | grep -o "[0-9]\{1,\}")"
  127. if [ "$GAhe" ]; then
  128. PS1+="${Gre}↑${RCol}${GAhe}" ## Ahead
  129. fi
  130. ## Needs a `git fetch`
  131. local GBeh="$(echo ${GStat} | tr ':' '\n' | grep "^##" | grep -o "behind [0-9]\{1,\}" | grep -o "[0-9]\{1,\}")"
  132. if [ "$GBeh" ]; then
  133. PS1+="${Red}↓${RCol}${GBeh}" ## Behind
  134. fi
  135. local GMod="$(echo ${GStat} | tr ':' '\n' | grep -c "^[ MARC]M")"
  136. if [ "$GMod" -gt "0" ]; then
  137. PS1+="${Pur}≠${RCol}${GMod}" ## Modified
  138. fi
  139. local GUnt="$(echo ${GStat} | tr ':' '\n' | grep -c "^\?")"
  140. if [ "$GUnt" -gt "0" ]; then
  141. PS1+="${Yel}?${RCol}${GUnt}" ## Untracked
  142. fi
  143. ### End Commit Status ### }}}
  144. fi
  145. else
  146. MISSING_ITEMS+="git-prompt, "
  147. fi
  148. ### End Git Status ### }}}
  149. PS1+=" ${PSCol}-> ${RCol}" ## End of PS1
  150. fi
  151. }
  152. ### End PS1 ### }}}