dot/*: Major shake-up of shell configuration.
authorMark Wooding <mdw@distorted.org.uk>
Sat, 5 Aug 2017 23:56:24 +0000 (00:56 +0100)
committerMark Wooding <mdw@distorted.org.uk>
Sat, 5 Aug 2017 23:56:24 +0000 (00:56 +0100)
Split out the major logic of session startup and shell configuration
into shell-neutral files `dot/profile' and `dot/shell-rc'.  There's a
little support now for pleasant `dash' sessions, but since `dash'
doesn't have a line editor or any way of varying the prompt dynamically,
it's still not marvellous.

Various things which have also been changed:

  * The prompt setup has been heavily refactored.  There's now a piece
    which calculates most of the major pieces, and another piece spliced
    into the shell's command-loop machinery to insert stuff like the Git
    status and previous exit code.  This also takes care of setting and
    clearing the Screen status, so that's much cleaner now.  (In
    particular, this means that Screen doesn't say that it's running
    Bash when it isn't really.)

  * Many of the shell functions have been revised to improve
    portability.  The old hack behind Solaris man(1) has gone
    because (a) it's hard to write portably, and (b) I don't use Solaris
    any more anyway.

dot/bash-profile
dot/bashrc
dot/profile [new file with mode: 0644]
dot/screenrc
dot/shell-logout [moved from dot/bash-logout with 56% similarity]
dot/shell-rc [new file with mode: 0644]
dot/shrc [new file with mode: 0644]
dot/xsession
setup

index 3e84154..7aaf148 100644 (file)
 ### -*-bash-*-
 ###
-### Bash startup things
+### Bash startup things.
 
-## The `.bashrc' hook will run us if it thinks we haven't been run before.
-## We should therefore let it know.
-export __mdw_profile=done
+## Do the common shell profile things.
+. "$HOME/.profile"
 
-###--------------------------------------------------------------------------
-### Utility functions.
-
-## __mdw_addto VAR DIR PATH ...
-##
-## VAR is the name of a PATH-like environment variable (i.e., one which
-## contains a sequence of pathnames separated by colons).  DIR is either `l'
-## or `r'.  The PATHs are pathnames.  Those PATHs which correspond to
-## existing directories but which aren't currently named in the variable are
-## added to the left or right (depending on DIR) of VAR.  The relative order
-## of PATHs added in the same invokation is the same as the order they
-## appeared in PATHs: the DIR argument only affects which end of the VAR they
-## get added to.
-__mdw_addto () {
-  local var=$1 val dir=$2 new="" change=nil
-  eval "val=\$$var"
-  shift 2
-  for i in "$@"; do
-    case "$new:" in *:$i:*) continue;; esac
-    [ -d $i ] || continue
-    case "X$val" in
-      X) val=$i change=t continue ;;
-      X$i) continue ;;
-      X*:$i:*) val=`echo $val | sed -e "s=:$i:=:="` ;;
-      X$i:*) val=${val#$i:} ;;
-      X*:$i) val=${val%:$i} ;;
-    esac
-    new=$new:$i change=t
-  done
-  case $dir in
-    l) val=${new#:}:$val ;;
-    r) val=$val$new ;;
-  esac
-  case $change in t) export $var="$val" ;; esac
-}
-
-## __mdw_programp NAME
-##
-## Does NAME exist as an executable program?
-__mdw_programp () { type -t >/dev/null "$1"; }
-
-###--------------------------------------------------------------------------
-### Other preliminaries.
-
-## Work out my home directory.
-##
-## This horrible trick resolves symbolic links.  It enables resolving links,
-## changes directory and displays the name of the directory in a subshell to
-## avoid changing the current state.
-HOME=`(set -P; cd $HOME; pwd)`
-[ -n "$SCHROOT_SESSION_ID" ] || cd $HOME
-
-## CDE's session structure is demented and doesn't leave us with a proper
-## logout hook, so synthesize one here.
-[ -n "$DT" ] && trap "source $HOME/.bash_logout" EXIT
-
-###--------------------------------------------------------------------------
-### Set some basic paths.
-
-## The main path.
-__mdw_addto PATH l \
-  $HOME/bin \
-  {/usr{/local,}{,/X11R6},}{/bin,/sbin,/games} \
-  /opt/nfast{,/gcc}{/bin,/sbin} \
-  $HOME/src/ncipher/scripts
-
-## If we have Plan 9 from User Space, then add that in.
-if [ -d /usr/local/plan9 ]; then
-  export PLAN9=/usr/local/plan9
-  __mdw_addto PATH r \
-    $PLAN9/bin
-fi
-
-## Search for `info' documents.
-__mdw_addto INFOPATH r \
-       $HOME/info \
-       /usr/info /usr/share/info \
-       /usr/local/info /usr/local/share/info \
-       /usr/local/share/info/its
-
-## Script libraries.
-__mdw_addto PERLLIB r $HOME/lib/perl
-__mdw_addto PYTHONPATH r $HOME/lib/python
-
-###--------------------------------------------------------------------------
-### Various other kinds of configuration.
-
-__mdw_setconf () {
-  if val=$(mdw-conf 2>/dev/null "$2"); then
-    eval "export $1=\$val"
-  fi
-}
-
-## Establish a temporary directory.
-[ "$TMPDIR" ] || eval `tmpdir -b`
-export TMP=$TMPDIR
-
-## Sensible umask if users have their own groups.
-umask 002
-
-## Mail and general identification.
-__mdw_setconf MAIL mailbox
-export NAME="Mark Wooding"
-__mdw_setconf EMAIL email
-export QMAILINJECT=c
-
-## Some programs want to know the hostname.
-[ -z "$HOST" ] && export HOST=`hostname`
-
-## Text editor configuration.
-export MDW_EDITOR=ed
-emacs_startup_args="--no-site-file --mdw-fast-startup -nw"
-for ed in \
-       "emacs23 $emacs_startup_args" \
-       "emacs24 $emacs_startup_args" \
-       "emacs22 $emacs_startup_args" \
-       "emacs21 $emacs_startup_args" \
-       zile mg \
-       "emacs -nw" \
-       vi pico nano ae; do
-  name=`echo $ed | sed 's/ .*$//'`
-  if __mdw_programp "$name"; then
-    MDW_EDITOR=$ed
-    break
-  fi
-done
-export EDITOR=mdw-editor VISUAL=mdw-editor
-
-## Determine the locale settings.  Really don't set LC_COLLATE because it
-## messes with the order of files in `ls' listings and similar.
-if [ "$DISPLAY" != "" ]; then
-  LANG=`mdw-conf x-ctype POSIX`
-else
-  : ${LANG=${LC_CTYPE-${LC_ALL-`mdw-conf console-ctype POSIX`}}}
-  case "$TERM,`tty`" in
-    linux,/dev/tty*)
-      if { vt-is-UTF8 ||
-          kbd_mode | grep UTF-8; } >/dev/null 2>&1; then
-       ctype=.utf8
-      else
-       ctype=
-      fi
-      LANG=${LANG%.*}$ctype
-      ;;
-  esac
-fi
-unset LC_ALL
-export LC_COLLATE=POSIX LANG
-
-## Pager configuration.
-export MDW_PAGER=`type -p less` PAGER=mdw-pager METAMAIL_PAGER=mdw-pager
-export LESS="-iqgRh1j.3FSX"
-export LESSOPEN="|lesspipe.sh %s"
-case "${LC_CTYPE-$LANG}" in
-  *utf8 | *utf-8 | *UTF8 | *UTF-8) LESSCHARSET=utf-8 ;;
-  *) LESSCHARSET=latin1 ;;
-esac
-export LESSCHARSET
-__mdw_programp global && export LESSGLOBALTAGS=global
-
-## HTTP and FTP proxies.
-http=`mdw-conf http-proxy none`
-case "${http_proxy-none},$http" in
-  *,none) ;;
-  none,*) export http_proxy=http://$http/ ;;
+## Bash-specific hack: if we haven't run the `.bashrc' yet, and this shell is
+## interactive, then run it now.
+case ${__mdw_bashrc+t} in
+  t) ;;
+  *) if [ -t 0 ] && [ -r "$HOME/.bashrc" ]; then . "$HOME/.bashrc"; fi ;;
 esac
-ftp=`mdw-conf ftp-proxy none`
-case "${ftp_proxy-none},$ftp,${http_proxy-none}" in
-  *,none,none) ;;
-  none,none,*) export ftp_proxy=$http_proxy ;;
-  none,*,*) export ftp_proxy=http://$ftp/ ;;
-esac
-
-## Ncurses programs should use the Unicode box-drawing characters because the
-## alternative character set stuff isn't supported well.
-export NCURSES_NO_UTF8_ACS=1
-
-## Shut up Perl's readline machinery.
-export PERL_READLINE_NOWARN=yes
-
-## If we have `distcc' then tell `ccache' to use it.
-__mdw_programp distcc && export CCACHE_PREFIX=distcc
-
-## Choose a sensible web browser.  If we have a display, try to pick a
-## graphical one.
-browsers="elinks w3m lynx"
-case "${DISPLAY+t}" in
-  t) browsers="mdw-iceweasel mdw-chrome iceweasel firefox $browsers" ;;
-esac
-for i in $browsers; do
-  if __mdw_programp $i; then
-    export BROWSER=$i
-    break
-  fi
-done
-unset browsers
-
-## Acquiring root privileges.  This is mainly the job of `bashrc', but we
-## cache the mechanism here.
-__mdw_setconf __MDW_ROOTLY rootly
-export BECOME="--preserve-environment"
-
-## It's useful to see the little sigils in `ls'.
-[ -z "$LS_OPTIONS" ] && export LS_OPTIONS="-F"
-
-## Settings for BBC BASIC listing.
-export BASCAT="-l +n"
-
-## Version control hacking.
-export CVS_RSH=ssh
-__mdw_setconf CVSROOT cvs-root
-__mdw_setconf SVNROOT svn-root
-export P4CONFIG=.p4
-
-## News server.
-__mdw_setconf NNTPSERVER nntp-server
-
-## Help X programs find their resources.
-export XUSERFILESEARCHPATH="$HOME/.Xapps/%N:/usr/lib/X11/%T/%N%S"
-
-## Make OpenOffice.org do its thing properly.
-export OOO_FORCE_DESKTOP=gnome
-
-## Hack Qt-ish things to be unstoatly.
-export QT_STYLE_OVERRIDE=gtk2
-
-## Configure `ps'.
-export PS_PERSONALITY=gnu
-
-## Disable core dumps.
-ulimit -S -c 0
-
-###--------------------------------------------------------------------------
-### Authentication and SSH hacking.
-
-## Start an authentication agent.  This is unnecessarily fiddly.  If there's
-## a Gnome keyring server then we should use that; unfortunately, it may not
-## yet have had a chance to populate the environment with its settings, so we
-## go off and fetch them.
-if { { [ "$GNOME_KEYRING_CONTROL" ] &&
-       [ -s "$GNOME_KEYRING_CONTROL" ]; } ||
-     { [ "$DBUS_SESSION_BUS_ADDRESS" ] &&
-       __mdw_programp gnome-keyring-daemon; }; } &&
-   stuff=$(gnome-keyring-daemon -s -c gpg 2>/dev/null)
-then
-  eval "$stuff"
-  export SSH_AUTH_SOCK GPG_AGENT_INFO
-fi
-
-## If we still don't have an agent then start one with a stable name.
-eval `start-ssh-agent -b`
-
-## Decide whether this session should be considered `secure'.  A session is
-## secure if it's on a secure TTY, but there are lots of ways of finding out
-## which TTYs are secure.
-if [ -z "$__mdw_bashrc" ] && [ "$__mdw_force_secure_session" = "yes" ] ||
-   ( tty="`tty`" devtty="(/dev/)?${tty#/dev/}"
-     { { { [ -e /etc/securetty ] && sectty=/etc/securetty; } ||
-        { [ -e /etc/securettys ] && sectty=/etc/securettys; }; } &&
-       egrep "$devtty" $sectty >/dev/null; } ||
-     { [ -e /etc/default/login ] &&
-       egrep "^CONSOLE=$devtty" /etc/default/login >/dev/null; } ||
-     case "${tty#/dev/}" in
-       console|systty|tty[0-9]) true ;;
-       *) false ;;
-     esac )
-then
-  export __mdw_sechost="`hostname`"
-fi
-
-## Start a passphrase pixie if there is one and it's not already running.
-if pixie --version >/dev/null 2>&1; then
-  mkdir -p $HOME/.catacomb
-  pixie=${CATACOMB_PIXIE-$HOME/.catacomb/pixie}
-  if [ -S "$pixie" ] && pixie -C help >/dev/null 2>/dev/null; then
-    :
-  else
-    pixie -d 2>>$HOME/.catacomb/pixie.log
-    __mdw_started_pixie=yes
-  fi
-fi
-
-###--------------------------------------------------------------------------
-### Finishing touches.
-
-## If there's a local hook then run it.
-[ -f "$HOME/.profile-local" ] && . "$HOME/.profile-local"
-
-## If we haven't run the `.bashrc' yet, and this shell is interactive, then
-## run it now.
-[ -z "$__mdw_bashrc" ] && [ -t 0 ] && \
-  [ -r $HOME/.bashrc ] && . $HOME/.bashrc
 
 ###----- That's all, folks --------------------------------------------------
index 8dc678b..6d06f7e 100644 (file)
@@ -1,34 +1,35 @@
 ### -*-bash-*-
 ###
-### Bash session things
+### Bash session things.
+
+__mdw_shell=bash
 
 ## Only do this if we haven't done it before.  (Note that this guard isn't
 ## exported, so subshells will need to make their own arrangements.)
-if [ -z "$__mdw_bashrc" ]; then
-__mdw_bashrc=done
+case ${__mdw_shellrc+t} in
+  t) ;;
+  *) __mdw_shellrc=done
+
+## Fetch the common configuration.
+. "$HOME/.shell-rc"
 
 ## If we've not run the main profile yet, we should do that first.  It sets
 ## up things we rely on.  Also, if there's a system script, we should run
 ## that too.
-[ -z "$__mdw_profile" -a -r $HOME/.bash_profile ] && . $HOME/.bash_profile
-[ -r /etc/bashrc ] && . /etc/bashrc
+case ${__mdw_profile+t} in t) ;; *) . "$HOME/.profile" ;; esac
+__mdw_source_if_exists /etc/bashrc
 
 ## Completion.
-[ -r /etc/bash_completion ] && . /etc/bash_completion
-[ -r $HOME/.bash_completion ] && . $HOME/.bash_completion
+__mdw_source_if_exists /etc/bash_completion "$HOME/.bash_completion"
 
 ## Set the temporary directory again.  (If we've switched users, we'll want a
 ## different temporary directory.)
-[ "${TMPDIR+yes}" ] || eval `tmpdir -b`
+case ${TMPDIR+t} in t) ;; *) eval $(tmpdir -b); esac
 
 ###--------------------------------------------------------------------------
 ### Prompt hacking.
 
-## Only bother if the shell is interactive.
-if [ -t 0 ]; then
-
-  ## Fancy highlighting in some terminals.
-  marker=${STY+'\[\ek\e\\\]'}
+__mdw_set_prompt_hacks () {
   case "$TERM" in
     linux*|screen*|xterm*|vt100*|eterm*)
       case "$(tput bold)" in
@@ -40,52 +41,22 @@ if [ -t 0 ]; then
       uncolour="\[$(tput op)\]"
       nl="\[\r\]"
       ;;
-    *)
-      bold='' unbold='' nl='' gitcolour='' rccolour='' uncolour='';;
   esac
+  host='\h' dir=' \w'
+}
 
-  ## Choose the right delimiters.  Highlight root prompts specially;
-  ## highlight when I'm running as some other user.  Highlight when this
-  ## isn't the outermost shell on the terminal.
-  if (( EUID == 0 )); then
-    left=`echo « | iconv -f UTF-8 -t //translit`
-    right=`echo » | iconv -f UTF-8 -t //translit`
-  else
-    case $USER in
-      mdw|mwooding|nemo) u="" left="[" right="]" ;;
-      *) u="\\u@" left="{" right="}" ;;
-    esac
-    if [ "$__mdw_tty" = "`tty`" ]; then
-      left="<" right=">"
-    else
-      export __mdw_tty="`tty`"
-    fi
-  fi
-
-  ## If this session is insecure then highlight that.
-  if [ -z "$SSH_CLIENT" ] && [ -z "$SCHROOT_CHROOT_NAME" ] &&
-     [ "$__mdw_sechost" != "`hostname`" ]
-  then
-    sec_l='(' sec_r=')'
-  fi
-
-  ## If this is an schroot environment then point this out.
-  hqual=""
-  hqual="$hqual${SCHROOT_CHROOT_NAME+/$SCHROOT_CHROOT_NAME}"
+__mdw_before_cmd_hack () {
+  set -- $(history 1); shift
+  __mdw_preexec "$*"
+}
 
-  ## Build the prompt string.
-  git="" rc=""
-  if [[ ${BASH_VERSINFO[0]} -ge 4 ]]; then
-    if type __git_ps1 >/dev/null 2>&1; then
-      git="$unbold$gitcolour\$(rc=\$?;__git_ps1;exit \$rc)$uncolour$bold"
-    fi
-    rc="$unbold$rccolour\$(rc=\$?;case \$rc in 0);;"
-    rc="$rc*)echo -n \" rc=\$rc\";;esac;exit \$rc)$uncolour$bold"
-  fi
-  PS1="$nl$bold$left$sec_l$u\\h$hqual$sec_r \\w$git$rc$marker$right$unbold"
-  PS2="$PS1 $bold>$unbold "
-  unset nl bold unbold left right sec_l sec_r marker
-  unset gitcolour rccolour uncolour git rc hqual
+## Only bother if the shell is interactive.
+if [ -t 0 ]; then
+  PROMPT_DIRTRIM=5
+  __mdw_source_if_exists /usr/lib/git-core/git-sh-prompt
+  __mdw_set_prompt_pieces
+  PROMPT_COMMAND=__mdw_precmd
+  PS0="\$(__mdw_before_cmd_hack)"
 fi
 
 ###--------------------------------------------------------------------------
@@ -119,283 +90,12 @@ shopt -u shift_verbose
 shopt -s sourcepath
 HISTCONTROL=ignorespace:erasedups
 
-## Some handy aliases.
-alias cx='chmod a+x'
-alias which="command -v"
-alias rc="rc -l"
-alias ssync="rsync -e ssh"
-rootly () {
-  case $# in 0) set -- "${SHELL-/bin/sh}" ;; esac
-  $__MDW_ROOTLY "$@"
-}
-alias r=rootly
-alias re="rootly $EDITOR"
-alias pstree="pstree -hl"
-alias cdtmp='cd ${TMPDIR-/tmp}'
-alias pushtmp='pushd ${TMPDIR-/tmp}'
-alias e="$EDITOR"
-alias svn="svnwrap svn"
-alias @="ssh"
-
-###--------------------------------------------------------------------------
-### Colour output.
-
-## Arrange for `ls' output to be in colour.
-if [ -x /usr/bin/dircolors -o -x /usr/local/bin/dircolors ]; then
-  eval `dircolors -b ~/.dircolors`
-else
-  unset LS_COLORS
-fi
-
-unalias ls 2>/dev/null || :; function ls () {
-  if [ -t 1 ]; then
-    command ls $LS_OPTIONS ${LS_COLORS+--color=auto} "$@"
-  else
-    command ls "$@"
-  fi
-}
-
-## Arrange for `grep' output to be in colour.
-export GREP_COLORS="mt=01;31:ms=01;31:mc=031;31:fn=36:ln=36:bn=36:se=34"
-
-greplike () {
-  declare grep=$1; shift
-  if [ -t 1 ]; then
-    command $grep ${GREP_COLORS+--color=always} "$@" | mdw-pager
-  else
-    command $grep "$@"
-  fi
-}
-alias grep="greplike grep"
-alias egrep="greplike egrep"
-alias fgrep="greplike fgrep"
-alias zgrep="greplike zgrep"
-
-## Turn off pagers inside Emacs shell buffers.
-case "$INSIDE_EMACS" in
-  2[2-9].*,comint | [3-9][0-9].*,comint) export PAGER=cat ;;
-esac
-
-###--------------------------------------------------------------------------
-### More complicated shell functions.
-
-## xt [@HOST] XTERM-ARGS
-##
-## Open a terminal, maybe on a remote host.
-xt () {
-  case "$1" in
-    @*)
-      local remote=${1#@} title
-      shift
-      if [ $# -gt 0 ]; then
-       title="xterm [$remote] $1"
-      else
-       title="xterm [$remote]"
-      fi
-      (xterm -title "$title" -e ssh $remote "$@" &)
-      ;;
-    *)
-      (xterm "$@" &)
-      ;;
-  esac
-}
-
-## core [y|n]
-##
-## Tweak core dumps on and off, or show the current status.
-core () {
-  case "x$1" in
-    xon|xy|xyes) ulimit -Sc `ulimit -Hc` ;;
-    xoff|xn|xno) ulimit -Sc 0 ;;
-    x)
-      local l=`ulimit -Sc`
-      case $l in
-       0) echo "Core dumps disabled" ;;
-       unlimited) echo "Core dumps enabled" ;;
-       *) echo "Core dump limit is $l blocks" ;;
-      esac
-      ;;
-    *)
-      echo >&2 "usage: core [y|n]"
-      return 1
-      ;;
-  esac
-}
-
-## world [NAME]
-##
-## Set current security world to NAME.  With no NAME, print the currently
-## selected world.
-world () {
-  local nfast=${NFAST_HOME-/opt/nfast}
-  local kmdata
-  case "$#" in
-    0)
-      echo "${NFAST_KMDATA#$nfast/kmdata-}"
-      ;;
-    *)
-      if [ -d "$1" ]; then
-       kmdata=$1
-      elif [ -d "$nfast/kmdata-$1" ]; then
-       kmdata=$nfast/kmdata-$1
-      else
-       echo >&2 "world: can't find world $1"
-       return 1
-      fi
-      shift
-      case "$#" in
-       0) export NFAST_KMDATA=$kmdata ;;
-       *) "$@" ;;
-      esac
-      ;;
-  esac
-}
-
-## Fix `man' under Slowaris.
-case "$MACHTYPE" in
-  *solaris*)
-    man () {
-      declare -i i=0
-      declare arg
-      declare -a man
-      for arg; do
-       case "$arg" in [0-9]*) man[i+=1]="-s" ;; esac
-       man[i+=1]="$arg"
-      done
-      command man "${man[@]}"
-    }
-    ;;
-esac
-
-###--------------------------------------------------------------------------
-### Path hacks.
-
-## path-add [VAR] DIR
-##
-## Add DIR to the beginning of PATH-like variable VAR (defaults to PATH) if
-## it's not there already.
-path-add () {
-  local pathvar export dir val
-  case $# in
-    1) pathvar=PATH dir=$1 export="export PATH";;
-    2) pathvar=$1 dir=$2 export=:;;
-    *) echo >&2 "Usage: $0 [VAR] DIR";;
-  esac
-  eval "val=\$$pathvar"
-  case ":$val:" in
-    *:"$dir":*) ;;
-    *) val=$dir:$val ;;
-  esac
-  eval "$pathvar=\$val"
-  $export
-}
-
-## path-remove [VAR] DIR
-##
-## Remove DIR from PATH-like variable VAR (defaults to PATH); it's not an
-## error if DIR isn't in VAR.
-path-remove () {
-  local pathvar export dir val
-  case $# in
-    1) pathvar=PATH dir=$1 export="export PATH";;
-    2) pathvar=$1 dir=$2 export=:;;
-    *) echo >&2 "Usage: $0 [VAR] DIR";;
-  esac
-  eval "val=\$$pathvar"
-  case ":$val:" in
-    :"$dir":) val= ;;
-    :"$dir":*) val=${val#$dir:} ;;
-    *:"$dir":) val=${val%:$dir} ;;
-    *:"$dir":*) val=${val/:$dir:/:} ;;
-  esac
-  eval "$pathvar=\$val"
-  $export
-}
-
-## pathhack [-f] +HACK|-HACK...
-##
-## Each HACK refers to a subdirectory of `~/bin/hacks'.  A hack name preceded
-## by `+' adds the directory to the PATH; a `-' removes.  Adding a hack
-## that's already on the PATH doesn't do anything unless `-f' is set, in
-## which case it gets moved to the beginning.  With no arguments, print the
-## currently installed hacks.
-pathhack () {
-  if [ $# -eq 0 ]; then
-    local IFS=:
-    for e in $PATH; do
-      case "$e" in
-       "$HOME/bin/hacks/"*)
-         echo ${e#$HOME/bin/hacks/}
-         ;;
-      esac
-    done
-    return
-  fi
-  local force=nil
-  local path=$PATH
-  while [ $# -gt 0 ]; do
-    arg=$1
-    case "$arg" in
-      -f | --force)
-       force=t
-       shift
-       continue
-       ;;
-      --)
-       shift
-       break
-       ;;
-      [-+]*)
-       ;;
-      *)
-       break
-       ;;
-    esac
-    hack=${arg#[+-]}
-    dir=$HOME/bin/hacks/$hack
-    [ -d "$dir" ] || {
-      echo "$0: path hack $hack not found"
-      return 1
-    }
-    case "$arg,$force,:$PATH:" in
-      -*,*,*:"$dir":*)
-       path-remove path "$dir"
-       ;;
-      +*,t,*:"$dir":*)
-       path-remove path "$dir"
-       path-add path "$dir"
-       ;;
-      +*,nil,*:"$dir":*)
-       ;;
-      +*,*)
-       path-add path "$dir"
-       ;;
-    esac
-    shift
-  done
-  if [ $# -eq 0 ]; then
-    PATH=$path
-    export PATH
-  else
-    PATH=$path "$@"
-  fi
-}
-
 ###--------------------------------------------------------------------------
 ### Finishing touches.
 
-## For `root' use -- some simple molly-guards.
-if (( UID == 0 )); then
-  alias rm='rm -i' cp='cp -i' mv='mv -i'
-  set -o noclobber
-fi
-
 ## Run any local hooks.
-[ -f "$HOME/.bashrc-local" ] && . "$HOME/.bashrc-local"
-
-## Close the `__mdw_bashrc' guard.
-fi
+__mdw_source_if_exists "$HOME/.bashrc-local"
 
 ###----- That's all, folks --------------------------------------------------
 
-:
+esac
diff --git a/dot/profile b/dot/profile
new file mode 100644 (file)
index 0000000..818ae8a
--- /dev/null
@@ -0,0 +1,317 @@
+### -*-sh-*-
+###
+### Session startup things.
+
+## The shell-specific hook will run us if it thinks we haven't been run
+## before.  We should therefore let it know.
+__mdw_profile=t; export __mdw_profile
+
+###--------------------------------------------------------------------------
+### Utility functions.
+
+## __mdw_addto VAR DIR PATH ...
+##
+## VAR is the name of a PATH-like environment variable (i.e., one which
+## contains a sequence of pathnames separated by colons).  DIR is either `l'
+## or `r'.  The PATHs are pathnames.  Those PATHs which correspond to
+## existing directories but which aren't currently named in the variable are
+## added to the left or right (depending on DIR) of VAR.  The relative order
+## of PATHs added in the same invokation is the same as the order they
+## appeared in PATHs: the DIR argument only affects which end of the VAR they
+## get added to.
+__mdw_addto () {
+  local var=$1 val dir=$2 new="" change=nil
+  eval val=\$$var
+  shift 2
+  for i in "$@"; do
+    case "$new:" in *:$i:*) continue;; esac
+    if ! [ -d $i ]; then continue; fi
+    case "$val" in
+      "") val=$i change=t; continue ;;
+      $i) continue ;;
+      *:$i:*) val=${val%%:$i:*}:${val#*:$i:} ;;
+      $i:*) val=${val#$i:} ;;
+      *:$i) val=${val%:$i} ;;
+    esac
+    new=$new:$i change=t
+  done
+  case $dir in
+    l) val=${new#:}:$val ;;
+    r) val=$val$new ;;
+  esac
+  case $change in t) eval $var=\$val ;; esac
+}
+
+## __mdw_programp NAME
+##
+## Does NAME exist as an executable program?
+__mdw_programp () { type >/dev/null 2>&1 "$1"; }
+
+## __mdw_setconf VAR CONF [DEFAULT]
+##
+## If CONF is defined in `~/.mdw.conf' then set VAR to its value; otherwise,
+## set VAR to DEFAULT, if given; otherwise, do nothing at all.
+__mdw_setconf () {
+  local var=$1 conf=$2 val; shift 2
+  if val=$(mdw-conf 2>/dev/null "$conf" "$@"); then
+    eval "$var=\$val; export $var"
+  fi
+}
+
+###--------------------------------------------------------------------------
+### Other preliminaries.
+
+## Work out my home directory, resolving symbolic links.
+HOME=$(cd "$HOME"; pwd -P)
+case ${SCHROOT_SESSION_ID+t} in t) ;; *) cd "$HOME" ;; esac
+
+## CDE's session structure is demented and doesn't leave us with a proper
+## logout hook, so synthesize one here.
+case ${DT+t} in t) trap "source $HOME/.shell-logout" EXIT; esac
+
+###--------------------------------------------------------------------------
+### Set some basic paths.
+
+## The main path.
+export PATH
+__mdw_addto PATH l \
+  "$HOME"/bin \
+  /usr/local/bin /usr/local/sbin /usr/local/games \
+  /usr/bin /usr/sbin /usr/games \
+  /usr/X11R6/bin /usr/local/X11R6/bin \
+  /bin /sbin \
+  /opt/nfast/bin /opt/nfast/sbin
+
+## If we have Plan 9 from User Space, then add that in.
+if [ -d /usr/local/plan9 ]; then
+  PLAN9=/usr/local/plan9; export PLAN9
+  __mdw_addto PATH r $PLAN9/bin
+fi
+
+###--------------------------------------------------------------------------
+### Some other preliminaries.
+
+## Establish a temporary directory.
+case ${TMPDIR+t} in
+  t) ;;
+  *) if __mdw_programp tmpdir; then eval $(tmpdir -b); fi
+esac
+TMP=$TMPDIR; export TMP
+
+## Sensible umask if users have their own groups.
+umask 002
+
+###--------------------------------------------------------------------------
+### Text editor configuration.
+
+MDW_EDITOR=ed
+emacs_startup_args="--no-site-file --mdw-fast-startup -nw"
+for ed in \
+  "emacs24 $emacs_startup_args" \
+  "emacs23 $emacs_startup_args" \
+  "emacs22 $emacs_startup_args" \
+  "emacs21 $emacs_startup_args" \
+  zile mg \
+  "emacs -nw" \
+  vi pico nano ae
+do
+  name=${ed%% *}
+  if __mdw_programp "$name"; then MDW_EDITOR=$ed; break; fi
+done
+EDITOR=mdw-editor VISUAL=mdw-editor
+export EDITOR VISUAL MDW_EDITOR
+unset ed emacs_startup_args
+
+###--------------------------------------------------------------------------
+### Locale configuration.
+
+case ${DISPLAY+t} in
+  t)
+    __mdw_setconf LANG x-ctype POSIX
+    ;;
+  *)
+    : LANG=${LC_CTYPE-${LC_ALL-$(mdw-conf console-ctype POSIX)}}
+    case "$TERM,$(tty)" in
+      linux,/dev/tty*)
+       if { vt-is-UTF8 || kbd_mode | grep UTF-8; } >/dev/null 2>&1; then
+         ctype=.utf8
+       else
+         ctype=
+       fi
+       LANG=${LANG%.*}$ctype
+       ;;
+    esac
+    ;;
+esac
+unset LC_ALL
+export LANG
+
+LC_COLLATE=POSIX; export LC_COLLATE
+
+###--------------------------------------------------------------------------
+### Pagers.
+
+## Choose a sensible pager.
+MDW_PAGER=more
+for pg in less more; do
+  if __mdw_programp "$pg"; then MDW_PAGER=$(command -v "$pg"); break; fi
+done
+PAGER=mdw-pager METAMAIL_PAGER=mdw-pager
+export MDW_PAGER PAGER METAMAIL_PAGER
+unset pg
+
+## Configure `less'.
+LESS="-iqgRh1j.3FSX"; export LESS
+LESSOPEN="|lesspipe.sh %s"; export LESSOPEN
+case ${LC_CTYPE-$LANG} in
+  *utf8 | *utf-8 | *UTF8 | *UTF-8) LESSCHARSET=utf-8 ;;
+  *) LESSCHARSET=latin1 ;;
+esac
+export LESSCHARSET
+if __mdw_programp global; then
+  LESSGLOBALTAGS=global
+  export LESSGLOBALTAGS
+fi
+
+###--------------------------------------------------------------------------
+### Miscellaneous things.
+
+## Mail and general identification.
+__mdw_setconf MAIL mailbox /var/mail/mdw
+__mdw_setconf EMAIL email mdw@distorted.org.uk
+NAME="Mark Wooding"; export NAME
+
+## News server.
+__mdw_setconf NNTPSERVER nntp-server
+
+## Some programs want to know the hostname.
+case ${HOST+t} in t) ;; *) HOST=$(hostname); export HOST; esac
+
+## HTTP and FTP proxies.
+http=$(mdw-conf http-proxy none)
+case "${http_proxy-none},$http" in
+  *,none) ;;
+  none,*) http_proxy=http://$http/; export http_proxy ;;
+esac
+ftp=$(mdw-conf ftp-proxy none)
+case "${ftp_proxy-none},$ftp,${http_proxy-none}" in
+  *,none,none) ;;
+  none,none,*) ftp_proxy=$http_proxy; export ftp_proxy ;;
+  none,*,*) ftp_proxy=http://$ftp/; export ftp_proxy ;;
+esac
+unset http ftp
+
+## Ncurses programs should use the Unicode box-drawing characters because the
+## alternative character set stuff isn't supported well.
+NCURSES_NO_UTF8_ACS=1; export NCURSES_NO_UTF8_ACS
+
+## Shut up Perl's readline machinery.
+PERL_READLINE_NOWARN=yes; export PERL_READLINE_NOWARN
+
+## If we have `distcc' then tell `ccache' to use it.
+if __mdw_programp distcc; then CCACHE_PREFIX=distcc; export CCACHE_PREFIX; fi
+
+## Choose a sensible web browser.  If we have a display, try to pick a
+## graphical one.
+set -- elinks w3m lynx
+case ${DISPLAY+t} in
+  t) set -- mdw-iceweasel mdw-chrome iceweasel firefox "$@" ;;
+esac
+for b in "$@"; do
+  if __mdw_programp $b; then BROWSER=$b; export BROWSER; break; fi
+done
+unset b
+
+## Acquiring root privileges.  This is mainly the job of `bashrc', but we
+## cache the mechanism here.
+__mdw_setconf __MDW_ROOTLY rootly
+BECOME="--preserve-environment"; export BECOME
+
+## It's useful to see the little sigils in `ls'.
+case ${LS_OPTIONS+t} in t) ;; *) LS_OPTIONS="-F"; export LS_OPTIONS; esac
+
+## Settings for BBC BASIC listing.
+export BASCAT="-l +n"
+
+## Version control hacking.
+CVS_RSH=ssh; export CVS_RSH
+__mdw_setconf CVSROOT cvs-root
+__mdw_setconf SVNROOT svn-root
+P4CONFIG=.p4; export P4CONFIG
+
+## Help X programs find their resources.
+XUSERFILESEARCHPATH="$HOME/.Xapps/%N:/usr/lib/X11/%T/%N%S"
+export XUSERFILESEARCHPATH
+
+## Make OpenOffice.org do its thing properly.
+OOO_FORCE_DESKTOP=gnome; export OOO_FORCE_DESKTOP
+
+## Hack Qt-ish things to be unstoatly.
+QT_STYLE_OVERRIDE=gtk2; export QT_STYLE_OVERRIDE
+
+## Configure `ps'.
+PS_PERSONALITY=gnu; export PS_PERSONALITY
+
+## Disable core dumps.
+ulimit -S -c 0
+
+###--------------------------------------------------------------------------
+### Authentication and SSH hacking.
+
+## Start an authentication agent.  This is unnecessarily fiddly.  If there's
+## a Gnome keyring server then we should use that; unfortunately, it may not
+## yet have had a chance to populate the environment with its settings, so we
+## go off and fetch them.
+if { { [ "$GNOME_KEYRING_CONTROL" ] &&
+       [ -s "$GNOME_KEYRING_CONTROL" ]; } ||
+     { [ "$DBUS_SESSION_BUS_ADDRESS" ] &&
+       __mdw_programp gnome-keyring-daemon; }; } &&
+   stuff=$(gnome-keyring-daemon -s -c gpg 2>/dev/null)
+then
+  eval "$stuff"
+  export SSH_AUTH_SOCK GPG_AGENT_INFO
+fi
+
+## If we still don't have an agent then start one with a stable name.
+eval $(start-ssh-agent -b)
+
+## Decide whether this session should be considered `secure'.  A session is
+## secure if it's on a secure TTY, but there are lots of ways of finding out
+## which TTYs are secure.
+if [ -z "$__mdw_bashrc" ] && [ "$__mdw_force_secure_session" = "yes" ] ||
+   ( tty="`tty`" devtty="(/dev/)?${tty#/dev/}"
+     { { { [ -e /etc/securetty ] && sectty=/etc/securetty; } ||
+        { [ -e /etc/securettys ] && sectty=/etc/securettys; }; } &&
+       egrep "$devtty" $sectty >/dev/null; } ||
+     { [ -e /etc/default/login ] &&
+       egrep "^CONSOLE=$devtty" /etc/default/login >/dev/null; } ||
+     case "${tty#/dev/}" in
+       console|systty|tty[0-9]) true ;;
+       *) false ;;
+     esac )
+then
+  __mdw_sechost=$HOST; export __mdw_sechost
+fi
+
+## Start a passphrase pixie if there is one and it's not already running.
+if pixie --version >/dev/null 2>&1; then
+  mkdir -p "$HOME/.catacomb"
+  pixie=${CATACOMB_PIXIE-$HOME/.catacomb/pixie}
+  if [ -S "$pixie" ] && pixie -C help >/dev/null 2>&1; then
+    :
+  else
+    pixie -d 2>>"$HOME/.catacomb/pixie.log"
+    __mdw_started_pixie=yes
+  fi
+fi
+
+###--------------------------------------------------------------------------
+### Finishing touches.
+
+## For old-fashioned Bourne-ish shells, set up per-shell definitions.
+ENV=$HOME/.shrc; export ENV
+
+## If there's a local hook then run it.
+if [ -f "$HOME/.profile-local" ]; then . "$HOME/.profile-local"; fi
+
+###----- That's all, folks --------------------------------------------------
index c4e7792..e4f4652 100644 (file)
@@ -42,7 +42,6 @@ bindkey -d -a -k fe stuff ^M
 startup_message off
 
 ## Caption and status lines.
-shelltitle ]|bash:
 caption splitonly "%{=br Cb}%?%F%{Yr}%?%3n %t%=%? [%h]%?"
 hardstatus alwayslastline "%{= bC}%-Lw%{+b .Y}%n %t%{-}%+Lw%=%?%E* %?%?%P[] %?%H %Y-%m-%d %c:%s"
 rendition monitor + .R
similarity index 56%
rename from dot/bash-logout
rename to dot/shell-logout
index 25baa3c..c663d90 100644 (file)
@@ -3,4 +3,4 @@
 ### Bash logout things
 
 ## If there's a local hook, then run it.
-[ -f "$HOME/.bash_logout-local" ] && . "$HOME/.bash_logout-local"
+if [ -f "$HOME/.logout-local" ]; then . "$HOME/.logout-local"; fi
diff --git a/dot/shell-rc b/dot/shell-rc
new file mode 100644 (file)
index 0000000..1fa4343
--- /dev/null
@@ -0,0 +1,338 @@
+### -*-sh-*-
+###
+### Common per-shell configuration.
+
+###--------------------------------------------------------------------------
+### Utilities.
+
+__mdw_programp () { type >/dev/null 2>&1 "$1"; }
+
+__mdw_source_if_exists () {
+  local i
+  for i in "$@"; do
+    if [ -r "$i" ]; then . "$i"; fi
+  done
+}
+
+###--------------------------------------------------------------------------
+### Prompt machinery.
+
+__mdw_set_prompt_hacks () { host=$(hostname); dir=""; }
+
+__mdw_set_prompt_pieces () {
+  local hqual
+  hqual=""
+
+  ## Fancy highlighting in some terminals.
+  local bold unbold nl gitcolour rccolour uncolour
+  local host dir
+  bold="" unbold="" nl="" gitcolour="" rccolour="" uncolour=""
+  __mdw_set_prompt_hacks
+
+  ## Choose the right delimiters.  Highlight root prompts specially;
+  ## highlight when I'm running as some other user.  Highlight when this
+  ## isn't the outermost shell on the terminal.
+  local left right user u tty
+  user=${USER-$LOGNAME}
+  case $(id -u) in
+    0)
+      left=$(echo « | iconv -f UTF-8 -t //translit)
+      right=$(echo » | iconv -f UTF-8 -t //translit)
+      ;;
+    *)
+      case $user in
+       mdw | mwooding | nemo) u="" left="[" right="]" ;;
+       *) u="$user@" left="{" right="}" ;;
+      esac
+      tty=$(tty)
+      case "$__mdw_tty" in
+       "$tty") left="<" right=">" ;;
+       *) __mdw_tty=$tty; export __mdw_tty ;;
+      esac
+      ;;
+  esac
+
+  ## If this session is insecure then highlight that.
+  local sec_l sec_r h
+  h=$(hostname)
+  case ${SSH_CLIENT-nil},${SCHROOT_CHROOT_NAME-nil},$__mdw_sechost in
+    nil,nil,"$h") sec_l="" sec_r="" ;;
+    nil,nil,*) sec_l="(" sec_r=")" ;;
+    *) sec_l="" sec_r=""
+  esac
+
+  ## If this is an schroot environment then point this out.
+  hqual="$hqual${SCHROOT_CHROOT_NAME+/$SCHROOT_CHROOT_NAME}"
+
+  ## Put together the main pieces.
+  __mdw_prompt_left="$nl$bold$left$sec_l$u$host$hqual$sec_r$dir"
+  __mdw_prompt_git_left="$unbold$gitcolour"
+  __mdw_prompt_git_right="$uncolour$bold"
+  __mdw_prompt_rc_left="$unbold$rccolour"
+  __mdw_prompt_rc_right="$uncolour$bold"
+  __mdw_prompt_right="$right$unbold"
+}
+
+__mdw_set_prompt () {
+  __mdw_last_rc=$?
+  local git rc
+  if type __git_ps1 >/dev/null 2>&1; then
+    git="$__mdw_prompt_git_left$(__git_ps1)$__mdw_prompt_git_right"
+  else
+    git=""
+  fi
+  case $__mdw_last_rc in
+    0) rc="" ;;
+    *) rc="$__mdw_prompt_rc_left rc=$__mdw_last_rc$__mdw_prompt_rc_right" ;;
+  esac
+  PS1="$__mdw_prompt_left$git$rc$__mdw_prompt_right"
+  PS2="$PS1 $bold>$unbold "
+  unset __mdw_last_rc
+}
+
+__mdw_precmd () {
+  __mdw_set_prompt
+  case ${STY+t} in
+    t) printf "\ek%s\e\\" "$__mdw_shell" ;;
+  esac
+}
+
+__mdw_preexec () {
+  case ${STY+t} in
+    t) printf "\ek%s\e\\" "$1" ;;
+  esac
+}
+
+###--------------------------------------------------------------------------
+### Some handy aliases.
+
+alias cx='chmod +x'
+alias which="command -v"
+alias rc="rc -l"
+rootly () {
+  case $# in 0) set -- "${SHELL-/bin/sh}" ;; esac
+  $__MDW_ROOTLY "$@"
+}
+alias r=rootly
+alias re="rootly $EDITOR"
+alias pstree="pstree -hl"
+alias cdtmp='cd ${TMPDIR-/tmp}'
+alias pushtmp='pushd ${TMPDIR-/tmp}'
+alias e="$EDITOR"
+alias svn="svnwrap svn"
+alias @="ssh"
+
+###--------------------------------------------------------------------------
+### Colour output.
+
+## Arrange for `ls' output to be in colour.
+if __mdw_programp dircolors; then eval $(dircolors -b "$HOME/.dircolors")
+else unset LS_COLORS; fi
+
+unalias ls 2>/dev/null || :
+ls () {
+  if [ -t 1 ]; then command ls $LS_OPTIONS ${LS_COLORS+--color=auto} "$@"
+  else command ls "$@"; fi
+}
+
+## Arrange for `grep' output to be in colour.
+export GREP_COLORS="mt=01;31:ms=01;31:mc=031;31:fn=36:ln=36:bn=36:se=34"
+
+greplike () {
+  local grep=$1; shift
+  if [ -t 1 ]; then
+    command $grep ${GREP_COLORS+--color=always} "$@" | mdw-pager
+  else
+    command $grep "$@"
+  fi
+}
+alias grep="greplike grep"
+alias egrep="greplike egrep"
+alias fgrep="greplike fgrep"
+alias zgrep="greplike zgrep"
+
+###--------------------------------------------------------------------------
+### Other hacks.
+
+## Turn off pagers inside Emacs shell buffers.
+case "$INSIDE_EMACS" in
+  2[2-9].*,comint | [3-9][0-9].*,comint) export PAGER=cat ;;
+esac
+
+###--------------------------------------------------------------------------
+### More complicated shell functions.
+
+## xt [@HOST] XTERM-ARGS
+##
+## Open a terminal, maybe on a remote host.
+xt () {
+  case "$1" in
+    @*)
+      local remote=${1#@} title
+      shift
+      if [ $# -gt 0 ]; then
+       title="xterm [$remote] $1"
+      else
+       title="xterm [$remote]"
+      fi
+      (xterm -title "$title" -e ssh $remote "$@" &)
+      ;;
+    *)
+      (xterm "$@" &)
+      ;;
+  esac
+}
+
+## core [y|n]
+##
+## Tweak core dumps on and off, or show the current status.
+core () {
+  case "x$1" in
+    xon|xy|xyes) ulimit -Sc $(ulimit -Hc) ;;
+    xoff|xn|xno) ulimit -Sc 0 ;;
+    x)
+      local l=$(ulimit -Sc)
+      case $l in
+       0) echo "Core dumps disabled" ;;
+       unlimited) echo "Core dumps enabled" ;;
+       *) echo "Core dump limit is $l blocks" ;;
+      esac
+      ;;
+    *)
+      echo >&2 "usage: core [y|n]"
+      return 1
+      ;;
+  esac
+}
+
+## world [NAME]
+##
+## Set current security world to NAME.  With no NAME, print the currently
+## selected world.
+world () {
+  local nfast=${NFAST_HOME-/opt/nfast}
+  local kmdata
+  case "$#" in
+    0)
+      echo "${NFAST_KMDATA#$nfast/kmdata-}"
+      ;;
+    *)
+      if [ -d "$1" ]; then
+       kmdata=$1
+      elif [ -d "$nfast/kmdata-$1" ]; then
+       kmdata=$nfast/kmdata-$1
+      else
+       echo >&2 "world: can't find world $1"
+       return 1
+      fi
+      shift
+      case "$#" in
+       0) export NFAST_KMDATA=$kmdata ;;
+       *) "$@" ;;
+      esac
+      ;;
+  esac
+}
+
+## path-add [VAR] DIR
+##
+## Add DIR to the beginning of PATH-like variable VAR (defaults to PATH) if
+## it's not there already.
+path_add () {
+  local pathvar export dir val
+  case $# in
+    1) pathvar=PATH dir=$1 export="export PATH" ;;
+    2) pathvar=$1 dir=$2 export=: ;;
+    *) echo >&2 "Usage: $0 [VAR] DIR"; return 1 ;;
+  esac
+  eval val=\$$pathvar
+  case ":$val:" in
+    *:"$dir":*) ;;
+    *) val=$dir:$val ;;
+  esac
+  eval $pathvar=\$val
+  eval $export
+}
+
+## path-remove [VAR] DIR
+##
+## Remove DIR from PATH-like variable VAR (defaults to PATH); it's not an
+## error if DIR isn't in VAR.
+path_remove () {
+  local pathvar export dir val
+  case $# in
+    1) pathvar=PATH dir=$1 export="export PATH" ;;
+    2) pathvar=$1 dir=$2 export=: ;;
+    *) echo >&2 "Usage: $0 [VAR] DIR"; return 1 ;;
+  esac
+  eval val=\$$pathvar
+  case ":$val:" in
+    :"$dir":) val= ;;
+    :"$dir":*) val=${val#$dir:} ;;
+    *:"$dir":) val=${val%:$dir} ;;
+    *:"$dir":*) val=${val%%:$dir:*}:${val#*:$dir:} ;;
+  esac
+  eval $pathvar=\$val
+  eval $export
+}
+
+## pathhack [-f] +HACK|-HACK...
+##
+## Each HACK refers to a subdirectory of `~/bin/hacks'.  A hack name preceded
+## by `+' adds the directory to the PATH; a `-' removes.  Adding a hack
+## that's already on the PATH doesn't do anything unless `-f' is set, in
+## which case it gets moved to the beginning.  With no arguments, print the
+## currently installed hacks.
+pathhack () {
+  local p e force arg hack dir
+  p=$PATH
+  if [ $# -eq 0 ]; then
+    while :; do
+      e=${p%%:*}
+      case "$e" in "$HOME/bin/hacks/"*) echo ${e#$HOME/bin/hacks/} ;; esac
+      case "$p" in *:*) p=${p#*:} ;; *) break ;; esac
+    done
+    return
+  fi
+  force=nil
+  while [ $# -gt 0 ]; do
+    arg=$1
+    case "$arg" in
+      -f | --force) force=t; shift; continue ;;
+      --) shift; break ;;
+      [-+]*) ;;
+      *) break; ;;
+    esac
+    hack=${arg#[+-]}
+    dir=$HOME/bin/hacks/$hack
+    if ! [ -d "$dir" ]; then
+      echo "$0: path hack $hack not found"
+      return 1
+    fi
+    case "$arg,$force,:$PATH:" in
+      -*,*,*:"$dir":*) path_remove p "$dir" ;;
+      +*,t,*:"$dir":*) path_remove p "$dir"; path_add p "$dir" ;;
+      +*,nil,*:"$dir":*) ;;
+      +*,*) path_add p "$dir" ;;
+    esac
+    shift
+  done
+  if [ $# -eq 0 ]; then PATH=$p; export PATH
+  else PATH=$p "$@"; fi
+}
+
+###--------------------------------------------------------------------------
+### Finishing touches.
+
+## For `root' use -- some simple molly-guards.
+case $(id -u) in
+  0)
+    alias rm="rm -i" cp="cp -i" mv="mv -i"
+    set -o noclobber
+    ;;
+esac
+
+## Run any local hooks.
+__mdw_source_if_exists "$HOME/.shell-local"
+
+###----- That's all, folks --------------------------------------------------
diff --git a/dot/shrc b/dot/shrc
new file mode 100644 (file)
index 0000000..90710df
--- /dev/null
+++ b/dot/shrc
@@ -0,0 +1,23 @@
+### -*-sh-*-
+
+## Fetch the common configuration.
+. "$HOME/.shell-rc"
+
+###--------------------------------------------------------------------------
+### Prompt hacking.
+
+__mdw_set_prompt_hacks () {
+  case "$TERM" in
+    linux*|screen*|xterm*|vt100*|eterm*)
+      case "$(tput bold)" in
+       "") bold="$(tput md)" unbold="$(tput me)" ;;
+       *) bold="$(tput bold)" unbold="$(tput sgr0)" ;;
+      esac
+      ;;
+  esac
+  host=$(hostname)
+  dir=""
+}
+
+__mdw_set_prompt_pieces
+__mdw_set_prompt
index 4497b21..af2cd7c 100755 (executable)
@@ -1,8 +1,8 @@
-#! /bin/bash
+#! /bin/sh
 
 # --- Lots of sensible initialisation ---
 
 __mdw_force_secure_session=yes
-. $HOME/.bash_profile
-$HOME/.xinitrc
-. $HOME/.bash_logout
+. "$HOME/.profile"
+"$HOME/.xinitrc"
+. "$HOME/.shell-logout"
diff --git a/setup b/setup
index b6b7066..622aac2 100755 (executable)
--- a/setup
+++ b/setup
@@ -131,8 +131,10 @@ fi
 
 ## Symlink the various dotfiles into place
 dotfiles="
-  bash-profile:.bash_profile bash-logout:.bash_logout
+  profile shell-rc shell-logout
+  bash-profile:.bash_profile
   bash-completion:.bash_completion bashrc inputrc
+  shrc
   emacs emacs-calc vm gnus.el ercrc.el
   vimrc mg zile lesskey sqliterc
   parallel-config:.parallel/config