diff options
author | dakkar <dakkar@thenautilus.net> | 2012-07-16 20:44:14 +0100 |
---|---|---|
committer | dakkar <dakkar@thenautilus.net> | 2012-07-16 20:44:14 +0100 |
commit | 0239c7c44bb6c4b3516ec73d3677559a8a546c76 (patch) | |
tree | 3916f749a7fa0f61ce488fc6eb10c6a1259f5682 /git-prompt.sh | |
parent | s/``/"$()"/g — always show rc & jobs (diff) | |
parent | fixed: filenames with special chars (diff) | |
download | git-prompt-0239c7c44bb6c4b3516ec73d3677559a8a546c76.tar.gz git-prompt-0239c7c44bb6c4b3516ec73d3677559a8a546c76.tar.bz2 git-prompt-0239c7c44bb6c4b3516ec73d3677559a8a546c76.zip |
Merge branch 'master' into dakkar
Diffstat (limited to 'git-prompt.sh')
-rwxr-xr-x | git-prompt.sh | 221 |
1 files changed, 145 insertions, 76 deletions
diff --git a/git-prompt.sh b/git-prompt.sh index dc2a2d1..3fac2f0 100755 --- a/git-prompt.sh +++ b/git-prompt.sh @@ -1,4 +1,3 @@ - # don't set prompt if this is not interactive shell [[ $- != *i* ]] && return @@ -6,8 +5,9 @@ ##### read config file if any. - unset dir_color rc_color jobs_color prompt_color user_id_color root_id_color init_vcs_color clean_vcs_color - unset modified_vcs_color added_vcs_color addmoded_vcs_color untracked_vcs_color op_vcs_color detached_vcs_color + unset dir_color rc_color jobs_color prompt_color user_id_color root_id_color init_vcs_color clean_vcs_color + unset modified_vcs_color added_vcs_color addmoded_vcs_color untracked_vcs_color op_vcs_color detached_vcs_color hex_vcs_color + unset rawhex_len conf=git-prompt.conf; [[ -r $conf ]] && . $conf conf=/etc/git-prompt.conf; [[ -r $conf ]] && . $conf @@ -15,12 +15,14 @@ conf=~/.config/git-prompt.conf; [[ -r $conf ]] && . $conf unset conf + ##### set defaults if not set git_module=${git_module:-on} svn_module=${svn_module:-off} hg_module=${hg_module:-on} vim_module=${vim_module:-on} + virtualenv_module=${virtualenv_module:-on} error_bell=${error_bell:-off} cwd_cmd=${cwd_cmd:-\\w} @@ -32,6 +34,7 @@ rc_color=${rc_color:-red} jobs_color=${jobs_color:-cyan} prompt_color=${prompt_color:-CYAN} + virtualenv_color=${virtualenv_color:-green} user_id_color=${user_id_color:-blue} root_id_color=${root_id_color:-magenta} else # only B/W @@ -44,7 +47,7 @@ prompt_char="${prompt_char:-'>'}" root_prompt_char="${root_prompt_char:-'>'}" - #### vcs state colors + #### vcs colors init_vcs_color=${init_vcs_color:-WHITE} # initial clean_vcs_color=${clean_vcs_color:-blue} # nothing to commit (working directory clean) modified_vcs_color=${modified_vcs_color:-red} # Changed but not updated: @@ -54,8 +57,14 @@ op_vcs_color=${op_vcs_color:-MAGENTA} detached_vcs_color=${detached_vcs_color:-RED} + hex_vcs_color=${hex_vcs_color:-BLACK} # gray + + max_file_list_length=${max_file_list_length:-100} + short_hostname=${short_hostname:-off} upcase_hostname=${upcase_hostname:-on} + count_only=${count_only:-off} + rawhex_len=${rawhex_len:-5} aj_max=${aj_max:-20} @@ -110,9 +119,11 @@ YELLOW='\['"$(tput setaf 3; tput bold)"'\]' BLUE='\['"$(tput setaf 4; tput bold)"'\]' MAGENTA='\['"$(tput setaf 5; tput bold)"'\]' - CYAN='\['"$(tput setaf 6; tput bold)"'\]' # why 14 doesn't work? + CYAN='\['"$(tput setaf 6; tput bold)"'\]' WHITE='\['"$(tput setaf 7; tput bold)"'\]' + dim='\['"$(tput sgr0; tput setaf p1)"'\]' # half-bright + bw_bold='\['"$(tput bold)"'\]' on='' @@ -129,6 +140,7 @@ op_vcs_color=${!op_vcs_color} addmoded_vcs_color=${!addmoded_vcs_color} detached_vcs_color=${!detached_vcs_color} + hex_vcs_color=${!hex_vcs_color} unset PROMPT_COMMAND @@ -142,7 +154,7 @@ #################################################################### MARKERS screen_marker="sCRn" - if [[ $(locale|grep LC_CTYPE) =~ "UTF" && $TERM != "linux" ]]; then + if [[ "$LC_CTYPE $LC_ALL" =~ "UTF" && $TERM != "linux" ]]; then elipses_marker="…" else elipses_marker="..." @@ -192,7 +204,7 @@ cwd_truncate() { # trunc middle if over limit if [[ ${#path_middle} -gt $(( $cwd_middle_max + ${#elipses_marker} + 5 )) ]]; then - + # truncate middle_tail="${path_middle:${#path_middle}-${cwd_middle_max}}" @@ -213,31 +225,37 @@ cwd_truncate() { set_shell_label() { - xterm_label() { echo -n "]2;${@}" ; } # FIXME: replace hardcodes with terminfo codes + xterm_label() { + local args="$*" + echo -n "]2;${args:0:200}" ; # FIXME: replace hardcodes with terminfo codes + } screen_label() { # FIXME: run this only if screen is in xterm (how to test for this?) - xterm_label "$screen_marker $plain_who_where $@" + xterm_label "$screen_marker $plain_who_where $@" # FIXME $STY not inherited though "su -" [ "$STY" ] && screen -S $STY -X title "$*" } + if [[ -n "$STY" ]]; then + screen_label "$*" + else + case $TERM in - case $TERM in + screen*) + screen_label "$*" + ;; - screen*) - screen_label "$*" - ;; + xterm* | rxvt* | gnome-* | konsole | eterm | wterm ) + # is there a capability which we can to test + # for "set term title-bar" and its escapes? + xterm_label "$plain_who_where $@" + ;; - xterm* | rxvt* | gnome-terminal | konsole | eterm | wterm ) - # is there a capability which we can to test - # for "set term title-bar" and its escapes? - xterm_label "$plain_who_where $@" - ;; - - *) - ;; - esac + *) + ;; + esac + fi } export -f set_shell_label @@ -263,7 +281,7 @@ set_shell_label() { # we don't need tty name under X11 case $TERM in - xterm* | rxvt* | gnome-terminal | konsole | eterm | wterm ) unset tty ;; + xterm* | rxvt* | gnome-terminal | konsole | eterm* | wterm | cygwin) unset tty ;; *);; esac @@ -271,6 +289,7 @@ set_shell_label() { rc_color=${!rc_color} prompt_color=${!prompt_color} jobs_color=${!jobs_color} + virtualenv_color=${!virtualenv_color} user_id_color=${!user_id_color} root_id_color=${!root_id_color} @@ -284,9 +303,15 @@ set_shell_label() { #then host=${HOSTNAME} - #host="$(hostname --short)" + if [[ $short_hostname = "on" ]]; then + if [[ "$(uname)" =~ "CYGWIN" ]]; then + host="$(hostname)" + else + host="$(hostname -s)" + fi + fi host=${host#$default_host} - uphost="$(echo ${host} | tr a-z A-Z)" + uphost="$(echo ${host} | tr a-z-. A-Z_)" if [[ $upcase_hostname = "on" ]]; then host=${uphost} fi @@ -294,7 +319,7 @@ set_shell_label() { host_color=${uphost}_host_color host_color=${!host_color} if [[ -z $host_color && -x /usr/bin/cksum ]] ; then - cksum_color_no="$(echo $uphost | cksum | awk '{print $1%7}')" + cksum_color_no="$(echo $uphost | cksum | awk '{print $1%6}')" color_index=(green yellow blue magenta cyan white) # FIXME: bw, color-256 host_color=${color_index[cksum_color_no]} fi @@ -304,7 +329,6 @@ set_shell_label() { # we might already have short host name host=${host%.$default_domain} - #################################################################### WHO_WHERE # [[user@]host[-tty]] @@ -361,8 +385,7 @@ parse_svn_status() { parse_hg_status() { # ☿ - - [[ -d ./.hg/ ]] || return 1 + hg_root=`hg root 2>/dev/null` || return 1 vcs=hg @@ -380,11 +403,17 @@ parse_hg_status() { branch="$(hg branch 2> /dev/null)" + [[ -f $hg_root/.hg/bookmarks.current ]] && bookmark=`cat "$hg_root/.hg/bookmarks.current"` + [[ -z $modified ]] && [[ -z $untracked ]] && [[ -z $added ]] && clean=clean vcs_info=${branch/default/D} + if [[ "$bookmark" ]] ; then + vcs_info+=/$bookmark + fi } + parse_git_status() { # TODO add status: LOCKED (.git/index.lock) @@ -396,46 +425,52 @@ parse_git_status() { [[ -n ${git_dir/./} ]] || return 1 vcs=git - #parse_git_complete ########################################################## GIT STATUS - file_regex='\([^/]*\/\?\).*' added_files=() modified_files=() untracked_files=() + [[ $rawhex_len -gt 0 ]] && freshness="$dim=" + unset branch status modified added clean init added mixed untracked op detached - # quoting hell + # info not in porcelain status eval " $( git status 2>/dev/null | sed -n ' s/^# On branch /branch=/p - s/^nothing to commit (working directory clean)/clean=clean/p - s/^# Initial commit/init=init/p - - /^# Changes to be committed:/,/^# [A-Z]/ { - s/^# Changes to be committed:/added=added;/p - - s/^# modified: '"$file_regex"'/ [[ \" ${added_files[*]} \" =~ \" \1 \" ]] || added_files[${#added_files[@]}]=\"\1\"/p - s/^# new file: '"$file_regex"'/ [[ \" ${added_files[*]} \" =~ \" \1 \" ]] || added_files[${#added_files[@]}]=\"\1\"/p - s/^# renamed:[^>]*> '"$file_regex"'/ [[ \" ${added_files[*]} \" =~ \" \1 \" ]] || added_files[${#added_files[@]}]=\"\1\"/p - s/^# copied:[^>]*> '"$file_regex"'/ [[ \" ${added_files[*]} \" =~ \" \1 \" ]] || added_files[${#added_files[@]}]=\"\1\"/p - } - - /^# Changed but not updated:/,/^# [A-Z]/ { - s/^# Changed but not updated:/modified=modified;/p - s/^# modified: '"$file_regex"'/ [[ \" ${modified_files[*]} \" =~ \" \1 \" ]] || modified_files[${#modified_files[@]}]=\"\1\"/p - s/^# unmerged: '"$file_regex"'/ [[ \" ${modified_files[*]} \" =~ \" \1 \" ]] || modified_files[${#modified_files[@]}]=\"\1\"/p - } - - /^# Untracked files:/,/^[^#]/{ - s/^# Untracked files:/untracked=untracked;/p - s/^# '"$file_regex"'/ [[ \" ${untracked_files[*]} ${modified_files[*]} ${added_files[*]} \" =~ \" \1 \" ]] || untracked_files[${#untracked_files[@]}]=\"\1\"/p - } + s/^nothing to commi.*/clean=clean/p + s/^# Initial commi.*/init=init/p + s/^# Your branch is ahead of \(.\).\+\1 by [[:digit:]]\+ commit.*/freshness=${WHITE}↑/p + s/^# Your branch is behind \(.\).\+\1 by [[:digit:]]\+ commit.*/freshness=${YELLOW}↓/p + s/^# Your branch and \(.\).\+\1 have diverged.*/freshness=${YELLOW}↕/p ' )" - if ! grep -q "^ref:" $git_dir/HEAD 2>/dev/null; then + # porcelain file list + # TODO: sed-less -- http://tldp.org/LDP/abs/html/arrays.html -- Example 27-5 + + # git bug: (was reported to git@vger.kernel.org ) + # echo 1 > "with space" + # git status --porcelain + # ?? with space <------------ NO QOUTES + # git add with\ space + # git status --porcelain + # A "with space" <------------- WITH QOUTES + + eval " $( + git status --porcelain 2>/dev/null | + sed -n ' + s,^[MARC]. \([^\"][^/]*/\?\).*, added=added; [[ \" ${added_files[@]} \" =~ \" \1 \" ]] || added_files[${#added_files[@]}]=\"\1\",p + s,^[MARC]. \"\([^/]\+/\?\).*\"$, added=added; [[ \" ${added_files[@]} \" =~ \" \1 \" ]] || added_files[${#added_files[@]}]=\"\1\",p + s,^.[MAU] \([^\"][^/]*/\?\).*, modified=modified; [[ \" ${modified_files[@]} \" =~ \" \1 \" ]] || modified_files[${#modified_files[@]}]=\"\1\",p + s,^.[MAU] \"\([^/]\+/\?\).*\"$, modified=modified; [[ \" ${modified_files[@]} \" =~ \" \1 \" ]] || modified_files[${#modified_files[@]}]=\"\1\",p + s,^?? \([^\"][^/]*/\?\).*, untracked=untracked; [[ \" ${untracked_files[@]} \" =~ \" \1 \" ]] || untracked_files[${#untracked_files[@]}]=\"\1\",p + s,^?? \"\([^/]\+/\?\).*\"$, untracked=untracked; [[ \" ${untracked_files[@]} \" =~ \" \1 \" ]] || untracked_files[${#untracked_files[@]}]=\"\1\",p + ' # |tee /dev/tty + )" + + if ! grep -q "^ref:" "$git_dir/HEAD" 2>/dev/null; then detached=detached fi @@ -482,12 +517,16 @@ parse_git_status() { #### GET GIT HEX-REVISION - rawhex="$(git rev-parse HEAD 2>/dev/null)" - rawhex="${rawhex/HEAD/}" - rawhex="${rawhex:0:6}" + if [[ $rawhex_len -gt 0 ]] ; then + rawhex="$(git rev-parse HEAD 2>/dev/null)" + rawhex=${rawhex/HEAD/} + rawhex="$hex_vcs_color${rawhex:0:$rawhex_len}" + else + rawhex="" + fi #### branch - branch="${branch/master/M}" + branch=${branch/#master/M} # another method of above: # branch=$(git symbolic-ref -q HEAD || { echo -n "detached:" ; git name-rev --name-only HEAD 2>/dev/null; } ) @@ -496,7 +535,7 @@ parse_git_status() { ### compose vcs_info if [[ $init ]]; then - vcs_info=M$white=init + vcs_info=${white}init else if [[ "$detached" ]] ; then @@ -510,7 +549,7 @@ parse_git_status() { fi #branch="<$branch>" fi - vcs_info="$branch$white=$rawhex" + vcs_info="$branch$freshness$rawhex" fi } @@ -554,23 +593,33 @@ parse_vcs_status() { eval $old_nullglob if [[ $vim_glob ]]; then - vim_file=${vim_glob#.} - vim_file=${vim_file/.sw?/} + set $vim_glob + #vim_file=${vim_glob#.} + if [[ $# > 1 ]] ; then + vim_files="*" + else + vim_file=${1#.} + vim_file=${vim_file/.sw?/} + [[ .${vim_file}.swp -nt $vim_file ]] && vim_files=$vim_file + fi # if swap is newer, then this is unsaved vim session - #[[ .${vim_file}.swp -nt $vim_file ]] && vim_files=$vim_file # [temoto custom] if swap is older, then it must be deleted, so show all swaps. - vim_files=$vim_file fi fi ### file list unset file_list - [[ ${added_files[0]} ]] && file_list+=" "$added_vcs_color${added_files[@]} - [[ ${modified_files[0]} ]] && file_list+=" "$modified_vcs_color${modified_files[@]} - [[ ${untracked_files[0]} ]] && file_list+=" "$untracked_vcs_color${untracked_files[@]} - [[ ${vim_files} ]] && file_list+=" "${RED}VIM:${vim_files} - file_list=${file_list:+:$file_list} + if [[ $count_only = "on" ]] ; then + [[ ${added_files[0]} ]] && file_list+=" "${added_vcs_color}+${#added_files[@]} + [[ ${modified_files[0]} ]] && file_list+=" "${modified_vcs_color}*${#modified_files[@]} + [[ ${untracked_files[0]} ]] && file_list+=" "${untracked_vcs_color}?${#untracked_files[@]} + else + [[ ${added_files[0]} ]] && file_list+=" "$added_vcs_color${added_files[@]} + [[ ${modified_files[0]} ]] && file_list+=" "$modified_vcs_color${modified_files[@]} + [[ ${untracked_files[0]} ]] && file_list+=" "$untracked_vcs_color${untracked_files[@]} + fi + [[ ${vim_files} ]] && file_list+=" "${MAGENTA}vim:${vim_files} if [[ ${#file_list} -gt $max_file_list_length ]] ; then file_list=${file_list:0:$max_file_list_length} @@ -580,7 +629,7 @@ parse_vcs_status() { fi - head_local="(${vcs_info}$vcs_color${file_list}$vcs_color)" + head_local="$vcs_color(${vcs_info}$vcs_color${file_list}$vcs_color)" ### fringes head_local="${head_local+$vcs_color$head_local }" @@ -588,11 +637,22 @@ parse_vcs_status() { #tail_local="${tail_local+$vcs_color $tail_local}${dir_color}" } +parse_virtualenv_status() { + unset virtualenv + + [[ $virtualenv_module = "on" ]] || return 1 + + if [[ -n "$VIRTUAL_ENV" ]] ; then + virtualenv=`basename $VIRTUAL_ENV` + rc="$rc $virtualenv_color<$virtualenv> " + fi + } + disable_set_shell_label() { trap - DEBUG >& /dev/null } -# enable stuffing currently executed command displays in label +# show currently executed command in label enable_set_shell_label() { disable_set_shell_label # check for BASH_SOURCE being empty, no point running set_shell_label on every line of .bashrc @@ -600,19 +660,27 @@ enable_set_shell_label() { set_shell_label "$BASH_COMMAND"' DEBUG >& /dev/null } +declare -ft disable_set_shell_label +declare -ft enable_set_shell_label + # autojump (see http://wiki.github.com/joelthelion/autojump) + +# TODO reverse the line order of a file +#awk ' { line[NR] = $0 } +# END { for (i=NR;i>0;i--) +# print line[i] }' listlogs + j (){ : ${1? usage: j dir-beginning} # go in ring buffer starting from current index. cd to first matching dir - for (( i=(aj_idx+1)%aj_max; i != aj_idx%aj_max; i=++i%aj_max )) ; do - #echo == ${aj_dir_list[$i]} == $i + for (( i=(aj_idx-1)%aj_max; i != aj_idx%aj_max; i=(--i+aj_max)%aj_max )) ; do if [[ ${aj_dir_list[$i]} =~ ^.*/$1[^/]*$ ]] ; then cd "${aj_dir_list[$i]}" return fi done echo '?' -} + } alias jumpstart='echo ${aj_dir_list[@]}' @@ -626,6 +694,7 @@ prompt_command_function() { cwd="${PWD/$HOME/~}" # substitute "~" set_shell_label "${cwd##[/~]*/}/" # default label - path last dir + parse_virtualenv_status parse_vcs_status # autojump @@ -642,7 +711,7 @@ prompt_command_function() { PS1="$colors_reset$color_who_where$dir_color$cwd $head_local\n$colors_reset$rc$jobs$prompt_color$prompt_char $colors_reset" unset head_local tail_local pwd -} + } PROMPT_COMMAND=prompt_command_function |