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