# .bashrc
# cayla fauver <[email protected]>
# Created: Sat Sep 17, 2005  07:55PM

# per workstation settings
if [ -e ~.bashrc.local ]; then
    source ~/.bashrc.local   # settings that vary per workstation
fi

if [ "$PS1" ]; then  # If running interactively...

    # Make $HOME comfy
    if [ ! -d "${HOME}/bin" ]; then
        mkdir ${HOME}/bin
        chmod 700 ${HOME}/bin
        echo "${HOME}/bin was missing.  I created it for you."
    fi
    if [ ! -d "${HOME}/tmp" ]; then
        mkdir ${HOME}/tmp
        chmod 700 ${HOME}/tmp
        echo "${HOME}/tmp was missing.  I created it for you."
    fi

    #######################################################################################
    #  color chart:
    #  Black       0;30     Dark Gray     1;30      Blue        0;34     Light Blue    1;34
    #  Red         0;31     Light Red     1;31      Purple      0;35     Light Purple  1;35
    #  Green       0;32     Light Green   1;32      Cyan        0;36     Light Cyan    1;36
    #  Brown       0;33     Yellow        1;33      Light Gray  0;37     White         1;37
    #  No color    0
    red='\[\e[0;31m\]'
    RED='\[\e[1;31m\]'
    blue='\[\e[0;34m\]'
    BLUE='\[\e[1;34m\]'
    cyan='\[\e[0;36m\]'
    CYAN='\[\e[1;36m\]'
    green='\[\e[0;32m\]'
    GREEN='\[\e[1;32m\]'
    yellow='\[\e[0;33m\]'
    YELLOW='\[\e[1;33m\]'
    NC='\[\e[0m\]'

    # prompt & window functions

    function set_xtitle()
    {
        if [[ $TERM == *term* ]]; then
            echo -ne "\033]0;${USER}@${HOSTNAME}: ${PWD}\007"
        fi
    }

    function shrhist()
    {
        history -a $HISTFILE
        history -n $HISTFILE
    }

    function custom_prompt()
    {
        set_xtitle
        shrhist
        PS1="$(ve_prompt_string)$(git_prompt_string)[${red}\t${NC}][${yellow}\u${NC}@${green}\H${NC}:${cyan}\w${NC}]\\$ "
    }

    PROMPT_COMMAND=custom_prompt

    # on exit function
    function _exit()
    {
        echo -e "So long and thanks for all the fish"
    }

    trap _exit EXIT

fi # End interactive bits

# random stuff
ulimit -S -c 0          # Don't want any coredumps
#umask 007
#stty stop undef
#stty start undef

# bash settings
set -o notify                           # notify when jobs running in background terminate
#set -o nounset                          # attempt to use undefined variable outputs error message and forces exit
#set -o xtrace                          # useful for debuging
#set -o ignoreeof                       # can't c-d out of shell
#set -o noclobber                       # prevents catting over file

shopt -s cdable_vars                    # if arg to cd is not a dir assume it is a variable
shopt -s cdspell                        # if arg to cd has a minor typo, fix it automatically
shopt -s checkhash                      # check commands in hash table for existness prior to running
shopt -s checkwinsize                   # update lines and columns if terminal resized
shopt -s cmdhist                        # save all of multiline cmds in history
shopt -s extglob                        # enable extended pattern matching
shopt -s histappend histreedit histverify   # append instead of overwrite, allow re-edit failed sub, verify command execution when pulling from history
shopt -s no_empty_cmd_completion        # no tab completion on otherwise empty lines
shopt -s sourcepath                     # look in the path for any files used as args to source/.
#shopt -u mailwarn                       # notify when mail has been read

# variables
OS=$(uname -s)
export EDITOR="vi"
export VISUAL="vi"
export HISTCONTROL=erasedups
export HISTSIZE=100000
export HISTTIMEFORMAT="%Y-%m-%d %T "
if [ "$TERM" = "screen" ]; then
    export TERM=$TERMINAL
fi

# aliases
if [ "${OS}" == 'Darwin' ]; then
    alias ls="ls -G"
else
    alias ls="ls --color=auto -h"
fi
alias ..="cd .."
alias be="$EDITOR ~/.bashrc;source ~/.bashrc"
alias c="clear"
alias cp="cp -i"
alias df="df -h"
alias la="ls -A"
alias mkdir="mkdir -p"
alias mv="mv -i"
alias path="env | grep PATH"
alias ps="ps aux"
alias rm="rm -i"
alias se="$EDITOR ~/.screenrc"
alias ve="$EDITOR ~/.vimrc"

# PATH
if [ "$UID" -eq 0 ]; then
    PATH=$PATH:/usr/local/bin:/usr/local/sbin:/usr/sbin:/sbin
fi
PATH=$PATH:$HOME/bin

# remove duplicate path entries
export PATH=$(echo $PATH | awk -F: '
{ for (i = 1; i <= NF; i++) arr[$i]; }
END { for (i in arr) printf "%s:" , i; printf "\n"; } ')

# ~/ functions

# common commands piped through grep
function hg()
{
    if [ $# -lt 1 ] || [ $# -gt 1 ]; then
        echo "search bash history"
        echo "usage: hg [search pattern]"
    else
        history | grep -i "$1" | grep -v hg
    fi
}

function psg()
{
    if [ $# -lt 1 ] || [ $# -gt 1 ]; then
        echo "grep running processes"
        echo "usage: psg [process]"
    else
        ps aux | grep USER | grep -v grep
        ps aux | grep -i $1 | grep -v grep
    fi
}

# random useful functions
function apath()
{
    if [ $# -lt 1 ] || [ $# -gt 2 ]; then
        echo "Temporarily add to PATH"
        echo "usage: apath [dir]"
    else
        PATH=$1:$PATH
    fi
}

### virtualenv helpers
wrapsource=$(which virtualenvwrapper.sh)
if [[ -f "$wrapsource" ]]; then
    # Setting up the VirtualEnv
    export WORKON_HOME=$HOME/.virtualenvs
    export VIRTUALENVWRAPPER_PYTHON=$(which python)
    export VIRTUALENVWRAPPER_VIRTUALENV_ARGS='--no-site-packages'
    export PIP_VIRTUALENV_BASE=$WORKON_HOME
    export PIP_RESPECT_VIRTUALENV=true
    source $wrapsource
    if [[ ! $DISABLE_VENV_CD -eq 1 ]]; then
        # Automatically activate Git projects' virtual environments based on the
        # directory name of the project. Virtual environment name can be overridden
        # by placing a .venv file in the project root with a virtualenv name in it
        function workon_cwd {
            # Check that this is a Git repo
            PROJECT_ROOT=$(git rev-parse --show-toplevel 2> /dev/null)
            if (( $? == 0 )); then
                # Check for virtualenv name override
                ENV_NAME=$(basename "$PROJECT_ROOT")
                if [[ -f "$PROJECT_ROOT/.venv" ]]; then
                    ENV_NAME=$(cat "$PROJECT_ROOT/.venv")
                fi
                # Activate the environment only if it is not already active
                if [[ "$VIRTUAL_ENV" != "$WORKON_HOME/$ENV_NAME" ]]; then
                    if [[ -e "$WORKON_HOME/$ENV_NAME/bin/activate" ]]; then
                        workon "$ENV_NAME" && export CD_VIRTUAL_ENV="$ENV_NAME"
                    elif [[ -e "$VIRTUAL_ENV" ]]; then
                        deactivate && unset CD_VIRTUAL_ENV
                    fi
                fi
            elif [ $CD_VIRTUAL_ENV ]; then
                # We've just left the repo, deactivate the environment
                # Note: this only happens if the virtualenv was activated automatically
                deactivate && unset CD_VIRTUAL_ENV
            fi
            unset PROJECT_ROOT
        }

        # New cd function that does the virtualenv magic
        function cd {
            builtin cd "$@" && workon_cwd
        }
    fi
    # for newly split windows check for virtualenv on startup
    workon_cwd
fi

### functions for PS1 
function ve_prompt_string() 
{
    if [ ! -z $VIRTUAL_ENV ]; then
        ve=$(basename $VIRTUAL_ENV)
        echo "(${yellow}${ve}${NC}) "
    fi
}

# Modify the colors and symbols in these variables as desired.
GIT_PROMPT_PREFIX="["
GIT_PROMPT_SUFFIX="${NC}]"
GIT_PROMPT_AHEAD="${red}ANUM${NC}"
GIT_PROMPT_BEHIND="${cyan}BNUM${NC}"
GIT_PROMPT_MERGING="${magenta}⚡︎${NC}"
GIT_PROMPT_UNTRACKED="${red}${NC}"
GIT_PROMPT_MODIFIED="${yellow}${NC}"
GIT_PROMPT_STAGED="${green}${NC}"

# Show Git branch/tag, or name-rev if on detached head
parse_git_branch() {
    (git rev-parse --abbrev-ref HEAD) 2> /dev/null
}

# Show different symbols as appropriate for various Git repository states
parse_git_state() {
    # Compose this value via multiple conditional appends.
    local GIT_STATE=""

    local NUM_AHEAD="$(git log --oneline @{u}.. 2> /dev/null | wc -l | tr -d ' ')"
    if [ "$NUM_AHEAD" -gt 0 ]; then
        GIT_STATE=$GIT_STATE${GIT_PROMPT_AHEAD//NUM/$NUM_AHEAD}
    fi

    local NUM_BEHIND="$(git log --oneline ..@{u} 2> /dev/null | wc -l | tr -d ' ')"
    if [ "$NUM_BEHIND" -gt 0 ]; then
        GIT_STATE=$GIT_STATE${GIT_PROMPT_BEHIND//NUM/$NUM_BEHIND}
    fi

    local GIT_DIR="$(git rev-parse --git-dir 2> /dev/null)"
    if [ -n $GIT_DIR ] && test -r $GIT_DIR/MERGE_HEAD; then
        GIT_STATE=$GIT_STATE$GIT_PROMPT_MERGING
    fi

    if [[ -n $(git ls-files --other --exclude-standard 2> /dev/null) ]]; then
        GIT_STATE=$GIT_STATE$GIT_PROMPT_UNTRACKED
    fi

    if ! git diff --quiet 2> /dev/null; then
        GIT_STATE=$GIT_STATE$GIT_PROMPT_MODIFIED
    fi

    if ! git diff --cached --quiet 2> /dev/null; then
        GIT_STATE=$GIT_STATE$GIT_PROMPT_STAGED
    fi

    if [[ -n $GIT_STATE ]]; then
        echo "$GIT_PROMPT_PREFIX$GIT_STATE$GIT_PROMPT_SUFFIX"
    fi
}

# If inside a Git repository, print its branch and state
git_prompt_string() {
    local git_where="$(parse_git_branch)"
    [ -n "$git_where" ] && echo "$(parse_git_state)$GIT_PROMPT_PREFIX${cyan}${git_where#(refs/heads/|tags/)}$GIT_PROMPT_SUFFIX\n"
}