#!/bin/bash
# ------------------------------------------------------------------------------
# Aliases
#
# --- a bit of fiddling about
uname=`uname`
[[ `uname` == SunOS && `uname -r` == 5.* ]] && uname=Solaris

case "$uname" in
SunOS | Solaris)
        alias pr='/usr/5bin/pr'
        alias ar='/usr/5bin/ar'
        # alias ls='/usr/5bin/ls'
        ;;
*)
        ;;
esac

# --- standard stuff
alias h=history
alias a=alias
alias d=type

# ------------------------------------------------------------------------------

# path manipulation

SHOWPATH () { [[ $# == 0 ]] && echo "SHOWPATH colon-paths" && return;
              echo "$1" | tr : "\n" | (
              i=0
              while read d; do
                printf "%3d %s" $i "$d";
                [[ -d "$d" ]] || printf " (not found)";
                echo "";
                i=$((i + 1))
              done ); }
alias path='SHOWPATH "$PATH"'
alias libpath='SHOWPATH "$LD_LIBRARY_PATH"'
alias manpath='SHOWPATH "$MANPATH"'
alias showpath='SHOWPATH'

ADDPATH () { [[ $# == 0 ]] && \
             echo "ADDPATH path-env-var new-tails" 1>&2 && \
             echo "(see also PATHADD for new heads)" 1>&2 && \
             return 1;
             local p="$1"; shift; export $p=$(buildpath "${!p}" "$@"); }
PATHADD () { [[ $# == 0 ]] && \
             echo "PATHADD env-var new-heads" 1>&2 && \
             echo "(see also ADDPATH for new tails)" 1>&2 && \
             return 1;
             local p="$1"; shift; export $p=$(buildpath "$@" "${!p}"); }
alias addpath=ADDPATH
alias pathadd=PATHADD


REMPATH ()
  { [[ $# == 0 ]] && echo "REMPATH env-var dirs-to-remove" 1>&2 && return 1;
    local p op d;
    p="$1"; shift; op="<:${!p}:>"; for d in "$@"; do op=${op//:${d}:/:}; done;
    op="${op//<:/}"; op="${op/:>/}"; export $p="$op"; }
alias rempath=REMPATH

alias addcdpath='ADDPATH CDPATH'
alias addxpath='ADDPATH PATH'
alias addmanpath='ADDPATH MANPATH'
alias addlibpath='ADDPATH LD_LIBRARY_PATH'

# ------------------------------------------------------------------------------

# --- named-char/hex dump (if you want non-named chars use "od -tcxC")
alias xd='od -taxC'

alias del='rm -i'
alias cls='tput clear'
alias cwd='echo $PWD'

psf  () { ps -ef | grep "$@" | grep -v grep; }
psu  () { ps -fu "$USER"; }
psuf () { ps -fu "$USER" | grep "$@" | grep -v grep; }

# ------------------------------------------------------------------------------

# --- list all normal files in the directories passed as parameters
files ()
  {
  (
  [[ $# == 0 ]] && set .
  for dir in "$@"; do
    [[ ! -d "$dir" ]] && echo "'$dir' is not a directory" 1>&2 && return 1
    [[ ! -r "$dir" ]] && echo "'$dir' is not readable"    1>&2 && return 1
  done
  for dir in "$@"; do
    for file in "$dir"/*; do
      fname=${file#./}
      [[ -f "$fname" ]] && echo "$fname"
    done
  done
  )
  }

# ------------------------------------------------------------------------------

# --- finding things - file names

# helper functions for name matches:
# expands a group of patterns as find(1) alternatives, with '-o's between them
# into the shell array pats
find_makepats()
  {
  local s="(" m="" n="" i=0
  for n in "$@"; do
    # bash could do the next line as: pats[i++]="$s"
    # we do things this way for ksh
    pats[i=i+1]="$s"
    pats[i=i+1]="-name"
    pats[i=i+1]="$n"
    s="-o";
  done
  [[ ${#pats[@]} > 0 ]] && pats[i=i+1]=")";
  }
# executing a command (for normal files only) - you need to include {}
find_exec ()
  {
    (
      if [[ -z "$1" ]]; then
        return 1
      fi
      unset pats
      declare -a pats
      set -o noglob;
      eval "find_makepats $1"
      shift;
      # set -o noglob;
      find . -type f "${pats[@]}" -exec "$@" \; ;
    )
  }
# general find things in files: $1 is file pattern, $2-$ are grep things
find_grep () { local p="${1:?'Arguments: patterns grep-arg grep-arg...'}";
               shift; find_exec "$p" grep "$@" {} /dev/null; }


# use the helper in these
ff     () { ( find_makepats "$@"; find * "${pats[@]}" -print ); }
ffl    () { ( find_makepats "$@"; find . "${pats[@]}" -exec ls -ld {} ';' ); }
fff    () { ( find_makepats "$@"; find "$PWD" "${pats[@]}" -print ); }
ffd    () { ( find_makepats "$@"; find "$PWD" -type d "${pats[@]}" -print ); }
ffr    () { ( p="${1:?'usage: ffr start-dir [name-pattern]'}"; shift;
              find_makepats "$@"; find "$p" "${pats[@]}" -print ); }

if [[ $BASHRC_SHELL == bash ]]; then
  ff.  () { ( find_makepats "$@"; find . "${pats[@]}" -print ); }
  fff. () { ( find_makepats "$@"; find "`pwd -p`" "${pats[@]}" -print ); }
fi

# removing files
ffrm   () { ( find_makepats "$@"; find . "${pats[@]}" -exec rm {} ';' ); }
ffrmi  () { ( find_makepats "$@"; find . "${pats[@]}" -exec rm -i {} ';' ); }

# executing for all files - the command receives the file as the last argument
ffx () { find_exec "$@" '{}'; }

f  () { local p="$1"; shift; find_grep "$p" -n "$@"; }
qf () { local p="$1"; shift; find_grep "$p" -l "$@"; }
fI () { local p="$1"; shift; find_grep "$p" -ni "$@"; }
fq () { local p="$1"; shift; find_grep "$p" -l "$@"; }

# provide help!
ffh ()
{
    cat <<-EnD
Finding files: these functions pass the list of patterns to find(1)
  ff      patterns... - find files starting in * (no hidden directories in PWD)
  ffl     patterns... - find files starting from ., executes ls -ld for each one
  fff     patterns... - find files from \$PWD; this gives full file paths
  ffd     patterns... - find only directories from \$PWD
  ffr dir patterns... - find files starting from directory dir
EnD
[[ $BASHRC_SHELL == bash ]] && cat <<-EnD
  ff.     patterns... - find files starting from . (allows hidden directories)
  fff.    patterns... - find files from \`pwd -p\`; also gives full file paths
EnD
cat <<-EnD

Removing files
  ffrm    patterns... - remove matching files, searching from .
  ffrmi   patterns... - interactively remove matching files searching from .

Executing commands for files matching a single pattern:
  ffx pattern command - issue command for each file found, with the file name as
                        the last argument

Executing grep for a search string on files matching a single pattern:
  f   pattern search  - calls 'grep -n search' (lists file name and line number)
  qf  pattern search  - calls 'grep -l search' (lists matching file names only)
  fI  pattern search  - calls 'grep -ni search' (like f, but case-indifferent)
  fq  pattern search  - calls 'grep -l search' (lists matching file names only)
EnD
}

# functions for producing file patterns for C/C++ development
CFilePats   () { echo '*.[cC] *.cpp *.CPP *.cxx *.CXX *.cc *.CC *.[cC]++'; }
HFilePats   () { echo '*.[hH] *.hpp *.HPP *.hxx *.HXX *.hh *.HH *.[hH]++'; }
IFilePats   () { echo '*.[iI] *.[iI][[nN][cC] *.[iI][nN][lL] *.[iI]++'; }
CHFilePats  () { echo $(CFilePats; HFilePats); }
CHIFilePats () { echo $(CHFilePats; IFilePats); }
JFilePats   () { echo '*.[jJ][aA][vV][aA]'; }

alias nocaseandnull='shopt -s nullglob nocaseglob'

# specialised instances for finding things in C source files
alias    fh='f "`HFilePats`"'
alias    fc='f "`CFilePats`"'
alias   fch='f "`CHFilePats`"'
alias  fchi='f "`CHIFilePats`"'
# specialised instances for finding things in C source files - case insensitive
alias   fih='fI "`HFilePats`"'
alias   fic='fI "`CFilePats`"'
alias  fich='fI "`CHFilePats`"'
alias fichi='fI "`CHIFilePats`"'
# and java?
alias    fj='f "`JFilePats`"'
alias fjava='f "`JFilePats`"'
alias   fij='fI "`JFilePats`"'
alias fijava='fI "`JFilePats`"'

# finding and editing things
# in C files or in all files (in this directory)
vif   () { p="$1"; shift; vi +/"$p" $(grep -l "$p" "$@"); }
vig   () { vi +/"$*" $(nocaseandnull; eval "grep -l $* `CHFilePats`"); }
vigc  () { vi +/"$*" $(nocaseandnull; eval "grep -l "$*" `CFilePats`"); }
vigh  () { vi +/"$*" $(nocaseandnull; eval "grep -l "$*" `HFilePats`"); }
viga  () { vi +/"$*" $(nocaseandnull; eval "grep -l "$*" *"); }
vigg  () { vi +/"$*" $(nocaseandnull; eval "grep -l "$*" `CHIFilePats`"); }
# recursive find and edit aliases
vifr   () { p="$1"; shift; vi +/"$p" $(fq "$@" "$p"); }
vigr   () { vi +/"$*" $(fq "`CHFilePats`" "$*"); }
vigrc  () { vi +/"$*" $(fq "`CFilePats`" "$*"); }
vigrh  () { vi +/"$*" $(fq "`HFilePats`" "$*"); }
vigra  () { vi +/"$*" $(fq "*" "$*"); }
vigrg  () { vi +/"$*" $(fq "`CHIFilePats`" "$*"); }

alias vig++=vigg
alias vigr++=vigrg

# --- other stuff
display () { export DISPLAY=$1 ; }
alias sd='echo export DISPLAY=$DISPLAY'

if [[ $BASHRC_SHELL == bash ]]; then
  = () { echo 'scale = 8; ' "$@" | bc -l; }
else
  calc () { echo 'scale = 8; ' "$@" | bc -l; }
fi

# --- DISPLAY?
if [[ -n "$DISPLAY" ]]; then
  # ha! NEdit!
  alias ned='nc -noask '
fi

# --- use of par - see http://www.nicemice.net/par/
export PARINIT='rTbgqR B=.,?_A_a Q=_s>|'

# ------------------------------------------------------------------------------

# do we have the jad Java decompiler?
if type jad > /dev/null 2>&1; then
    alias jad='jad -v -b -nonlb -o -space -s .d.java'
fi

# ------------------------------------------------------------------------------
# Extra aliases
#
# --- Makes it all a bit slower

for aliaspath in ~ ~/.util; do
  # check out any .aliasrc files
  if [[ -r $aliaspath/.bashaliasrc ]]; then
    . $aliaspath/.bashaliasrc
  fi
done
unset aliaspath
