# .zshrc
# cayla fauver <[email protected]>
# Created: Sat Aug 20, 2011 01:16AM

#setopt XTRACE VERBOSE

if [ ! "$PS1" ]; then  # If not running interactively...
    exit 0
fi

### Bootstaps and Includes
OS=$(uname)
test -e "${HOME}/.zshrc.local" && source "${HOME}/.zshrc.local"
test -e "${HOME}/.zshrc.personal" && source "${HOME}/.zshrc.personal"
test -d "$HOME/.zsh/functions" && fpath=($HOME/.zsh/functions $fpath)
test -d "/usr/local/share/zsh-completions" && fpath=(/usr/local/share/zsh-completions $fpath)
test -d "/usr/local/share/zsh/site-functions" && fpath=(/usr/local/share/zsh/site-functions $fpath)
for ZSH_PLUGIN in ~/.zsh/plugins/*.zsh      # extra zsh functionality.  prompts, etc
do
    source $ZSH_PLUGIN
done

### Path
PATH=$HOME/bin:/usr/local/opt/gnupg@2.1/bin:/usr/local/bin:/usr/local/sbin:/usr/sbin:/sbin:$PATH
# And then 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"; } ')

### Autoloads
autoload -Uz compinit
compinit
autoload -Uz colors
colors
# prompt
autoload -Uz promptinit
promptinit
prompt rainbows
# smart escapes in git dirs
autoload -Uz git-escape-magic
git-escape-magic

### Exports & Settings
export EDITOR="vim"
export GREP_COLOR='1;32'
export GROFF_NO_SGR=1
export HISTFILE=~/.zhistory
export HISTSIZE=10000
export LANG=en_US.UTF-8
export LESS=-RFX
export LESS_TERMCAP_mb=$'\E[0;34m'      # begin blinking
export LESS_TERMCAP_md=$'\E[0;34m'      # begin bold
export LESS_TERMCAP_me=$'\E[0m'         # end mode
export LESS_TERMCAP_se=$'\E[0m'         # end standout-mode
export LESS_TERMCAP_so=$'\E[01;47;34m'  # begin standout-mode - info box
export LESS_TERMCAP_ue=$'\E[0m'         # end underline
export LESS_TERMCAP_us=$'\E[01;34m'     # begin underline
export LISTMAX=200
if [[ "$OS" == "Darwin" ]]; then
    export LSCOLORS='gxfxcxdxbxegedabagacad'
else
    export LS_COLORS='di=36:ln=35:so=32:pi=33:ex=31:bd=34;46:cd=34;43:su=30;41:sg=30;46:tw=30;42:ow=30;43'
fi
export PAGER="less"
export SAVEHIST=10000

# make ctrl-w work on path components
local WORDCHARS=${WORDCHARS//\//}

### options
# auto directory pushd that you can get dirs list by cd -[tab]
setopt AUTO_PUSHD
# Resume jobs after typing it's name
setopt AUTO_RESUME
# Dont quit console if processes are running
setopt CHECK_JOBS
# Allow tab completion in the middle of a word
setopt COMPLETE_IN_WORD
# Spell correct commands
setopt CORRECT
# Regular expressions in files
#setopt EXTENDED_GLOB
# Ignore duplicates in history
setopt HIST_IGNORE_ALL_DUPS
# Prevent record in history entry if preceding them with at least one space
setopt HIST_IGNORE_SPACE
# Append command to history file once executed
setopt INC_APPEND_HISTORY
# Nobody needs flow control anymore. Troublesome feature.
setopt NOFLOW_CONTROL
# If set, parameter expansion, command substitution and arithmetic
# expansion are performed in prompts. Substitutions within prompts do
# not affect the command status.
setopt PROMPT_SUBST
# Do not query the user before executing ‘rm *’ or ‘rm path/*’.
setopt RM_STAR_SILENT
# for sharing history between zsh processes
setopt SHARE_HISTORY

### Aliases
alias c="clear"
alias cp="cp -i"
alias df="df -h"
alias gpg="gpg2"
if [[ "$OS" == "Darwin" ]]; then
    alias ls="ls -G"
else
    alias ls="ls --color=auto -h"
fi
alias macvim="open -a MacVim"
alias mkdir="mkdir -p"
alias mv="mv -i"
alias myip="dig +short myip.opendns.com @resolver1.opendns.com"
alias path="env | grep PATH"
alias ps="ps aux"
alias rm="rm -i"
alias se="$EDITOR ~/.screenrc"
alias sr="screen -d -RR"
alias tme="$EDITOR ~/.tmux.conf"
alias tmr="tmux attach || tmux"
alias upgrade="apt-get update;apt-get upgrade -y"
alias ve="$EDITOR ~/.vimrc"
alias vep="$EDITOR ~/.vim/vimrc.personal"
alias vi="vim"
alias xmas="perl -MAcme::POE::Tree -e 'Acme::POE::Tree->new()->run()'"
alias ze="$EDITOR ~/.zshrc;source ~/.zshrc"
alias zel="$EDITOR ~/.zshrc.local;source ~/.zshrc"
alias zep="$EDITOR ~/.zshrc.personal;source ~/.zshrc"

### Bindings
bindkey -e
bindkey '\C-x\C-e'  edit-command-line                           # ctrl-x,ctrl-e
bindkey "^R"        history-incremental-pattern-search-backward # ctrl + r
bindkey "^[[3~"     delete-char                                 # del
bindkey "\033[3~"   delete-char                                 # del (macs only?)
bindkey "\e[1~"     beginning-of-line                           # home
bindkey "\033[H"    beginning-of-line                           # home (macs only?)
bindkey "\e[4~"     end-of-line                                 # end
bindkey "\033[F"    end-of-line                                 # end (macs only?)
# bindkey "^[d"       kill-word                                   # ctrt + d
# bindkey "^[>"       end-of-buffer-or-history                    # alt-shift->

### Completion
zstyle ':completion:*' menu select
zstyle ':completion:*' verbose yes
if [[ "$OS" == "Darwin" ]]; then
    zstyle ':completion:*:default' list-colors ${(s.:.)LSCOLORS}
    zstyle ':completion:*' list-colors ${(s.:.)LSCOLORS}
else
    zstyle ':completion:*:default' list-colors ${(s.:.)LS_COLORS}
    zstyle ':completion:*' list-colors ${(s.:.)LS_COLORS}
fi
# Expansion options
zstyle ':completion:*' completer _complete _prefix _expand _approximate
zstyle ':completion::prefix-1:*' completer _complete
zstyle ':completion:incremental:*' completer _complete _correct
zstyle ':completion:predict:*' completer _complete
# Separate matches into groups
zstyle ':completion:*:matches'  group 'yes'
zstyle ':completion:*'          group-name ''
zstyle ':completion:*:messages' format '%d'
# Messages/warnings format
zstyle ':completion:*:messages' format '%B%U---- %d%u%b'
# set format for warnings
zstyle ':completion:*:warnings' format $'%{\e[0;31m%}No matches for:%{\e[0m%} %d'
# Describe options in full
zstyle ':completion:*:options' description 'yes'
zstyle ':completion:*:options' auto-description '%d'
# Nicer completion
zstyle ':completion:*:descriptions' format '%U%B%d%b%u'
zstyle ':completion:*:warnings' format '%BSorry, no matches for: %d%b'
# tab completion for PID
zstyle ':completion:*:*:kill:*' menu yes select
zstyle ':completion:*:kill:*' force-list always
zstyle ':completion:*:*:killall:*' menu yes select
zstyle ':completion:*:killall:*' force-list always
# format on completion
zstyle ':completion:*:descriptions'    format $'%{\e[0;31m%}completing %B%d%b%{\e[0m%}'
# insert all expansions for expand completer
zstyle ':completion:*:expand:*'        tag-order all-expansions
zstyle ':completion:*:history-words'   list false
# match uppercase from lowercase
zstyle ':completion:*'                 matcher-list 'm:{a-z}={A-Z}'
# offer indexes before parameters in subscripts
zstyle ':completion:*:*:-subscript-:*' tag-order indexes parameters
# define files to ignore for zcompile
zstyle ':completion:*:*:zcompile:*'    ignored-patterns '(*~|*.zwc)'
zstyle ':completion:correct:'          prompt 'correct to: %e'
# Ignore completion functions for commands you don't have:
zstyle ':completion::(^approximate*):*:functions' ignored-patterns '_*'
zstyle ':completion:*:complete:-command-::commands' ignored-patterns '*\~'

### Functions
function aptg() {
    if [ $# -lt 1 ] || [ $# -gt 1 ]; then
        echo "search debian package list"
        echo "usage: aptg [program/keyword]"
    else
        apt-cache search $1 | sort | less
    fi
}

function h()
{
    if [ -z "$*" ]; then
        history 1;
    else
        history 1 | egrep "$@";
    fi;
}

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

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

function ff() {
    if [ $# -ne 1 ]; then
        echo "use one argument to specify the filename"
    else
        find . -name $1
    fi
}

function fo() {
    if [ $# -ne 1 ]; then
        echo "use one argument to specify the filename"
    else
        find . -name $1 -exec open -a MacVim.app {} \;
    fi
}

function view_cert() {
    if [ $# -ne 1 ]; then
        echo "use one argument to specify the hostname"
    else
        echo | openssl s_client -showcerts -servername $1 -connect ${1}:443 2>/dev/null | openssl x509 -inform pem -noout -text
    fi
}

function zsrc() {
    autoload -U zrecompile
    [[ -f ~/.zshrc ]] && zrecompile -p ~/.zshrc
    [[ -f ~/.zcompdump ]] && zrecompile -p ~/.zcompdump
    [[ -f ~/.zcompdump ]] && zrecompile -p ~/.zcompdump
    [[ -f ~/.zshrc.zwc.old ]] && rm -f ~/.zshrc.zwc.old
    [[ -f ~/.zcompdump.zwc.old ]] && rm -f ~/.zcompdump.zwc.old
    source ~/.zshrc
}

### virtualenv helper
wrapsource=$(which virtualenvwrapper.sh)
if [[ -f "$wrapsource" ]]; then
    export PIP_RESPECT_VIRTUALENV=true
    export PIP_VIRTUALENV_BASE=$WORKON_HOME
    export VIRTUALENVWRAPPER_PYTHON=$(which python)
    export VIRTUALENVWRAPPER_VIRTUALENV_ARGS='--no-site-packages'
    export VIRTUAL_ENV_DISABLE_PROMPT=1
    export WORKON_HOME=$HOME/.virtualenvs
    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

function mk_ve_cwd () {
    mkvirtualenv $(basename "$PWD")
}

### Startup, title and exit settings
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
if [ ! -d "${HOME}/.ssh/tmp" ]; then
    mkdir -p ${HOME}/.ssh/tmp
    chmod 700 ${HOME}/.ssh/tmp
    echo "${HOME}/.ssh/tmp was missing.  I created it for you."
fi

case $TERM in
    *xterm*)
        precmd () {print -Pn "\e]0;%n@%M\a"}
        ;;
    *screen*)
        preexec () {printf "\033k$(hostname)-${~1:gs/%/%%}\033\\"}
        precmd () {printf "\033k$(hostname)$0\033\\"}
        ;;
esac

if [ -e "/usr/bin/uptime" ]; then
    echo "Uptime: ` /usr/bin/uptime`"
fi
# bsd (macos) pgrep doesn't have a -c option
if [ $(pgrep git | wc -l) -eq 0 ]; then
    if [ "$GIT_DOTS" = "Y" ]; then
        home_git_pull
    fi
fi

# if [ -z "$SSH_AUTH_SOCK" ] ; then
#     eval `ssh-agent -s`
# fi

# if ssh-add -l | grep -q "$(ssh-keygen -lf ~/.ssh/id_rsa | awk '{print $2}')"; then 
#     :
# else 
#     ssh-add ~/.ssh/id_rsa 
# fi

if [[ "$OS" == "Darwin" ]]; then
    ssh-add -l >/dev/null
    is_agent_empty=$?

    if [ "${is_agent_empty}" = "1" ]; then
        ssh-add ~/.ssh/id_rsa
    fi
fi

tmux_client_count=$(tmux list-clients | wc -l)
if [[ $tmux_client_count -eq 0 ]]; then
    tmux attach || tmux
fi

# on exit function
function zshexit()
{
    if [ "$GIT_DOTS" = "Y" ]; then
        home_git_push
    fi
    rm -f ~/.ssh/tmp/*
    echo -e "So long and thanks for all the fish"
}

test -e "${HOME}/.iterm2_shell_integration.zsh" && source "${HOME}/.iterm2_shell_integration.zsh"