b.liu | e958203 | 2025-04-17 19:18:16 +0800 | [diff] [blame] | 1 | #!/bin/bash |
| 2 | ############################################################################### |
| 3 | # IDENTIFICATION OF LOCAL HOST: CHANGE TO YOUR COMPUTER NAME |
| 4 | ############################################################################### |
| 5 | |
| 6 | |
| 7 | PRIMARYHOST="localhost" |
| 8 | |
| 9 | ############################################################################### |
| 10 | # PROMPT |
| 11 | ############################################################################### |
| 12 | |
| 13 | ############################################################################### |
| 14 | # Terminal Title |
| 15 | |
| 16 | set_terminal_title() { |
| 17 | if [[ -z $@ ]] |
| 18 | then |
| 19 | TERMINAL_TITLE=$(pwd -P) |
| 20 | else |
| 21 | TERMINAL_TITLE=$@ |
| 22 | fi |
| 23 | } |
| 24 | alias stt='set_terminal_title' |
| 25 | alarm() { perl -e 'alarm shift; exec @ARGV' "$@"; } |
| 26 | |
| 27 | STANDARD_PROMPT_COMMAND='history -a ; echo -ne "\033]0;${TERMINAL_TITLE}\007"' |
| 28 | PROMPT_COMMAND=$STANDARD_PROMPT_COMMAND |
| 29 | |
| 30 | ############################################################################### |
| 31 | # Parses Git info for prompt |
| 32 | |
| 33 | function _set_git_envar_info { |
| 34 | GIT_BRANCH="" |
| 35 | GIT_HEAD="" |
| 36 | GIT_STATE="" |
| 37 | GIT_LEADER="" |
| 38 | GIT_ROOT="" |
| 39 | GIT_REPO="" |
| 40 | GIT_ACTION="" |
| 41 | |
| 42 | if [[ $(which git 2>/dev/null) ]] |
| 43 | then |
| 44 | |
| 45 | local IS_GIT |
| 46 | IS_GIT=$(\git rev-parse --show-toplevel 2>/dev/null) |
| 47 | if [[ -z $IS_GIT ]] |
| 48 | then |
| 49 | return |
| 50 | fi |
| 51 | |
| 52 | GIT_ROOT=./$(\git rev-parse --show-cdup 2>/dev/null) |
| 53 | GIT_GIT=$(\git rev-parse --git-dir 2>/dev/null) |
| 54 | |
| 55 | local STATUS |
| 56 | # STATUS=$(\git status 2>/dev/null) |
| 57 | STATUS=$(alarm 3 \git status 2>/dev/null) |
| 58 | if [[ -z $STATUS ]] |
| 59 | then |
| 60 | STATUS="alarmed" |
| 61 | fi |
| 62 | |
| 63 | GIT_LEADER=":" |
| 64 | GIT_BRANCH="$(\git branch --no-color 2>/dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/\1/')" |
| 65 | GIT_HEAD=":$(\git log -n1 --pretty=format:%h 2>/dev/null)" |
| 66 | GIT_REPO="$(\git rev-parse --show-toplevel 2>/dev/null | awk -F/ '{print $NF}')" |
| 67 | |
| 68 | if [[ "$STATUS" == *'working directory clean'* ]] |
| 69 | then |
| 70 | GIT_STATE="" |
| 71 | else |
| 72 | GIT_HEAD=$GIT_HEAD":" |
| 73 | GIT_STATE="" |
| 74 | if [[ "$STATUS" == *'Changes to be committed:'* ]] |
| 75 | then |
| 76 | GIT_STATE=$GIT_STATE'+I' # Index has files staged for commit |
| 77 | fi |
| 78 | if [[ "$STATUS" == *'Changed but not updated:'* || "$STATUS" == *'Changes not staged for commit'* ]] |
| 79 | then |
| 80 | GIT_STATE=$GIT_STATE"+M" # Working tree has files modified but unstaged |
| 81 | fi |
| 82 | if [[ "$STATUS" == *'Untracked files:'* ]] |
| 83 | then |
| 84 | GIT_STATE=$GIT_STATE'+U' # Working tree has untracked files |
| 85 | fi |
| 86 | if [[ "$STATUS" == *'alarmed'* ]] |
| 87 | then |
| 88 | GIT_STATE=$GIT_STATE'*' # too much time to proceed status |
| 89 | fi |
| 90 | GIT_STATE=$GIT_STATE'' |
| 91 | fi |
| 92 | |
| 93 | if [ -f "$GIT_GIT/rebase-merge/interactive" ]; then |
| 94 | GIT_ACTION="REBASE-i" |
| 95 | elif [ -d "$GIT_GIT/rebase-merge" ]; then |
| 96 | GIT_ACTION="REBASE-m" |
| 97 | else |
| 98 | if [ -d "$GIT_GIT/rebase-apply" ]; then |
| 99 | if [ -f "$GIT_GIT/rebase-apply/rebasing" ]; then |
| 100 | GIT_ACTION="REBASE" |
| 101 | elif [ -f "$GIT_GIT/rebase-apply/applying" ]; then |
| 102 | GIT_ACTION="AM" |
| 103 | else |
| 104 | GIT_ACTION="AM/REBASE" |
| 105 | fi |
| 106 | elif [ -f "$GIT_GIT/MERGE_HEAD" ]; then |
| 107 | GIT_ACTION="MERGING" |
| 108 | elif [ -f "$GIT_GIT/BISECT_LOG" ]; then |
| 109 | GIT_ACTION="BISECTING" |
| 110 | fi |
| 111 | fi |
| 112 | |
| 113 | if [ ! -z "$GIT_ACTION" ]; then |
| 114 | GIT_ACTION="|"$GIT_ACTION |
| 115 | fi |
| 116 | |
| 117 | fi |
| 118 | |
| 119 | } |
| 120 | |
| 121 | ############################################################################### |
| 122 | # Composes prompt. |
| 123 | function setps1 { |
| 124 | |
| 125 | # Help message. |
| 126 | # local USAGE="Usage: setps1 [none] [screen=<0|1>] [user=<0|1>] [dir=<0|1|2>] [git=<0|1>] [wrap=<0|1>] [which-python=<0|1>]" |
| 127 | |
| 128 | if [[ (-z $@) || ($@ == "*-h*") || ($@ == "*--h*") ]] |
| 129 | then |
| 130 | echo $USAGE |
| 131 | return |
| 132 | fi |
| 133 | |
| 134 | # Prompt colors. |
| 135 | local CLEAR="\[\033[0m\]" |
| 136 | local STY_COLOR='\[\033[1;37;41m\]' |
| 137 | local PROMPT_COLOR='\[\033[1;94m\]' |
| 138 | local USER_HOST_COLOR='\[\033[1;30m\]' |
| 139 | local PROMPT_DIR_COLOR='\[\033[1;94m\]' |
| 140 | local GIT_LEADER_COLOR='\[\033[1;30m\]' |
| 141 | local GIT_BRANCH_COLOR=$CLEAR'\[\033[1;90m\]\[\033[4;90m\]' |
| 142 | local GIT_HEAD_COLOR=$CLEAR'\[\033[1;32m\]' |
| 143 | local GIT_STATE_COLOR=$CLEAR'\[\033[1;31m\]' |
| 144 | |
| 145 | # Hostname-based colors in prompt. |
| 146 | if [[ $HOSTNAME != $PRIMARYHOST ]] |
| 147 | then |
| 148 | USER_HOST_COLOR=$REMOTE_USER_HOST_COLOR |
| 149 | fi |
| 150 | |
| 151 | # Start with empty prompt. |
| 152 | local PROMPTSTR="" |
| 153 | |
| 154 | # Set screen session id. |
| 155 | if [[ $@ == *screen=1* ]] |
| 156 | then |
| 157 | ## Decorate prompt with indication of screen session ## |
| 158 | if [[ -z "$STY" ]] # if screen session variable is not defined |
| 159 | then |
| 160 | local SCRTAG="" |
| 161 | else |
| 162 | local SCRTAG="$STY_COLOR(STY ${STY%%.*})$CLEAR" # get screen session number |
| 163 | fi |
| 164 | fi |
| 165 | |
| 166 | # Set user@host. |
| 167 | # if [[ $@ == *user=1* ]] |
| 168 | # then |
| 169 | # PROMPTSTR=$PROMPTSTR"$USER_HOST_COLOR\\u@\\h$CLEAR" |
| 170 | # fi |
| 171 | |
| 172 | # Set directory. |
| 173 | if [[ -n $PROMPTSTR && ($@ == *dir=1* || $@ == *dir=2*) ]] |
| 174 | then |
| 175 | PROMPTSTR=$PROMPTSTR"$PROMPT_COLOR:" |
| 176 | fi |
| 177 | |
| 178 | if [[ $@ == *dir=1* ]] |
| 179 | then |
| 180 | #PROMPTSTR=$PROMPTSTR"$PROMPT_DIR_COLOR\W$CLEAR" |
| 181 | PROMPTSTR=$PROMPTSTR"$PROMPT_DIR_COLOR\$GIT_REPO$CLEAR" |
| 182 | elif [[ $@ == *dir=2* ]] |
| 183 | then |
| 184 | PROMPTSTR=$PROMPTSTR"$PROMPT_DIR_COLOR\$(pwd -P)$CLEAR" |
| 185 | fi |
| 186 | |
| 187 | # if [[ $@ == *dir=1* ]] |
| 188 | # then |
| 189 | # PROMPTSTR=$PROMPTSTR"$PROMPT_DIR_COLOR\W$CLEAR" |
| 190 | # elif [[ $@ == *dir=2* ]] |
| 191 | # then |
| 192 | # PROMPTSTR=$PROMPTSTR"$PROMPT_DIR_COLOR\w$CLEAR" |
| 193 | # fi |
| 194 | # |
| 195 | # Set git. |
| 196 | if [[ $@ == *git=1* ]] |
| 197 | then |
| 198 | PROMPT_COMMAND="$STANDARD_PROMPT_COMMAND && _set_git_envar_info" |
| 199 | PROMPTSTR=$PROMPTSTR"$BG_COLOR$GIT_LEADER_COLOR\$GIT_LEADER$GIT_BRANCH_COLOR" |
| 200 | PROMPTSTR=$PROMPTSTR"\$GIT_BRANCH$GIT_HEAD_COLOR\$GIT_HEAD$GIT_STATE_COLOR\$GIT_STATE\$GIT_ACTION$CLEAR" |
| 201 | else |
| 202 | PROMPT_COMMAND=$STANDARD_PROMPT_COMMAND |
| 203 | fi |
| 204 | |
| 205 | # Set wrap. |
| 206 | if [[ $@ == *wrap=1* ]] |
| 207 | then |
| 208 | local WRAP="$CLEAR\n" |
| 209 | else |
| 210 | local WRAP="" |
| 211 | fi |
| 212 | |
| 213 | # Set wrap. |
| 214 | if [[ $@ == *which-python=1* ]] |
| 215 | then |
| 216 | local WHICHPYTHON="$CLEAR\n(python is '\$(which python)')$CLEAR\n" |
| 217 | else |
| 218 | local WHICHPYTHON="" |
| 219 | fi |
| 220 | |
| 221 | # Finalize. |
| 222 | if [[ -z $PROMPTSTR || $@ == none ]] |
| 223 | then |
| 224 | PROMPTSTR="\$ " |
| 225 | else |
| 226 | PROMPTSTR="$TITLEBAR\n$SCRTAG${PROMPT_COLOR}[$CLEAR$PROMPTSTR$PROMPT_COLOR]$WRAP$WHICHPYTHON$PROMPT_COLOR\$$CLEAR " |
| 227 | fi |
| 228 | |
| 229 | # Set. |
| 230 | PS1="\[\e]0;\w\a\]\n\[\e[32m\]\u@\h \[\e[33m\]\w\[\e[0m\]$PROMPTSTR" |
| 231 | PS2='> ' |
| 232 | PS4='+ ' |
| 233 | } |
| 234 | |
| 235 | alias setps1-long='setps1 screen=1 user=1 dir=2 git=1 wrap=1' |
| 236 | alias setps1-short='setps1 screen=1 user=1 dir=1 git=1 wrap=0' |
| 237 | alias setps1-default='setps1-short' |
| 238 | alias setps1-plain='setps1 screen=0 user=0 dir=0 git=0 wrap=0' |
| 239 | alias setps1-nogit='setps1 screen=0 user=1 dir=1 git=0 wrap=0' |
| 240 | alias setps1-local-long='setps1 screen=1 user=0 dir=2 git=1 wrap=1' |
| 241 | alias setps1-local-short='setps1 screen=0 user=0 dir=1 git=1 wrap=0' |
| 242 | alias setps1-local='setps1-local-short' |
| 243 | alias setps1-dev-short='setps1 screen=0 user=0 dir=1 git=1 wrap=0 which-python=1' |
| 244 | alias setps1-dev-long='setps1 screen=0 user=1 dir=2 git=1 wrap=0 which-python=1' |
| 245 | alias setps1-dev-remote='setps1 screen=0 user=1 dir=1 git=1 wrap=0 which-python=1' |
| 246 | if [[ "$HOSTNAME" = "$PRIMARYHOST" ]] |
| 247 | then |
| 248 | setps1 screen=0 user=0 dir=1 git=1 wrap=0 which-python=0 |
| 249 | else |
| 250 | setps1 screen=1 user=1 dir=1 git=1 wrap=0 which-python=0 |
| 251 | fi |