chiark / gitweb /
a7173f7bc1bb9187a139495ff6ac01df4b4405fd
[profile] / dot / bashrc
1 ### -*-bash-*-
2 ###
3 ### Bash session things
4
5 ## Only do this if we haven't done it before.  (Note that this guard isn't
6 ## exported, so subshells will need to make their own arrangements.)
7 if [ -z "$__mdw_bashrc" ]; then
8 __mdw_bashrc=done
9
10 ## If we've not run the main profile yet, we should do that first.  It sets
11 ## up things we rely on.  Also, if there's a system script, we should run
12 ## that too.
13 [ -z "$__mdw_profile" -a -r $HOME/.bash_profile ] && . $HOME/.bash_profile
14 [ -r /etc/bashrc ] && . /etc/bashrc
15
16 ## Completion.
17 [ -r /etc/bash_completion ] && . /etc/bash_completion
18 [ -r $HOME/.bash_completion ] && . $HOME/.bash_completion
19
20 ## Set the temporary directory again.  (If we've switched users, we'll want a
21 ## different temporary directory.)
22 [ "${TMPDIR+yes}" ] || eval `tmpdir -b`
23
24 ###--------------------------------------------------------------------------
25 ### Prompt hacking.
26
27 ## Only bother if the shell is interactive.
28 if [ -t 0 ]; then
29
30   ## Fancy highlighting in some terminals.
31   marker=${STY+'\[\ek\e\\\]'}
32   case "$TERM" in
33     linux*|screen*|xterm*|vt100*|eterm*)
34       case "$(tput bold)" in
35         "") bold="\[$(tput md)\]" unbold="\[$(tput me)\]" ;;
36         *) bold="\[$(tput bold)\]" unbold="\[$(tput sgr0)\]" ;;
37       esac
38       nl="\[\r\]"
39       ;;
40     *)
41       bold='' unbold='' nl='' ;;
42   esac
43
44   ## Choose the right delimiters.  Highlight root prompts specially;
45   ## highlight when I'm running as some other user.  Highlight when this
46   ## isn't the outermost shell on the terminal.
47   if (( EUID == 0 )); then
48     left=`echo « | iconv -f UTF-8 -t //translit`
49     right=`echo » | iconv -f UTF-8 -t //translit`
50   else
51     case $USER in
52       mdw|mwooding|nemo) u="" left="[" right="]" ;;
53       *) u="\\u@" left="{" right="}" ;;
54     esac
55     if [ "$__mdw_tty" = "`tty`" ]; then
56       left="<" right=">"
57     else
58       export __mdw_tty="`tty`"
59     fi
60   fi
61
62   ## If this session is insecure then highlight that.
63   if [ -z "$SSH_CLIENT" ] &&
64     [ "$__mdw_sechost" != "`hostname`" ]
65     then
66     sec_l='(' sec_r=')'
67   fi
68
69   ## Build the prompt string.
70   PS1="$nl$bold$left$sec_l$u\\h$sec_r \\w$marker$right$unbold"
71   PS2="$PS1 $bold>$unbold "
72   unset nl bold unbold left right sec_l sec_r marker
73 fi
74
75 ###--------------------------------------------------------------------------
76 ### Other shell tweaking.
77
78 ## Random shell tweaks.
79 notify=1
80 set -b
81 shopt -u cdable_vars
82 shopt -s cdspell
83 shopt -s checkhash
84 shopt -s checkwinsize
85 shopt -s cmdhist
86 shopt -u dotglob
87 shopt -s expand_aliases
88 shopt -s extglob
89 if (( ${BASH_VERSINFO[0]} >= 4 )); then shopt -s globstar; fi
90 shopt -s gnu_errfmt
91 shopt -s histappend
92 shopt -s histreedit
93 shopt -u histverify
94 shopt -s hostcomplete
95 shopt -s huponexit
96 shopt -s interactive_comments
97 shopt -s lithist
98 shopt -u mailwarn
99 shopt -u nocaseglob
100 shopt -u nullglob
101 shopt -s promptvars
102 shopt -u shift_verbose
103 shopt -s sourcepath
104 HISTCONTROL=ignorespace:erasedups
105
106 ## Some handy aliases.
107 alias cx='chmod a+x'
108 alias which="command -v"
109 alias rc="rc -l"
110 alias ssync="rsync -e ssh"
111 rootly () {
112   case $# in 0) set -- "${SHELL-/bin/sh}" ;; esac
113   $__MDW_ROOTLY "$@"
114 }
115 alias r=rootly
116 alias re="rootly $EDITOR"
117 alias pstree="pstree -hl"
118 alias cdtmp='cd ${TMPDIR-/tmp}'
119 alias pushtmp='pushd ${TMPDIR-/tmp}'
120 alias e="$EDITOR"
121 alias svn="svnwrap svn"
122 alias @="ssh"
123
124 ###--------------------------------------------------------------------------
125 ### Colour output.
126
127 ## Arrange for `ls' output to be in colour.
128 if [ -x /usr/bin/dircolors -o -x /usr/local/bin/dircolors ]; then
129   eval `dircolors -b ~/.dircolors`
130 else
131   unset LS_COLORS
132 fi
133
134 unalias ls 2>/dev/null || :; function ls () {
135   if [ -t 1 ]; then
136     command ls $LS_OPTIONS ${LS_COLORS+--color=auto} "$@"
137   else
138     command ls "$@"
139   fi
140 }
141
142 ## Arrange for `grep' output to be in colour.
143 export GREP_COLORS="mt=01;31:ms=01;31:mc=031;31:fn=36:ln=36:bn=36:se=34"
144
145 greplike () {
146   declare grep=$1; shift
147   if [ -t 1 ]; then
148     command $grep ${GREP_COLORS+--color=always} "$@" | mdw-pager
149   else
150     command $grep "$@"
151   fi
152 }
153 alias grep="greplike grep"
154 alias egrep="greplike egrep"
155 alias fgrep="greplike fgrep"
156 alias zgrep="greplike zgrep"
157
158 ## Turn off pagers inside Emacs shell buffers.
159 case "$INSIDE_EMACS" in
160   2[2-9].*,comint | [3-9][0-9].*,comint) export PAGER=cat ;;
161 esac
162
163 ###--------------------------------------------------------------------------
164 ### More complicated shell functions.
165
166 ## xt [@HOST] XTERM-ARGS
167 ##
168 ## Open a terminal, maybe on a remote host.
169 xt () {
170   case "$1" in
171     @*)
172       local remote=${1#@} title
173       shift
174       if [ $# -gt 0 ]; then
175         title="xterm [$remote] $1"
176       else
177         title="xterm [$remote]"
178       fi
179       (xterm -title "$title" -e ssh $remote "$@" &)
180       ;;
181     *)
182       (xterm "$@" &)
183       ;;
184   esac
185 }
186
187 ## core [y|n]
188 ##
189 ## Tweak core dumps on and off, or show the current status.
190 core () {
191   case "x$1" in
192     xon|xy|xyes) ulimit -Sc `ulimit -Hc` ;;
193     xoff|xn|xno) ulimit -Sc 0 ;;
194     x)
195       local l=`ulimit -Sc`
196       case $l in
197         0) echo "Core dumps disabled" ;;
198         unlimited) echo "Core dumps enabled" ;;
199         *) echo "Core dump limit is $l blocks" ;;
200       esac
201       ;;
202     *)
203       echo >&2 "usage: core [y|n]"
204       return 1
205       ;;
206   esac
207 }
208
209 ## world [NAME]
210 ##
211 ## Set current security world to NAME.  With no NAME, print the currently
212 ## selected world.
213 world () {
214   local nfast=${NFAST_HOME-/opt/nfast}
215   local kmdata
216   case "$#" in
217     0)
218       echo "${NFAST_KMDATA#$nfast/kmdata-}"
219       ;;
220     *)
221       if [ -d "$1" ]; then
222         kmdata=$1
223       elif [ -d "$nfast/kmdata-$1" ]; then
224         kmdata=$nfast/kmdata-$1
225       else
226         echo >&2 "world: can't find world $1"
227         return 1
228       fi
229       shift
230       case "$#" in
231         0) export NFAST_KMDATA=$kmdata ;;
232         *) "$@" ;;
233       esac
234       ;;
235   esac
236 }
237
238 ## Fix `man' under Slowaris.
239 case "$MACHTYPE" in
240   *solaris*)
241     man () {
242       declare -i i=0
243       declare arg
244       declare -a man
245       for arg; do
246         case "$arg" in [0-9]*) man[i+=1]="-s" ;; esac
247         man[i+=1]="$arg"
248       done
249       command man "${man[@]}"
250     }
251     ;;
252 esac
253
254 ###--------------------------------------------------------------------------
255 ### Path hacks.
256
257 ## path-add [VAR] DIR
258 ##
259 ## Add DIR to the beginning of PATH-like variable VAR (defaults to PATH) if
260 ## it's not there already.
261 path-add () {
262   local pathvar export dir val
263   case $# in
264     1) pathvar=PATH dir=$1 export="export PATH";;
265     2) pathvar=$1 dir=$2 export=:;;
266     *) echo >&2 "Usage: $0 [VAR] DIR";;
267   esac
268   eval "val=\$$pathvar"
269   case ":$val:" in
270     *:"$dir":*) ;;
271     *) val=$dir:$val ;;
272   esac
273   eval "$pathvar=\$val"
274   $export
275 }
276
277 ## path-remove [VAR] DIR
278 ##
279 ## Remove DIR from PATH-like variable VAR (defaults to PATH); it's not an
280 ## error if DIR isn't in VAR.
281 path-remove () {
282   local pathvar export dir val
283   case $# in
284     1) pathvar=PATH dir=$1 export="export PATH";;
285     2) pathvar=$1 dir=$2 export=:;;
286     *) echo >&2 "Usage: $0 [VAR] DIR";;
287   esac
288   eval "val=\$$pathvar"
289   case ":$val:" in
290     :"$dir":) val= ;;
291     :"$dir":*) val=${val#$dir:} ;;
292     *:"$dir":) val=${val%:$dir} ;;
293     *:"$dir":*) val=${val/:$dir:/:} ;;
294   esac
295   eval "$pathvar=\$val"
296   $export
297 }
298
299 ## pathhack [-f] +HACK|-HACK...
300 ##
301 ## Each HACK refers to a subdirectory of `~/bin/hacks'.  A hack name preceded
302 ## by `+' adds the directory to the PATH; a `-' removes.  Adding a hack
303 ## that's already on the PATH doesn't do anything unless `-f' is set, in
304 ## which case it gets moved to the beginning.  With no arguments, print the
305 ## currently installed hacks.
306 pathhack () {
307   if [ $# -eq 0 ]; then
308     local IFS=:
309     for e in $PATH; do
310       case "$e" in
311         "$HOME/bin/hacks/"*)
312           echo ${e#$HOME/bin/hacks/}
313           ;;
314       esac
315     done
316     return
317   fi
318   local force=nil
319   local path=$PATH
320   while [ $# -gt 0 ]; do
321     arg=$1
322     case "$arg" in
323       -f | --force)
324         force=t
325         shift
326         continue
327         ;;
328       --)
329         shift
330         break
331         ;;
332       [-+]*)
333         ;;
334       *)
335         break
336         ;;
337     esac
338     hack=${arg#[+-]}
339     dir=$HOME/bin/hacks/$hack
340     [ -d "$dir" ] || {
341       echo "$0: path hack $hack not found"
342       return 1
343     }
344     case "$arg,$force,:$PATH:" in
345       -*,*,*:"$dir":*)
346         path-remove path "$dir"
347         ;;
348       +*,t,*:"$dir":*)
349         path-remove path "$dir"
350         path-add path "$dir"
351         ;;
352       +*,nil,*:"$dir":*)
353         ;;
354       +*,*)
355         path-add path "$dir"
356         ;;
357     esac
358     shift
359   done
360   if [ $# -eq 0 ]; then
361     PATH=$path
362     export PATH
363   else
364     PATH=$path "$@"
365   fi
366 }
367
368 ###--------------------------------------------------------------------------
369 ### Finishing touches.
370
371 ## For `root' use -- some simple molly-guards.
372 if (( UID == 0 )); then
373   alias rm='rm -i' cp='cp -i' mv='mv -i'
374   set -o noclobber
375 fi
376
377 ## Run any local hooks.
378 [ -f "$HOME/.bashrc-local" ] && . "$HOME/.bashrc-local"
379
380 ## Close the `__mdw_bashrc' guard.
381 fi
382
383 ###----- That's all, folks --------------------------------------------------