-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathprompt_command
137 lines (124 loc) · 5.51 KB
/
prompt_command
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#!/bin/bash
# -----------------------------------------------------------------------------
# Author: Paul Weaver ([email protected])
#
# Assign the prompt_command function defined below to the PROMPT_COMMAND
# environment variable in your .bashrc/.bash_profile to get a pretty prompt
# containing a bunch of information.
#
# Note: I don't provide a warranty of any kind with this software! On the plus
# side, however, please feel free to distribute this file to your friends,
# family, pets etc. (So long as you keep this attribution)
# -----------------------------------------------------------------------------
# NOTE colours will just fail silently if not present aside from the intial
# warning that .bash_colours is missing.
source $HOME/.bash_colors
function _padding {
# Creates a string of spaces of the passed size
local size=$1
local result
printf -v result "%${size}s" ' '
echo "$result"
}
function _repeat_chars {
# Creates a string of <size> repeats of <char>
local char=$1
local size=$2
local temp_str=$(_padding ${size})
echo ${temp_str// /${char}}
}
if ! __git_ps1 &> /dev/null; then
# Redefine __git_ps1 to print a helpful warning if it's not installed
function __git_ps1 {
echo '[Install __git_ps1]'
}
fi
function prompt_command {
# Must be the first thing we do, otherwise other exit statuses overwrite $?
local exit_status=$?
if [[ $exit_status == 0 ]]; then
local exit_status_text=${BGreen}✓${Color_Off}
else
local exit_status_text=${BRed}✗${Color_Off}
fi
# Must run this early because when we use $() this adds to our jobs count
local total_jobs=$(jobs | wc -l | perl -pe 's/\s+//g')
local stopped_jobs=$(jobs -s | wc -l | perl -pe 's/\s+//g')
if [[ ${total_jobs} != 0 ]]; then
if [[ ${stopped_jobs} == 0 ]]; then
local jobs_text="${LightGray}[${total_jobs}] ${Color_Off}"
else
local jobs_text="${LightGray}[${BRed}${stopped_jobs}${LightGray}/${total_jobs}] ${Color_Off}"
fi
fi
local hostname=`hostname -s`
local username=$(whoami)
local host_text=${username}@${hostname}
local virtual_env_text=""
if [[ -n $VIRTUAL_ENV ]]; then
virtual_env_text="${DarkGray} $(basename $VIRTUAL_ENV)${Color_Off}"
fi
local git_text git_ahead
if git branch &> /dev/null; then
# git is working and we're on a git branch
if [[ "$(__git_ps1)" =~ 'GIT_DIR!' ]]; then
# we're in the git directory!
git_text="${Purple}$(__git_ps1) ${Color_Off}"
else
if git status | grep "nothing to commit" > /dev/null 2>&1; then
# Clean repository - nothing to commit
git_text="${Green} $(__git_ps1 "(%s)") ${Color_Off}"
elif git status | grep "nothing added to commit but untracked files present" > /dev/null 2>&1; then
# No changes but files to add
git_text="${Cyan} $(__git_ps1 "[%s]") ${Color_Off}"
else
# Changes to working tree
git_text="${Red} $(__git_ps1 "{%s}") ${Color_Off}"
fi
git_ahead=$(git status | awk '/Your branch is ahead/{print "→" $8 " "}\
/Your branch is behind/{print $7 "← "}\
/diverged/,/respectively/{if ($0 ~ /respectively/) print $5 "←→" $3 " "}')
git_text="${git_text}${Yellow}${git_ahead%→*}${Red}${git_ahead#*←}${Color_Off}"
fi
else
# prompt component when not in git
git_text=' '
fi
local date_text=${DarkGray}$(date +%H:%M)${Color_Off}
local prompt_char=${exit_status_text}
local pwd_text="$(pwd | perl -pe "s|^$HOME|~|")"
local tmux_text tmux_session tmux_group num_tmux_attached_clients
local num_tmux_group_clients num_tmux_clients
if which tmux &> /dev/null && [[ -n $TMUX ]]; then
tmux_session=$(tmux display-message -p '#S')
num_tmux_attached_clients=$(tmux list-clients -t ${tmux_session} | wc -l)
tmux_group=$(tmux list-sessions | grep "^${tmux_session}:" | grep -o "(group [0-9]*)" | grep -o "[0-9]*")
num_tmux_group_clients=$(tmux list-sessions | grep "group ${tmux_group}" | wc -l)
# The main session will be counted in both attached clients and groups:
# FIXME: this seems to be bad now?!
#let num_tmux_group_clients-=1
num_tmux_clients=$((${num_tmux_attached_clients} + ${num_tmux_group_clients}))
if [[ ${num_tmux_clients} -gt 1 ]]; then
tmux_text="${Yellow}⎚ ${num_tmux_clients} ${Color_Off}"
fi
fi
local remove_color_codes_regex="s/\\\\\[\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]\\\\\]//g"
local length_elements=$(echo -e "${pwd_text}${virtual_env_text}${git_text}${tmux_text}${jobs_text}${date_text}" | perl -pe $remove_color_codes_regex)
local rule_length=$(($COLUMNS - ${#length_elements} - 1))
local rule
if [[ ${rule_length} -gt 0 ]]; then
# Everything fits on the info line
rule="${DarkGray}$(_repeat_chars '─' ${rule_length}) "
elif [[ ${rule_length} == 0 ]]; then
# Everything JUST fits on the info line
rule=""
else
# We need to truncate our path because the info line is too short
pwd_text="…${pwd_text:$((${rule_length} * -1))}"
rule=""
fi
pwd_text=${BBlue}${pwd_text}${Color_Off}
local line_1="${pwd_text}${virtual_env_text}${git_text}${rule}${tmux_text}${jobs_text}${date_text}"
local line_2="${host_text} ${prompt_char} "
PS1="\n${line_1}\n${line_2}"
}