| 1 | ### -*-sh-*- |
| 2 | ### |
| 3 | ### Common per-shell configuration. |
| 4 | |
| 5 | ###-------------------------------------------------------------------------- |
| 6 | ### Utilities. |
| 7 | |
| 8 | __mdw_programp () { type >/dev/null 2>&1 "$1"; } |
| 9 | |
| 10 | __mdw_source_if_exists () { |
| 11 | local i |
| 12 | for i in "$@"; do |
| 13 | if [ -r "$i" ]; then . "$i"; fi |
| 14 | done |
| 15 | } |
| 16 | |
| 17 | ###-------------------------------------------------------------------------- |
| 18 | ### Prompt machinery. |
| 19 | |
| 20 | __mdw_set_prompt_hacks () { host=$(hostname); dir=""; } |
| 21 | |
| 22 | __mdw_set_prompt_pieces () { |
| 23 | local hqual |
| 24 | hqual="" |
| 25 | |
| 26 | ## Fancy highlighting in some terminals. |
| 27 | local bold unbold nl gitcolour rccolour uncolour |
| 28 | local host dir more |
| 29 | bold="" unbold="" nl="" gitcolour="" rccolour="" uncolour="" more="" |
| 30 | __mdw_set_prompt_hacks |
| 31 | |
| 32 | ## Choose the right delimiters. Highlight root prompts specially; |
| 33 | ## highlight when I'm running as some other user. Highlight when this |
| 34 | ## isn't the outermost shell on the terminal. |
| 35 | local left right user u tty |
| 36 | user=${USER-${LOGNAME-$(id -un)}} |
| 37 | case $(id -u) in |
| 38 | 0) |
| 39 | left=$(echo « | iconv -f UTF-8 -t //translit) |
| 40 | right=$(echo » | iconv -f UTF-8 -t //translit) |
| 41 | ;; |
| 42 | *) |
| 43 | case $user in |
| 44 | mdw | mwooding | nemo) u="" left="[" right="]" ;; |
| 45 | *) u="$user@" left="{" right="}" ;; |
| 46 | esac |
| 47 | tty=$(tty) |
| 48 | case "$__mdw_tty" in |
| 49 | "$tty") left="<" right=">" ;; |
| 50 | *) __mdw_tty=$tty; export __mdw_tty ;; |
| 51 | esac |
| 52 | ;; |
| 53 | esac |
| 54 | |
| 55 | ## If this session is insecure then highlight that. |
| 56 | local sec_l sec_r h |
| 57 | h=$(hostname) |
| 58 | case ${SSH_CLIENT-nil},${SCHROOT_CHROOT_NAME-nil},$__mdw_sechost in |
| 59 | nil,nil,"$h") sec_l="" sec_r="" ;; |
| 60 | nil,nil,*) sec_l="(" sec_r=")" ;; |
| 61 | *) sec_l="" sec_r="" |
| 62 | esac |
| 63 | |
| 64 | ## If this is an schroot environment or some other interesting augmented |
| 65 | ## environment then point this out. |
| 66 | hqual="$hqual${SCHROOT_CHROOT_NAME+/$SCHROOT_CHROOT_NAME}" |
| 67 | hqual="$hqual${MDW_BUILDENV+/$MDW_BUILDENV}" |
| 68 | |
| 69 | ## Put together the main pieces. |
| 70 | __mdw_prompt_left="$nl$bold$left$sec_l$u$host$hqual$sec_r$dir" |
| 71 | __mdw_prompt_git_left="$unbold$gitcolour" |
| 72 | __mdw_prompt_git_right="$uncolour$bold" |
| 73 | __mdw_prompt_rc_left="$unbold$rccolour" |
| 74 | __mdw_prompt_rc_right="$uncolour$bold" |
| 75 | __mdw_prompt_right="$right$unbold" |
| 76 | __mdw_prompt_more=" $more$bold>$unbold " |
| 77 | } |
| 78 | |
| 79 | __mdw_set_prompt () { |
| 80 | case "${TERM-dumb}:${INSIDE_EMACS+$INSIDE_EMACS}" in |
| 81 | dumb:) |
| 82 | case $(id -u) in 0) PS1='# ' ;; *) PS1='$ ' ;; esac |
| 83 | PS2='> ' |
| 84 | ;; |
| 85 | *) |
| 86 | __mdw_last_rc=$? |
| 87 | local git rc |
| 88 | if type __git_ps1 >/dev/null 2>&1; then |
| 89 | git="$__mdw_prompt_git_left$(__git_ps1)$__mdw_prompt_git_right" |
| 90 | else |
| 91 | git="" |
| 92 | fi |
| 93 | case $__mdw_last_rc in |
| 94 | 0) rc="" ;; |
| 95 | *) rc="$__mdw_prompt_rc_left rc=$__mdw_last_rc$__mdw_prompt_rc_right" ;; |
| 96 | esac |
| 97 | PS1="$__mdw_prompt_left$git$rc$__mdw_prompt_right" |
| 98 | PS2="$PS1$__mdw_prompt_more" |
| 99 | unset __mdw_last_rc |
| 100 | ;; |
| 101 | esac |
| 102 | } |
| 103 | |
| 104 | __mdw_precmd () { |
| 105 | __mdw_set_prompt |
| 106 | case ${STY+t} in |
| 107 | t) printf "\ek%s\e\\" "$__mdw_shell" ;; |
| 108 | esac |
| 109 | } |
| 110 | |
| 111 | __mdw_preexec () { |
| 112 | case ${STY+t} in |
| 113 | t) printf "\ek%s\e\\" "$1" ;; |
| 114 | esac |
| 115 | } |
| 116 | |
| 117 | ###-------------------------------------------------------------------------- |
| 118 | ### Some handy aliases. |
| 119 | |
| 120 | alias cx='chmod +x' |
| 121 | alias which="command -v" |
| 122 | alias rc="rc -l" |
| 123 | rootly () { |
| 124 | case $# in 0) set -- "${SHELL-/bin/sh}" ;; esac |
| 125 | $__MDW_ROOTLY "$@" |
| 126 | } |
| 127 | alias r=rootly |
| 128 | alias re="rootly $EDITOR" |
| 129 | alias pstree="pstree -hl" |
| 130 | alias cdtmp='cd ${TMPDIR-/tmp}' |
| 131 | alias pushtmp='pushd ${TMPDIR-/tmp}' |
| 132 | alias e="$EDITOR" |
| 133 | alias svn="svnwrap svn" |
| 134 | alias @="ssh" |
| 135 | alias make="nice make" |
| 136 | alias gdb="gdb -q" |
| 137 | |
| 138 | ###-------------------------------------------------------------------------- |
| 139 | ### Colour output. |
| 140 | |
| 141 | ## Arrange for `ls' output to be in colour. |
| 142 | if __mdw_programp dircolors; then eval $(dircolors -b "$HOME/.dircolors") |
| 143 | else unset LS_COLORS; fi |
| 144 | |
| 145 | unalias ls 2>/dev/null || : |
| 146 | ls () { |
| 147 | if [ -t 1 ]; then command ls $LS_OPTIONS ${LS_COLORS+--color=auto} "$@" |
| 148 | else command ls "$@"; fi |
| 149 | } |
| 150 | |
| 151 | ## Arrange for `grep' output to be in colour. |
| 152 | export GREP_COLORS="mt=01;31:ms=01;31:mc=031;31:fn=36:ln=36:bn=36:se=34" |
| 153 | |
| 154 | greplike () { |
| 155 | local grep=$1; shift |
| 156 | if [ -t 1 ]; then |
| 157 | command $grep ${GREP_COLORS+--color=always} "$@" | mdw-pager |
| 158 | else |
| 159 | command $grep "$@" |
| 160 | fi |
| 161 | } |
| 162 | alias grep="greplike grep" |
| 163 | alias egrep="greplike egrep" |
| 164 | alias fgrep="greplike fgrep" |
| 165 | alias zgrep="greplike zgrep" |
| 166 | |
| 167 | ## Arrange for `diff' output to be in colour. |
| 168 | export DIFF_COLORS="hd=1:ln=36:ad=32:de=31" |
| 169 | difflike () { |
| 170 | local diff=$1; shift |
| 171 | if [ -t 1 ]; then |
| 172 | command $diff \ |
| 173 | ${DIFF_COLORS+--color=always} \ |
| 174 | ${DIFF_COLORS+--palette="$DIFF_COLORS"} \ |
| 175 | "$@" | mdw-pager |
| 176 | else |
| 177 | command $diff "$@" | cat |
| 178 | fi |
| 179 | } |
| 180 | alias diff="difflike diff" |
| 181 | |
| 182 | ###-------------------------------------------------------------------------- |
| 183 | ### Other hacks. |
| 184 | |
| 185 | ## Turn off pagers inside Emacs shell buffers. |
| 186 | case "$INSIDE_EMACS" in |
| 187 | 2[2-9].*,comint | [3-9][0-9].*,comint) export PAGER=cat ;; |
| 188 | esac |
| 189 | |
| 190 | ###-------------------------------------------------------------------------- |
| 191 | ### More complicated shell functions. |
| 192 | |
| 193 | ## xt [@HOST] XTERM-ARGS |
| 194 | ## |
| 195 | ## Open a terminal, maybe on a remote host. |
| 196 | xt () { |
| 197 | case "$1" in |
| 198 | @*) |
| 199 | local remote=${1#@} title |
| 200 | shift |
| 201 | if [ $# -gt 0 ]; then |
| 202 | title="xterm [$remote] $1" |
| 203 | else |
| 204 | title="xterm [$remote]" |
| 205 | fi |
| 206 | (xterm -title "$title" -e ssh $remote "$@" &) |
| 207 | ;; |
| 208 | *) |
| 209 | (xterm "$@" &) |
| 210 | ;; |
| 211 | esac |
| 212 | } |
| 213 | |
| 214 | ## core [y|n] |
| 215 | ## |
| 216 | ## Tweak core dumps on and off, or show the current status. |
| 217 | core () { |
| 218 | case "x$1" in |
| 219 | xon|xy|xyes) ulimit -Sc $(ulimit -Hc) ;; |
| 220 | xoff|xn|xno) ulimit -Sc 0 ;; |
| 221 | x) |
| 222 | local l=$(ulimit -Sc) |
| 223 | case $l in |
| 224 | 0) echo "Core dumps disabled" ;; |
| 225 | unlimited) echo "Core dumps enabled" ;; |
| 226 | *) echo "Core dump limit is $l blocks" ;; |
| 227 | esac |
| 228 | ;; |
| 229 | *) |
| 230 | echo >&2 "usage: core [y|n]" |
| 231 | return 1 |
| 232 | ;; |
| 233 | esac |
| 234 | } |
| 235 | |
| 236 | ## world [NAME] |
| 237 | ## |
| 238 | ## Set current security world to NAME. With no NAME, print the currently |
| 239 | ## selected world. |
| 240 | world () { |
| 241 | local nfast=${NFAST_HOME-/opt/nfast} |
| 242 | local kmdata |
| 243 | case "$#" in |
| 244 | 0) |
| 245 | echo "${NFAST_KMDATA#$nfast/kmdata-}" |
| 246 | ;; |
| 247 | *) |
| 248 | if [ -d "$1" ]; then |
| 249 | kmdata=$1 |
| 250 | elif [ -d "$nfast/kmdata-$1" ]; then |
| 251 | kmdata=$nfast/kmdata-$1 |
| 252 | else |
| 253 | echo >&2 "world: can't find world $1" |
| 254 | return 1 |
| 255 | fi |
| 256 | shift |
| 257 | case "$#" in |
| 258 | 0) export NFAST_KMDATA=$kmdata ;; |
| 259 | *) "$@" ;; |
| 260 | esac |
| 261 | ;; |
| 262 | esac |
| 263 | } |
| 264 | |
| 265 | ## path-add [VAR] DIR |
| 266 | ## |
| 267 | ## Add DIR to the beginning of PATH-like variable VAR (defaults to PATH) if |
| 268 | ## it's not there already. |
| 269 | path_add () { |
| 270 | local pathvar export dir val |
| 271 | case $# in |
| 272 | 1) pathvar=PATH dir=$1 export="export PATH" ;; |
| 273 | 2) pathvar=$1 dir=$2 export=: ;; |
| 274 | *) echo >&2 "Usage: $0 [VAR] DIR"; return 1 ;; |
| 275 | esac |
| 276 | eval val=\$$pathvar |
| 277 | case ":$val:" in |
| 278 | *:"$dir":*) ;; |
| 279 | *) val=$dir:$val ;; |
| 280 | esac |
| 281 | eval $pathvar=\$val |
| 282 | eval $export |
| 283 | } |
| 284 | |
| 285 | ## path-remove [VAR] DIR |
| 286 | ## |
| 287 | ## Remove DIR from PATH-like variable VAR (defaults to PATH); it's not an |
| 288 | ## error if DIR isn't in VAR. |
| 289 | path_remove () { |
| 290 | local pathvar export dir val |
| 291 | case $# in |
| 292 | 1) pathvar=PATH dir=$1 export="export PATH" ;; |
| 293 | 2) pathvar=$1 dir=$2 export=: ;; |
| 294 | *) echo >&2 "Usage: $0 [VAR] DIR"; return 1 ;; |
| 295 | esac |
| 296 | eval val=\$$pathvar |
| 297 | case ":$val:" in |
| 298 | :"$dir":) val= ;; |
| 299 | :"$dir":*) val=${val#$dir:} ;; |
| 300 | *:"$dir":) val=${val%:$dir} ;; |
| 301 | *:"$dir":*) val=${val%%:$dir:*}:${val#*:$dir:} ;; |
| 302 | esac |
| 303 | eval $pathvar=\$val |
| 304 | eval $export |
| 305 | } |
| 306 | |
| 307 | ## pathhack [-f] +HACK|-HACK... |
| 308 | ## |
| 309 | ## Each HACK refers to a subdirectory of `~/bin/hacks'. A hack name preceded |
| 310 | ## by `+' adds the directory to the PATH; a `-' removes. Adding a hack |
| 311 | ## that's already on the PATH doesn't do anything unless `-f' is set, in |
| 312 | ## which case it gets moved to the beginning. With no arguments, print the |
| 313 | ## currently installed hacks. |
| 314 | pathhack () { |
| 315 | local p e force arg hack dir |
| 316 | p=$PATH |
| 317 | if [ $# -eq 0 ]; then |
| 318 | while :; do |
| 319 | e=${p%%:*} |
| 320 | case "$e" in "$HOME/bin/hacks/"*) echo ${e#$HOME/bin/hacks/} ;; esac |
| 321 | case "$p" in *:*) p=${p#*:} ;; *) break ;; esac |
| 322 | done |
| 323 | return |
| 324 | fi |
| 325 | force=nil |
| 326 | while [ $# -gt 0 ]; do |
| 327 | arg=$1 |
| 328 | case "$arg" in |
| 329 | -f | --force) force=t; shift; continue ;; |
| 330 | --) shift; break ;; |
| 331 | [-+]*) ;; |
| 332 | *) break; ;; |
| 333 | esac |
| 334 | hack=${arg#[+-]} |
| 335 | dir=$HOME/bin/hacks/$hack |
| 336 | if ! [ -d "$dir" ]; then |
| 337 | echo "$0: path hack $hack not found" |
| 338 | return 1 |
| 339 | fi |
| 340 | case "$arg,$force,:$PATH:" in |
| 341 | -*,*,*:"$dir":*) path_remove p "$dir" ;; |
| 342 | +*,t,*:"$dir":*) path_remove p "$dir"; path_add p "$dir" ;; |
| 343 | +*,nil,*:"$dir":*) ;; |
| 344 | +*,*) path_add p "$dir" ;; |
| 345 | esac |
| 346 | shift |
| 347 | done |
| 348 | if [ $# -eq 0 ]; then PATH=$p; export PATH |
| 349 | else PATH=$p "$@"; fi |
| 350 | } |
| 351 | |
| 352 | ###-------------------------------------------------------------------------- |
| 353 | ### Finishing touches. |
| 354 | |
| 355 | ## Make sure `$HOME/bin' is on the path. |
| 356 | path_add "$HOME/bin" |
| 357 | |
| 358 | ## Set the temporary directory again. (A setuid or setgid program may have |
| 359 | ## unhelpfully forgotten this for us.) |
| 360 | case ${TMPDIR+t} in |
| 361 | t) ;; |
| 362 | *) if __mdw_programp tmpdir; then eval $(tmpdir -b); fi ;; |
| 363 | esac |
| 364 | |
| 365 | ## For `root' use -- some simple molly-guards. |
| 366 | case $(id -u) in |
| 367 | 0) |
| 368 | alias rm="rm -i" cp="cp -i" mv="mv -i" |
| 369 | set -o noclobber |
| 370 | ;; |
| 371 | esac |
| 372 | |
| 373 | ## Run any local hooks. |
| 374 | __mdw_source_if_exists "$HOME/.shell-local" |
| 375 | |
| 376 | ###----- That's all, folks -------------------------------------------------- |