*** empty log message ***
[scripts.git] / bashrc
1 # -*-Shell-script-*-
2
3 #########################################################################
4 # This program is free software: you can redistribute it and/or modify  #
5 # it under the terms of the version 3 of the GNU General Public License #
6 # as published by the Free Software Foundation.                         #
7 #                                                                       #
8 # This program is distributed in the hope that it will be useful, but   #
9 # WITHOUT ANY WARRANTY; without even the implied warranty of            #
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      #
11 # General Public License for more details.                              #
12 #                                                                       #
13 # You should have received a copy of the GNU General Public License     #
14 # along with this program. If not, see <http://www.gnu.org/licenses/>.  #
15 #                                                                       #
16 # Written by and Copyright (C) Francois Fleuret                         #
17 # Contact <francois@fleuret.org> for comments & bug reports             #
18 #########################################################################
19
20 # The site-specific and confidential settings are in another file
21
22 PRIVATE_BASHRC="${HOME}/private/bashrc.perso"
23
24 # If the MANPATH is not set, set it
25
26 [ "${MANPATH}" ] || MANPATH=$(manpath)
27
28 # If the private bashrc exists, execute it
29
30 [ -f "${PRIVATE_BASHRC}" ] && source "${PRIVATE_BASHRC}"
31
32 # !!! THIS HAS TO BE HERE EVEN IN THE NON-INTERACTIVE PART OR YOU WILL
33 # LOSE YOU PREVIOUS HISTORY !!!
34
35 export HISTFILESIZE=20000
36 export HISTSIZE=${HISTFILESIZE}
37
38 export HISTIGNORE="${HISTIGNORE}:&:[ ]*"
39
40 # I want to save the command time, but I do not want to see it in
41 # history
42
43 export HISTTIMEFORMAT=""
44
45 shopt -s histappend
46
47 # I realized that most of my settings are meaningful only in
48 # interactive mode. This should maybe be done more properly through
49 # using different .bash_profile and .bash_login
50
51 [[ ${TERM} == "dumb" ]] || [ ! -t 0 ] && return
52
53 ######################################################################
54 ## The interactive part
55
56 export VT_RESET=$'\033[0m'
57 export VT_BOLD=$'\033[1m'
58 export VT_UNDERLINE=$'\033[4m'
59 export VT_BLINK=$'\033[5m'
60
61 export VT_SET_TITLE=$'\033]0;'
62 export VT_END_TITLE=$'\007'
63
64 export VT_BLACK_FG=$'\033[30m'
65 export VT_RED_FG=$'\033[31m'
66 export VT_GREEN_FG=$'\033[32m'
67 export VT_YELLOW_FG=$'\033[33m'
68 export VT_BLUE_FG=$'\033[34m'
69 export VT_MAGENTA_FG=$'\033[35m'
70 export VT_CYAN_FG=$'\033[36m'
71 export VT_WHITE_FG=$'\033[37m'
72
73 export VT_BLACK_BG=$'\033[40m'
74 export VT_RED_BG=$'\033[41m'
75 export VT_GREEN_BG=$'\033[42m'
76 export VT_YELLOW_BG=$'\033[43m'
77 export VT_BLUE_BG=$'\033[44m'
78 export VT_MAGENTA_BG=$'\033[45m'
79 export VT_CYAN_BG=$'\033[46m'
80 export VT_WHITE_BG=$'\033[47m'
81
82 # This prevents ^S from freezing the shell
83
84 stty -ixon
85
86 alias rm='rm -i'
87 alias mv='mv -i'
88 # alias chmod='chmod -v'
89 alias chmod='chmod -c'
90 alias cp='cp -i'
91 alias rd=rmdir
92 alias md='mkdir -v'
93 alias ps='ps uxaf'
94 alias df='df -hT --sync'
95 alias grep='grep -E --mmap'
96
97 alias s='screen -d -R -U && clear'
98 alias mc='echo Try mv ' # I'm fed up with midnight commander
99 # alias kj="keyjnote -s -D 1000 -t Crossfade -T 100"
100 alias im="impressive -s -D 1000 -t Crossfade -T 100"
101
102 # alias fdupes='fdupes -r .'
103
104 # ls colors
105
106 if [ -e "${HOME}/.dircolors" ]; then
107     eval $(dircolors "${HOME}/.dircolors")
108     alias ls='ls --color'
109     # alias ll='ls --color -lth'
110     alias lt='ls --color -gohtr --time-style="+%Y %b %d %H:%M"'
111     alias ll='ls --color -goh --time-style="+%Y %b %d %H:%M"'
112     alias l='ls --color -I "*~" -I "*.o"'
113     alias less='less -R'
114 else
115     # alias ll='ls -lth'
116     alias lt='ls -gohtr --time-style="+%Y %b %d %H:%M"'
117     alias ll='ls -goh --time-style="+%Y %b %d %H:%M"'
118     alias l='ls -I "*~" -I "*.o"'
119 fi
120
121 export EDITOR=emacsclient
122 export GIT_EDITOR=${EDITOR}
123
124 ######################################################################
125 # Ignored extensions when completing
126
127 export FIGNORE="CVS"
128
129 ######################################################################
130 # Functions
131
132 # Find a file containing a name
133
134 function fn () {
135     name=$1
136     shift
137     find $* -name "*${name}*";
138 }
139
140 # Create a dir and cd there
141
142 function mcd () {
143     mkdir -vp $1
144     cd $1
145 }
146
147 # Capture the screen in a dated png
148
149 function cap () {
150     name="capture-$(date +%s).png"
151     [[ $1 ]] && sleep $1
152     xwd  | convert - ${name}
153     \ls -l ${name}
154 }
155
156 # Create and CD in a /tmp/tmp.XXXXXX directory. With the '-'
157 # arguments, do not create one and CD in the most recent instead
158
159 function cdt () {
160     if [[ $1 ]]; then
161         if [[ $1 == "-" ]]; then
162             cd $(\ls -td /tmp/tmp.?????? | head -1)
163         else
164             echo "USAGE: cdt [-]" >&2
165             return 1
166         fi
167     else
168         cd $(mktemp -d /tmp/tmp.XXXXXX)
169     fi
170 }
171
172 alias t='cd /tmp'
173
174 alias trash=trash.sh
175
176 function mmsget () {
177     mplayer $1 -dumpstream -dumpfile $(basename $1)
178 }
179
180 ######################################################################
181 # http://www.reddit.com/r/linux/comments/akt3j/a_functional_programming_style_map_function_for/
182
183 function map () {
184     local command i rep
185     if [ $# -lt 2 ] || [[ ! "$@" =~ :[[:space:]] ]];then
186         echo "Invalid syntax." >&2; return 1
187     fi
188     until [[ $1 =~ : ]]; do
189         command="$command $1"; shift
190     done
191     command="$command ${1%:}"; shift
192     for i in "$@"; do
193         if [[ $command =~ \{\} ]];then
194             rep="${command//\{\}/\"$i\"}"
195             eval "${rep//\\/\\\\}"
196         else
197             eval "${command//\\/\\\\} \"${i//\\/\\\\}\""
198         fi
199     done
200 }
201
202 ######################################################################
203 ## A version of pho which stores the image numbers in environment
204 ## variables
205
206 function pho () {
207     PHO_BIN=/usr/bin/pho
208     TEMP=$(mktemp /tmp/pho.XXXXXXX)
209     ${PHO_BIN} $* | tee ${TEMP}
210     PHO_NOTE_1=$(grep ^"Note 1: " ${TEMP} | sed -e "s/^[^:]*: //")
211     PHO_NOTE_2=$(grep ^"Note 2: " ${TEMP} | sed -e "s/^[^:]*: //")
212     PHO_NOTE_3=$(grep ^"Note 3: " ${TEMP} | sed -e "s/^[^:]*: //")
213     PHO_NOTE_R90=$(grep ^"Rotate 90 \(CW\): " ${TEMP} | sed -e "s/^[^:]*: //")
214     PHO_NOTE_R180=$(grep ^"Rotate 180: " ${TEMP} | sed -e "s/^[^:]*: //")
215     PHO_NOTE_R270=$(grep ^"Rotate -90 \(CCW\): " ${TEMP} | sed -e "s/^[^:]*: //")
216     \rm ${TEMP}
217 }
218
219 # function rotjpeg () {
220     # if [ $1 == "90" ] || [ $1 == "180" ] || [ $1 == "270" ]; then
221         # TEMP=$(mktemp /tmp/rotjpeg.XXXXXX)
222         # echo jpegtran -rotate $1 -copy all $2 > ${TEMP}
223         # echo cp $2 ${2/jpg/}original.jpg
224         # echo cp ${TEMP} $2
225         # rm ${TEMP}
226     # else
227         # echo "Can not rotate with an angle of $1 degrees."
228     # fi
229 # }
230
231 ######################################################################
232 ## A version of date that shows the time at home if TZ is set
233
234 function dt () {
235     echo "Local: $(date)"
236     if [[ ${TZ} ]]; then
237         unset TZ
238         echo "Home:  $(date)"
239     fi
240 }
241
242 ######################################################################
243 ## ifup / ifdown with sudo and memorization of the network
244
245 ## When invoked without an argument this "ifup" uses the same argument
246 ## as the previous time
247
248 ## When invoked without an argument this "ifdown" removes the last
249 ## interface which was ifuped
250
251 [[ ${IFUPRC} ]] || IFUPRC="${HOME}/.ifuprc"
252
253 function ifup () {
254     echo "${VT_BOLD}${VT_GREEN_FG}This is the bash function ifup from .bashrc${VT_RESET}"
255     if [[ "$1" == "-s" ]]; then
256         chosen_ifup=$(mktemp /tmp/chosen_ifup.XXXXXX)
257         selector -o ${chosen_ifup} <(cat ${IFUPRC} | sort | uniq)
258         ARGS=$(cat ${chosen_ifup})
259         rm -f ${chosen_ifup}
260         echo ${ARGS} >> ${IFUPRC}
261     else
262         if [[ ! $* ]] && [[ -s ${IFUPRC} ]]; then
263             # If we have no argument and there is a .ifuprc, use it
264             ARGS=$(tail -1 ${IFUPRC})
265         else
266             # Otherwise uses the given arguments, and store them
267             ARGS=$*
268             echo ${ARGS} >> ${IFUPRC}
269         fi
270     fi
271     echo "${VT_GREEN_FG}Running [sudo ifup ${ARGS}]${VT_RESET}"
272     sudo ifup ${ARGS}
273
274     # Ugly hack to remove the dsl modem dns server when we add
275     # explicitely a dns in the /etc/network/interfaces
276
277     REMOVE_LOCAL_DNS=/usr/local/bin/remove-local-dns.sh
278
279     if [[ -x ${REMOVE_LOCAL_DNS} ]]; then
280         echo "${VT_GREEN_FG}Running [sudo ${REMOVE_LOCAL_DNS} 192.168]${VT_RESET}"
281         sudo ${REMOVE_LOCAL_DNS} 192.168
282     fi
283 }
284
285 function ifdown () {
286     echo "${VT_BOLD}${VT_GREEN_FG}This is the bash function ifdown from .bashrc${VT_RESET}"
287     if [[ ! $* ]] && [[ -s ${IFUPRC} ]]; then
288         # If there are no arguments and there is a .ifuprc, get the
289         # interface from it
290         ARGS=$(tail -1 ${IFUPRC} | sed -e "s/=.*$//")
291     else
292         # Otherwise, use the standard ifdown
293         ARGS=$*
294     fi
295     echo "${VT_GREEN_FG}Running sudo [ifdown ${ARGS}]${VT_RESET}"
296     sudo ifdown ${ARGS}
297 }
298
299 function checkgw () {
300     ping $(route -n | grep ^0.0.0.0 | awk '{print $2}')
301 }
302
303 ######################################################################
304 # Show the most recent files, no scroll
305
306 function lr () {
307     HEIGHT=$(stty size | awk '{print $1}')
308     WIDTH=$(stty size | awk '{print $2}')
309     \ls -goth  --time-style="+%Y %b %d %H:%M" $* | head -$((HEIGHT-2)) | cut -b1-${WIDTH}
310     # \ls -lth $* | head -$((HEIGHT-2)) | cut -b1-${WIDTH}
311 }
312
313 ######################################################################
314 # cd and ls into a directory
315 # [from http://www.oreillynet.com/onlamp/blog/2007/01/whats_in_your_bash_history.html]
316
317 # function c () { cd "$@" && lr; }
318
319 ######################################################################
320 # You can change the xterm background color on the fly!
321
322 function setxtermbg () {
323     echo -n $'\033]11;'$1$'\007'
324 }
325
326 ######################################################################
327 # Shuffle the lines from the stdin
328
329 function shuffle () {
330     SEED=$1
331     [[ $SEED ]] || SEED=0
332     awk 'BEGIN{srand('${SEED}')} { print rand()" "$0 }' | sort -g | sed -e "s/^[0-9\.e\-]* //"
333 }
334
335 ######################################################################
336 # Stores the last entered command into a file
337
338 KEPT_COMMANDS=${HOME}/.kept_bash_commands
339
340 function keep () {
341     if [[ ${KEPT_COMMANDS} ]]; then
342         LINE=$(history | tail -2 | head -1 | sed -e "s/^[0-9 ]*//")
343         echo $LINE
344         echo $(date)": "${LINE} >> ${KEPT_COMMANDS}
345     else
346         echo "You have to set \$KEPT_COMMANDS"
347     fi
348 }
349
350 ######################################################################
351 # I sometime burn CDs and DVDs
352
353 function burn () {
354     set -e
355     DEVICE="/dev/cdrw"
356     if [[ ! $1 ]]; then
357         echo "burn <iso name | dirname>" >&2
358     elif [[ -f $1 ]]; then
359         if [[ $(file $1 | grep "ISO 9660") ]]; then
360             wodim -eject -v dev=${DEVICE} $1
361         else
362             echo "Unknown type of $1" >&2
363         fi
364     elif [[ -d $1 ]]; then
365         TMP=$(mktemp /tmp/cdimage.XXXXXX) && \
366             genisoimage -input-charset iso8859-1 -r -o ${TMP} $1 && \
367             wodim -eject -v dev=${DEVICE} ${TMP}
368         rm -f ${TMP}
369     else
370         echo "Can not find $1" >&2
371     fi
372 }
373
374 ######################################################################
375 # And watch DVDs too!
376
377 function dvd () {
378
379     echo
380     echo " ! and @   Seek to the beginning of the previous/next chapter"
381     echo " j         Cycle through the available subtitles"
382     echo " o         Show/hide the timing"
383     echo
384
385     if [[ $1 ]]; then
386         dvd_device="$1"
387         shift
388     else
389         dvd_device="/dev/cdrom"
390     fi
391
392     title="1"
393
394     if [[ $1 ]]; then
395         title=$1
396         shift
397     fi
398
399     mplayer > /dev/null \
400         -stop-xscreensaver \
401         -vc ffmpeg12 -quiet \
402         -vf yadif \
403         -alang en \
404         -dvd-device ${dvd_device} dvd://${title}
405
406 # -slang en
407
408 }
409
410 function ripdvd () {
411     mkdir -p ${HOME}/dvds
412     cd ${HOME}/dvds
413     time dvdbackup -v -M && eject
414 }
415
416 ######################################################################
417 # Upload the sources from the current directory to work
418
419 function ulsrc () {
420     if [[ ! "${MY_WORK_MACHINE}" ]]; then
421         echo "\$MY_WORK_MACHINE undefined" 1>&2
422         return 1
423     fi
424
425     DIR=${PWD/$HOME\//}
426
427     scp {Makefile,*.{cc,h,sh}} ${MY_WORK_MACHINE}:${DIR}
428
429     echo "Uploaded to ${MY_WORK_MACHINE}:${DIR}/"
430 }
431
432 ######################################################################
433 # Create small images from images
434
435 function mksmall () {
436
437     PARAMS="-geometry 800x600"
438
439     # Auto-orient does not seem to work at all, hence the ugly hack
440     # with exif below
441
442     # PARAMS="-auto-orient -geometry 800x600"
443
444     echo "Using ${PARAMS}"
445
446     DEST_DIR=$1
447
448     [[ ${DEST_DIR} ]] || DEST_DIR=./small
449
450     mkdir -p ${DEST_DIR}
451
452     if [[ ! -d ${DEST_DIR} ]]; then
453         echo "Can not create ${DEST_DIR}" >&2
454         return
455     fi
456
457     NB_TOTAL=$(find -maxdepth 1 -type f | wc -l)
458     NB=0
459
460     for i in $(find -maxdepth 1 -type f); do
461         if [[ $(file $i | grep image) ]]; then
462             if [[ -e ${DEST_DIR}/$i ]]; then
463                 echo "The file ${DEST_DIR}/$i already exists."
464             else
465
466                 orientation=$(exif $i \
467                     | grep ^Orientation \
468                     | head -1 \
469                     | sed -e "s/^[^|]*|//" \
470                     | sed -e "s/ *$//")
471
472                 case ${orientation} in
473                     ""|"top - left")
474                         rotation_cmd=""
475                         ;;
476
477                     "right - top")
478                         rotation_cmd="-rotate 90"
479                         ;;
480
481                     "left - bottom")
482                         rotation_cmd="-rotate 270"
483                         ;;
484
485                     *)
486                         rotation_cmd=""
487                         echo "Unknown orientation \"${orientation}\" !"
488                         ;;
489                 esac
490
491                 if [[ $(file ${i/%.*/}.* | grep -E movie) ]] ; then
492                     CAPTION_PARAMS="-font FreeSans-Bold -pointsize 32 -fill green -annotate +10+32 Video"
493                 else
494                     CAPTION_PARAMS=""
495                 fi
496
497                 convert ${rotation_cmd} $i ${PARAMS} ${CAPTION_PARAMS} ${DEST_DIR}/$i
498             fi
499
500             \ls -lt ${DEST_DIR}/$i
501         fi
502
503         NB=$((NB+1))
504
505         echo "$((NB*100/NB_TOTAL))% (${NB}/${NB_TOTAL})"
506     done
507 }
508
509 ######################################################################
510 # Move a file to the ~/sources/config directory and replace it where
511 # it was by a symbolic link
512
513 function mvtoconfig () {
514     CONFIGDIR=${HOME}/sources/config
515     if [[ -d ${CONFIGDIR} ]]; then
516         NEWNAME=${CONFIGDIR}/$(basename $1 | sed -e "s/^\.//")
517         mv $1 $NEWNAME
518         ln -s $NEWNAME $1
519     else
520         echo "Can not find ${CONFIGDIR}"
521     fi
522 }
523
524 ######################################################################
525 # Track uncommited files (I presume this is very ugly from a real git
526 # user perspective)
527
528 function git-fm () {
529     CURRENT_DIR=$(pwd)
530     NB_SUBDIR=0
531
532     for i in $(find -name ".git"); do
533         NB_SUBDIR=$((NB_SUBDIR+1))
534         cd ${CURRENT_DIR}/$(dirname $i)
535         NB_MODIFIED=$(git status | grep modified | wc -l)
536         if [[ ${NB_MODIFIED} -gt 0 ]]; then
537             echo "$(dirname $i) (${NB_MODIFIED})"
538             git status | grep modified \
539                 | sed -e "s/^#\t/    /" | sed -e "s/modified: *//"
540         fi
541     done
542
543     cd ${CURRENT_DIR}
544
545     echo "Visited ${NB_SUBDIR} directories."
546 }
547
548 ######################################################################
549 # Commits all directories under git
550
551 function git-ca () {
552     ORIGINAL_PWD=${PWD}
553     UNCOMMITTED=""
554     for d in $(find ${PWD} -name ".git"  | sed -e "s/\.git$//"); do
555         cd $d
556         NB_MODIFIED=$(git status | grep modified | wc -l)
557         if [[ ${NB_MODIFIED} -gt 0 ]]; then
558             if [[ $(pwd) =~ ${NO_AUTOMATIC_GIT_COMMIT} ]]; then
559                 UNCOMMITTED="${UNCOMMITTED} $(pwd)"
560             else
561                 echo $(pwd)" (${NB_MODIFIED} modified file(s))"
562                 git commit -a -m "Automatic commit" | grep -v ^#
563             fi
564             # git gc
565         fi
566     done
567
568     cd ${ORIGINAL_PWD}
569
570     if [[ ${UNCOMMITTED} ]]; then
571         echo "** WARNING: Did not automatically commit${UNCOMMITTED}"
572     fi
573 }
574
575 ######################################################################
576 # Backups all git directories into an encrypted backup file located
577 # either on the usb key or the SD card (in that order) if they can be
578 # mounted.
579
580 function git-backup () {
581
582     BACKUPDIR=/mnt/key
583
584     mount ${BACKUPDIR} 2> /dev/null
585
586     if [[ ! $(mount | grep ${BACKUPDIR}) ]]; then
587         BACKUPDIR=/mnt/sd
588         mount ${BACKUPDIR}
589     fi
590
591     if [[ $(mount | grep ${BACKUPDIR}) ]]; then
592         echo "Mounted ${BACKUPDIR}"
593     else
594         echo "Could not mount the backup directory"
595         return 1
596     fi
597
598     RESULT=${BACKUPDIR}/gitbackup-$(date +%F-%H%M%S).tgz.mc
599
600     tar zcvf - $(find ${HOME}/ -name .git) \
601         | mcrypt -f ${HOME}/private/mcrypt.key > ${RESULT}
602
603     if [[ -f ${RESULT} ]]; then
604         ls -lh ${RESULT}
605     else
606         echo "Could not create the backup!"
607         return 1
608     fi
609
610     sync
611
612     umount ${BACKUPDIR} && echo "Umounted ${BACKUPDIR}"
613 }
614
615 ######################################################################
616 # Downloads torrents located in ${BT_DIR}/torrents/ and puts the
617 # result in the ${BT_DIR}
618
619 function bt () {
620     if [[ ${BT_DIR} ]]; then
621         if [[ -d "${BT_DIR}/torrents" ]]; then
622             if [[ $1 ]]; then
623                 mv $1 ${BT_DIR}/torrents
624             fi
625             if [[ "$(ps auxwww | grep btlaunchmanycurses | grep -v grep)" ]]; then
626                 echo "A client is already running."
627             else
628                 cd ${BT_DIR} && screen btlaunchmanycurses torrents --max_upload_rate 32
629             fi
630         else
631             echo "Directory ${BT_DIR}/torrents does not exist."
632         fi
633     else
634         echo "You have to set \$BT_DIR."
635     fi
636 }
637
638 ######################################################################
639 # The complex prompt policy
640
641 export PS1
642
643 if [ "${CONSOLE}" == "yes" ]; then
644     PS1=""
645 else
646
647 # If the login is a standard one (as specified in
648 # IGNORED_PROMPT_LOGIN, which is set in the private bash file), do not
649 # show it. I have IGNORED_PROMPT_LOGIN="^fleuret$".
650
651     if [ ! ${IGNORED_PROMPT_LOGIN} ] || [[ ! ${USER} =~ ${IGNORED_PROMPT_LOGIN} ]]; then
652         IDENT="${USER}"
653     fi
654
655 # If the display is not the main one, make the assumption that the
656 # shell is not running on the localhost, and show the hostname
657
658     [ "${DISPLAY}" != ":0.0" ] && IDENT="${IDENT}@\h"
659
660 # If there is the login or the hostname, add a ":" to the prompt
661
662     [ "${IDENT}" ] && IDENT="${IDENT}:"
663
664 # If we are root, show that in red
665
666     if [[ ${USER} == "root" ]]; then
667         PS1="\[${VT_RED_BG}${VT_WHITE_FG}\]${IDENT}\w\[${VT_RESET}\] "
668     else
669         PS1="\[${VT_WHITE_BG}${VT_BLACK_FG}\]${IDENT}\w\[${VT_RESET}\] "
670     fi
671
672 # In an xterm, show the hostname and path in the title bar, highlight
673 # the prompt
674
675     # [ "${TERMS_WITH_BAR}" ] || TERMS_WITH_BAR="^xterm|screen$"
676
677     # if [[ "${TERM}" =~ "${TERMS_WITH_BAR}" ]]; then
678         # PS1="\[${VT_SET_TITLE}shell@\h (\w)${VT_END_TITLE}${VT_WHITE_BG}\]${IDENT}\w\[${VT_RESET}\] "
679     # else
680         # PS1="\[${VT_WHITE_BG}\]${IDENT}\w\[${VT_RESET}\] "
681     # fi
682
683 fi
684
685 ######################################################################
686 # This implements a local history. If we are in a directory containing
687 # a writable local history file, we add the last line of the global
688 # history to it.
689
690 LOCAL_HISTORY_FILE=".local_bash_history"
691
692 function keep_local_history () {
693     if [[ -w "${LOCAL_HISTORY_FILE}" ]]; then
694         history 1 | sed -e 's/^ *[0-9]* *//' >> ${LOCAL_HISTORY_FILE}
695         TMP=$(mktemp /tmp/lh.XXXXXX)
696         \chmod 600 ${TMP}
697         uniq < ${LOCAL_HISTORY_FILE} | tail -${HISTSIZE} > ${TMP}
698         # mv would replace a symbolic link, while cp keeps it
699         \cp ${TMP} ${LOCAL_HISTORY_FILE}
700         \rm ${TMP}
701         LOCAL_HISTORY_HINT=" LH "
702     else
703         LOCAL_HISTORY_HINT=""
704     fi
705 }
706
707 PS1="\[${VT_WHITE_BG}\]\${LOCAL_HISTORY_HINT}\[${VT_RESET}\]${PS1}"
708
709 ######################################################################
710 # Switch off the history
711
712 alias nh=" export HISTFILE=/dev/null"
713
714 function histfile_cue () {
715     if [[ ! "${HISTFILE}" == "${HOME}/.bash_history" ]]; then
716         HISTORY_CUE="[${HISTFILE}]"
717     else
718         HISTORY_CUE=""
719     fi
720 }
721
722 PS1="\[${VT_YELLOW_BG}\]\${HISTORY_CUE}\[${VT_RESET}\]${PS1}"
723
724 ######################################################################
725 # The dus command is available on my web site
726 #
727 # git clone http://fleuret.org/git/dus/
728
729 alias dus='dus -f -i'
730
731 ######################################################################
732 # The finddup command is available on my web site
733 #
734 # git clone http://fleuret.org/git/finddup/
735
736 # alias finddup='finddup -p0d'
737 alias finddup='finddup -p'
738
739 ######################################################################
740 # This script grep messages in my mail archives
741
742 alias gma='gma.sh'
743
744 ######################################################################
745 # Selector based history
746 #
747 # The selector command is available on my web site
748 #
749 # git clone http://fleuret.org/git/selector/
750
751 function selector-history () {
752     selector --bash -c 7,4,0,3 -q <(history)
753 }
754
755 # Find pathes in the history and make a list of the existing ones
756
757 function selector-cd () {
758     CD_HISTORY=${HOME}/.selector-cd-history
759     if [[ $1 == "+" ]]; then
760         PATH_TEMP=$(mktemp /tmp/selector-cd-path.XXXXXX)
761         selector -d -i -o ${PATH_TEMP} ${CD_HISTORY}
762         cd $(cat ${PATH_TEMP} | sed -e "s|~|${HOME}|")
763         \rm ${PATH_TEMP}
764     else
765         cd $1 && echo $PWD | sed -e "s|${HOME}|~|" >> ${CD_HISTORY}
766     fi
767 }
768
769 alias cd=selector-cd
770
771 # M-c provides a dynamic list of directories to cd into
772
773 bind '"\C-[c":"\C-a\C-kselector-cd +\C-m"'
774
775 # function selector-cd () {
776 #     LIST_TEMP=$(mktemp /tmp/selector-cd-list.XXXXXX)
777 #     PATH_TEMP=$(mktemp /tmp/selector-cd-path.XXXXXX)
778 #     for d in $(history | \
779 #         grep ^" *[0-9]* *cd" | \
780 #         awk '{ print $3 }' | \
781 #         grep -v "\.\." | \
782 #         uniq); do
783 #         if [[ -d $d ]]; then
784 #             echo "$d"
785 #         fi
786 #     done >> ${LIST_TEMP}
787 #     selector -d -i -o ${PATH_TEMP} ${LIST_TEMP}
788 #     cd $(cat ${PATH_TEMP})
789 #     \rm ${LIST_TEMP}
790 #     \rm ${PATH_TEMP}
791 # }
792
793 # M-r puts the selected history line in place of the current one
794
795 bind '"\C-[r":"\C-a\C-kselector-history\C-m"'
796
797 # M-t appends the selected history line and the end of the current one
798
799 bind '"\C-[t":"\C-a\C-kselector-history\C-m\C-a\C-y\C-e"'
800
801 # And we avoid to put in the history the use of the selector, which we
802 # do too often
803
804 HISTIGNORE="${HISTIGNORE}:selector-history"
805
806 function selector-printer () {
807     TMP=$(mktemp /tmp/selector-printer.XXXXXX)
808     selector -o ${TMP} <(lpstat -a | awk '{print $1}')
809     export PRINTER=$(cat ${TMP})
810     echo "PRINTER=${PRINTER}"
811     rm -f ${TMP}
812     lpq
813 }
814
815 ######################################################################
816
817 function prompt_command () {
818 # save the history after every command to avoid loosing some when
819 # multiple shells are open
820     history -a
821 # and the local histories system defined above
822     keep_local_history
823 # and the history cue
824     histfile_cue
825 }
826
827 PROMPT_COMMAND="prompt_command"
828
829 ######################################################################
830
831 # Displaying the timezone if it is set
832
833 if [[ ${TZ} ]]; then
834     echo "${VT_BOLD}${VT_GREEN_FG}Time zone is ${TZ}.${VT_RESET}"
835 fi
836
837 ######################################################################