# Licence : WTFPL
# Les sections commentées par #~# sont des features qui ne sont pas activées
-# par défaut. Sentez-vous libre de les décommenter pour les utiliser.
+# par défaut. Sentez-vous libre de les décommenter pour les utiliser.
#------------------------------------------------------------------------------
# ils seront chargés par la ligne suivante
[ -d ~/.bash_completion.d/ ] && for f in ~/.bash_completion.d/*; do source $f; done
-
# +-----+
# | VCS |
# +-----+
# Définition de fonction pour pouvoir afficher dans le prompt
# des infos quand on est dans un dépôt versionné
-find_up () {
- local path normalized_path normalized_ret
- path="$1"
- shift 1
- normalized_path=`readlink -f -- "$path"`
- normalized_ret=$?
- while [[ "$normalized_path" != "/" ]] && [ $normalized_ret -eq 0 ];
- do
- find "$path" -maxdepth 1 -mindepth 1 "$@"
- path=${path}/..
- normalized_path=`readlink -f -- "$path"`
- normalized_ret=$?
- done
+# Checks if the command provided is in the commands list and is
+# executable
+check_command(){
+ [[ -n ${commands[$1]} ]] && [ -x ${commands[$1]} ] && return 0
+ return 1
}
-get_vcs_info () {
- # Donne les infos sur le dépôt VCS courant.
- local LBRANCH LTYPE BRANCH TYPE DIR
- declare -a DIR
- declare -A TYPE
- declare -A BRANCH
- DIR[0]=".git"
- DIR[1]=".hg"
- DIR[2]="_darcs"
- DIR[3]=".svn"
- TYPE[.git]="git"
- TYPE[.hg]="mercurial"
- TYPE[_darcs]="darcs"
- TYPE[.svn]="svn"
- BRANCH[.git]='git branch 2>/dev/null | sed -r "s/^[^*].*$//" | paste -s -d "" | sed -r "s/^[*] //"'
- BRANCH[.hg]='hg branch 2>/dev/null'
- BRANCH[_darcs]="darcs show repo 2>/dev/null| egrep '^ *Cache' | sed 's@.*/\([^/]*\),.*@\1@'"
- BRANCH[.svn]="svn info 2>/dev/null | head -n 6 | tail -n 1"
-
- DIR=$(eval "find_up \"$PWD\" -name \"\"$(printf -- ' -o -name "%s"' "${DIR[@]}") | head -n 1")
- if [ -n "$DIR" ]; then
- DIR=$(basename "$DIR")
- LBRANCH=$(eval "${BRANCH[$DIR]}")
- LTYPE="${TYPE[$DIR]}"
- if [ "$color_prompt" = yes ]; then
- VCS_info="${nocolor_prompt}${vcs_symbols_color}(${vcs_type_color}$LTYPE${vcs_symbols_color})-${vcs_symbols_color}[${vcs_branch_color}$LBRANCH${vcs_symbols_color}]${nocolor_prompt}"
+# If name should be overwritten (eg for git-svn), do it.
+vcs_adjust(){
+ [[ -n ${vcs_comm[overwrite_name]} ]] && vcs=${vcs_comm[overwrite_name]}
+ return 0
+}
+
+# Formats two VCS_info messages, one with colors, and one without
+vcs_formats(){
+ local action=$1 branch=$2 base=$3 rev=$4
+ local msg
+ local -i i
+
+ # printf is for readability (it's easier to find %s)
+ msg="(%s)-[%s/%s"
+ msg=$(printf $msg $vcs ${base/*\/} $branch)
+
+ # If there is a revnumber, print it
+ if [ ! -z ${rev} ]; then
+ msg="${msg}:%s"
+ msg=$(printf $msg $rev)
+ fi
+
+ # Print the current cvs action state
+ if [ ! -z ${action} ] ; then
+ msg="${msg}|%s"
+ msg=$(printf $msg $action)
+ fi
+ msg="${msg}]-"
+
+ msgs[1]=$msg
+
+ # Same shit with colors
+ msg="${nocolor_prompt}${vcs_symbols_color}(${vcs_type_color}%s${vcs_symbols_color})${vcs_sep_color}-${vcs_symbols_color}[${vcs_repo_color}%s${vcs_sep_color}/${vcs_branch_color}%s"
+ msg=$(printf $msg $vcs ${base/*\/} $branch)
+ if [ ! -z ${rev} ]; then
+ msg="${msg}${vcs_colon_color}:${vcs_rev_color}%s"
+ msg=$(printf $msg $rev)
+ fi
+ if [[ ! -z ${action} ]] ; then
+ msg="${msg}${nocolor_prompt}|${vcs_action_color}%s"
+ msg=$(printf $msg $action)
+ fi
+ msg="${msg}${vcs_symbols_color}]${nocolor_prompt}-"
+ msgs[0]=$msg
+
+ return 0
+}
+
+# Uses -P option for cd in order to resolve symlinks
+vcs_realpath(){
+ (
+ cd -P $1 2>/dev/null && pwd
+ )
+}
+
+# Feature to detect a special dir, at the top of
+# the current repo
+detect_by_dir(){
+ local dirname=$1
+ local basedir="." realbasedir
+
+ realbasedir="$(vcs_realpath ${basedir})"
+ while [[ ${realbasedir} != '/' ]]; do
+ [[ -r ${realbasedir} ]] || return 1
+
+ # Tries to find detect_need_file (eg formats) in the dir
+ if [[ -n ${vcs_comm[detect_need_file]} ]] ; then
+ [[ -d ${basedir}/${dirname} ]] && \
+ [[ -e ${basedir}/${dirname}/${vcs_comm[detect_need_file]} ]] && \
+ break
else
- VCS_info="($LTYPE)-[$LBRANCH]"
+ [[ -d ${basedir}/${dirname} ]] && break
+ fi
+
+ basedir=${basedir}/..
+ realbasedir="$(vcs_realpath ${basedir})"
+ done
+
+ [[ ${realbasedir} == "/" ]] && return 1
+ vcs_comm[basedir]=${realbasedir}
+ return 0
+}
+
+# Git is powerfull
+git_detect(){
+ if check_command git && git rev-parse --is-inside-work-tree &> /dev/null; then
+ vcs_comm[gitdir]="$(git rev-parse --git-dir 2> /dev/null)" || return 1
+ if [[ -d ${vcs_comm[gitdir]}/svn ]] ; then vcs_comm[overwrite_name]='git-svn'
+ elif [[ -d ${vcs_comm[gitdir]}/refs/remotes/p4 ]] ; then vcs_comm[overwrite_name]='git-p4' ; fi
+ return 0
+ fi
+ return 1
+}
+
+# Mercurial isn't
+hg_detect(){
+ check_command hg || return 1
+ vcs_comm[detect_need_file]=store
+ detect_by_dir '.hg'
+ return $?
+}
+
+# Neither is svk
+# TODO - Not working : imported from zsh but not post treated
+svk_detect(){
+ local -a info
+ local -i fhash
+ fhash=0
+
+ check_command svk || return 1
+ [[ -f ~/.svk/config ]] || return 1
+
+ # This detection function is a bit different from the others.
+ # We need to read svk's config file to detect a svk repository
+ # in the first place. Therefore, we'll just proceed and read
+ # the other information, too. This is more then any of the
+ # other detections do but this takes only one file open for
+ # svk at most. VCS_INFO_svk_get_data() get simpler, too. :-)
+ while IFS= read -r line ; do
+ if [[ -n ${vcs_comm[basedir]} ]] ; then
+ line=${line## ##}
+ [[ ${line} == depotpath:* ]] && vcs_comm[branch]=${line##*/}
+ [[ ${line} == revision:* ]] && vcs_comm[revision]=${line##*[[:space:]]##}
+ [[ -n ${vcs_comm[branch]} ]] && [[ -n ${vcs_comm[revision]} ]] && break
+ continue
+ fi
+ (( fhash > 0 )) && [[ ${line} == ' '[^[:space:]]*:* ]] && break
+ [[ ${line} == ' hash:'* ]] && fhash=1 && continue
+ (( fhash == 0 )) && continue
+ [[ ${PWD}/ == ${${line## ##}%:*}/* ]] && vcs_comm[basedir]=${${line## ##}%:*}
+ done < ~/.svk/config
+
+ [[ -n ${vcs_comm[basedir]} ]] && \
+ [[ -n ${vcs_comm[branch]} ]] && \
+ [[ -n ${vcs_comm[revision]} ]] && return 0
+ return 1
+}
+
+# .svn in each directories
+svn_detect() {
+ check_command svn || return 1
+ [[ -d ".svn" ]] && return 0
+ return 1
+}
+
+bzr_detect(){
+ check_command bzr || return 1
+ vcs_comm[detect_need_file]=branch/format
+ detect_by_dir '.bzr'
+ return $?
+}
+
+cdv_detect(){
+ check_command cdv || return 1
+ vcs_comm[detect_need_file]=format
+ detect_by_dir '.cdv'
+ return $?
+}
+
+cvs_detect(){
+ check_command svn || return 1
+ [[ -d "./CVS" ]] && [[ -r "./CVS/Repository" ]] && return 0
+ return 1
+}
+
+darcs_detect(){
+ check_command darcs || return 1
+ vcs_comm[detect_need_file]=format
+ detect_by_dir '_darcs'
+ return $?
+}
+
+# Find git's branch
+git_getbranch (){
+ local gitbranch gitdir=$1 tmp actiondir
+ local gitsymref='git symbolic-ref HEAD'
+
+ # In certain circumstances, we have to take into account
+ # actions
+ actiondir=''
+ for tmp in "${gitdir}/rebase-apply" \
+ "${gitdir}/rebase" \
+ "${gitdir}/../.dotest"; do
+ if [[ -d ${tmp} ]]; then
+ actiondir=${tmp}
+ break
+ fi
+ done
+ if [[ -n ${actiondir} ]]; then
+ gitbranch="$(${gitsymref} 2> /dev/null)"
+ [[ -z ${gitbranch} ]] && [[ -r ${actiondir}/head-name ]] \
+ && gitbranch="$(< ${actiondir}/head-name)"
+
+ # MERGE_HEAD state
+ elif [[ -f "${gitdir}/MERGE_HEAD" ]] ; then
+ gitbranch="$(eval $gitsymref 2> /dev/null)"
+ [[ -z ${gitbranch} ]] && gitbranch="$(< ${gitdir}/MERGE_HEAD)"
+
+ # rebase
+ elif [[ -d "${gitdir}/rebase-merge" ]] ; then
+ gitbranch="$(< ${gitdir}/rebase-merge/head-name)"
+
+ # dotest
+ elif [[ -d "${gitdir}/.dotest-merge" ]] ; then
+ gitbranch="$(< ${gitdir}/.dotest-merge/head-name)"
+
+ # Normal case
+ else
+ gitbranch="$(eval $gitsymref 2> /dev/null)"
+
+ # shit happens
+ if [[ $? -ne 0 ]] ; then
+ gitbranch="refs/tags/$(git describe --exact-match HEAD 2>/dev/null)"
+
+ # big shit happens
+ if [[ $? -ne 0 ]] ; then
+ gitbranch=$(< $gitdir/HEAD)
+ gitbranch="${gitbranch:0:7}..."
+ fi
+ fi
+ fi
+
+ # keep only the last part of gitbranch
+ printf '%s' "${gitbranch#refs/[^/]*/}"
+ return 0
+}
+
+git_getaction(){
+ local gitaction='' gitdir=$1
+ local tmp
+
+ for tmp in "${gitdir}/rebase-apply" \
+ "${gitdir}/rebase" \
+ "${gitdir}/../.dotest" ; do
+ if [[ -d ${tmp} ]] ; then
+ if [[ -f "${tmp}/rebasing" ]] ; then
+ gitaction="rebase"
+ elif [[ -f "${tmp}/applying" ]] ; then
+ gitaction="am"
+ else
+ gitaction="am/rebase"
+ fi
+ printf '%s' ${gitaction}
+ return 0
fi
- VCS_size=$((${#LTYPE}+${#LBRANCH}+5))
+ done
+
+ for tmp in "${gitdir}/rebase-merge/interactive" \
+ "${gitdir}/.dotest-merge/interactive" ; do
+ if [[ -f "${tmp}" ]] ; then
+ printf '%s' "rebase-i"
+ return 0
+ fi
+ done
+
+ for tmp in "${gitdir}/rebase-merge" \
+ "${gitdir}/.dotest-merge" ; do
+ if [[ -d "${tmp}" ]] ; then
+ printf '%s' "rebase-m"
+ return 0
+ fi
+ done
+
+ if [[ -f "${gitdir}/MERGE_HEAD" ]] ; then
+ printf '%s' "merge"
+ return 0
+ fi
+
+ if [[ -f "${gitdir}/BISECT_LOG" ]] ; then
+ printf '%s' "bisect"
+ return 0
+ fi
+ return 1
+}
+
+git_get_data(){
+ local gitdir gitbase gitbranch gitaction
+
+ gitdir=${vcs_comm[gitdir]}
+ gitbranch="$(git_getbranch ${gitdir})"
+
+ if [[ -z ${gitdir} ]] || [[ -z ${gitbranch} ]] ; then
+ return 1
+ fi
+
+ vcs_adjust
+ gitaction="$(git_getaction ${gitdir})"
+ gitprefix=$(git rev-parse --show-prefix)
+ gitbase=${PWD%/${gitprefix%/}}
+ vcs_formats "${gitaction}" "${gitbranch}" "${gitbase}" ''
+ return 0
+}
+
+hg_get_data(){
+ local hgbranch hgbase file
+
+ hgbase=${vcs_comm[basedir]}
+
+ file="${hgbase}/.hg/branch"
+ if [[ -r ${file} ]] ; then
+ hgbranch=$(< ${file})
else
- VCS_info=""
- VCS_size=0
+ hgbranch='default'
fi
+
+ vcs_formats '' "${hgbranch}" "${hgbase}" ''
+ return 0
+}
+
+svk_get_data(){
+ local svkbranch svkbase
+
+ svkbase=${vcs_comm[basedir]}
+ svkbranch=${vcs_comm[branch]}
+ svkrevision=${vcs_comm[revision]}
+ vcs_formats '' "${svkbranch}" "${svkbase}" "${svkrevision}"
+ return 0
+}
+
+svn_get_data(){
+ local svnbase svnbranch
+ local -a svninfo
+
+ svnbase="."
+ while [[ -d "${svnbase}/../.svn" ]]; do
+ svnbase="${svnbase}/.."
+ done
+ svnbase="$(vcs_realpath ${svnbase})"
+ svnrev=$(svn info | awk '{if($1 == "Révision :") print $2}')
+ svnbranch=$(svn info | awk '{if($1 == "URL :") print $2}'|awk -F "/" '{ print $NF }')
+
+ vcs_formats '' "${svnbranch}" "${svnbase}" "${svnrev}"
+ return 0
+}
+
+bzr_get_data(){
+ local bzrbase bzrbr
+ local -a bzrinfo
+
+ bzrbase=$(bzr info|awk '{if ($1 == "branch" && $2 == "root:") print $3}')
+ bzrbranch=$(bzr version-info|awk '{if ($1 == "branch-nick:") print $2}')
+ bzrrev=$(bzr version-info|awk '{if ($1 == "revno:") print $2}')
+ bzrbase="$(vcs_realpath ${bzrbase})"
+ bzrbr="${bzrbranch}"
+
+ vcs_formats '' "${bzrbr}" "${bzrbase}" "${bzrrev}"
+ return 0
+}
+
+cdv_get_data(){
+ local cdvbase
+
+ cdvbase=${vcs_comm[basedir]}
+ vcs_formats '' "${cdvbase/*\/}" "${cdvbase}" ''
+ return 0
+}
+
+cvs_get_data(){
+ local cvsbranch cvsbase basename
+
+ cvsbase="."
+ while [[ -d "${cvsbase}/../CVS" ]]; do
+ cvsbase="${cvsbase}/.."
+ done
+ cvsbase="$(vcs_realpath ${cvsbase})"
+ cvsbranch=$(< ./CVS/Repository)
+ basename=${cvsbase/*\/}
+ cvsbranch=${cvsbranch#${basename}/}
+
+ [[ -z ${cvsbranch} ]] && cvsbranch=${basename}
+ vcs_formats '' "${cvsbranch}" "${cvsbase}" ''
+ return 0
}
+darcs_get_data(){
+ local darcsbase
+
+ darcsbase=${vcs_comm[basedir]}
+ vcs_formats '' "${darcsbase/*\/}" "${darcsbase}" ''
+ return 0
+}
+
+vcs_info(){
+ local -i found
+ local -ax msgs
+ local -Ax vcs_comm commands
+ local -x vcs
+ local -a vcss
+
+ vcs="init"
+ vcss=(git hg bzr darcs svk svn cvs cdv)
+ for i in $(seq 0 $(( ${#vcss[*]} - 1 ))); do
+ commands[${vcss[$i]}]=$(which ${vcss[$i]});
+ done;
+
+ found=0
+ for vcs in ${vcss[*]}; do
+ ${vcs}_detect && found=1 && break
+ done
+
+ (( found == 1 )) && ${vcs}_get_data
+
+ if [ ${color_prompt} = "yes" ]; then
+ VCS_info=${msgs[0]}
+ else
+ VCS_info=${msgs[1]}
+ fi
+ VCS_size=${#msgs[1]}
+}
# Pour avoir le bon umask en fonction du dossier où on se trouve
# L'umask définit avec quel droits un fichier est créé.
blanc_thin_prompt="\[${blanc_thin}\]"
nocolor_prompt="\[${nocolor}\]"
-if [ -x /usr/bin/tput ] && tput setaf 1 >&/dev/null; then
- # support de la couleur
- color_prompt=yes
- # Couleurs dans "user@host $"
- username_color=${rouge_prompt}
- host_color=${bleu_prompt}
- symbols_color=${vert_prompt}
- # Couleur de la ligne séparatrice de prompt
- line_color=${cyan}
- line_color_prompt=${cyan_prompt}
- # Couleur du path actuel
- pwd_color=${jaune_prompt}
- # Couleur de la date (à chaque affichage du prompt)
- date_color=${violet_prompt}
- # Couleur de la date au premier affichage (à l'ouverture du terminal)
- announce_date_color=${blanc}
- # Couleur d'affichage de vcs_info
- vcs_symbols_color=${violet_thin_prompt}
- vcs_type_color=${jaune_thin_prompt}
- vcs_branch_color=${vert_thin_prompt}
-else
- # pas de support de la couleur
- color_prompt=no
-fi
# Est-ce qu'on veut que le prompt affiche les information sur l'éventuel dépôt
# versionné dans lequel on se trouve
# À décommenter si on veut afficher des infos
# quand on se trouve dans un dépôt versionné
if [ "$display_vcs_info" = yes ]; then
- get_vcs_info
+ vcs_info
fi
# Chemin courant, en faisant attention à la largeur de la fenêtre
fi
}
+if [ -x /usr/bin/tput ] && tput setaf 1 >&/dev/null; then
+ # support de la couleur
+ color_prompt=yes
+ # Couleurs dans "user@host $"
+ username_color=${rouge_prompt}
+ host_color=${bleu_prompt}
+ symbols_color=${vert_prompt}
+ # Couleur de la ligne séparatrice de prompt
+ line_color=${cyan}
+ line_color_prompt=${cyan_prompt}
+ # Couleur du path actuel
+ pwd_color=${jaune_prompt}
+ # Couleur de la date (à chaque affichage du prompt)
+ date_color=${violet_prompt}
+ # Couleur de la date au premier affichage (à l'ouverture du terminal)
+ announce_date_color=${blanc}
+ # Couleur d'affichage de vcs_info
+ vcs_symbols_color=${violet_thin_prompt}
+ vcs_type_color=${jaune_thin_prompt}
+ vcs_branch_color=${vert_thin_prompt}
+ vcs_repo_color=${vert_thin_prompt}
+ vcs_action_color=${rouge_thin_prompt}
+ vcs_sep_color=${jaune_thin_prompt}
+ vcs_rev_color=${jaune_thin_prompt}
+ vcs_colon_color=${rouge_thin_prompt}
+else
+ # pas de support de la couleur
+ color_prompt=no
+fi
+
# On change le titre de la fenêtre dynamiquement si on est sous X
if [[ $TERM = "xterm" ]]; then
TITLE='\[\e];\u@\h:\w\a\]'
TITLE=''
fi
-# On régénère le prompt après chaque commande
+# On regénére le prompt après chaque commande
PROMPT_COMMAND=prompt_command
# +-------------------+