# .zshrc [2] Used for setting user's interactive shell configuration and
# executing commands, will be sourced when starting as an interactive shell.

# Load plugin scripts
source-plugin() {
  if [ -d ~/.config/zsh/$1 ]; then
    source ~/.config/zsh/$1/$1.plugin.zsh
  else
    echo "zsh plugin not found: $1"
  fi
}

# Fish like automatic suggestions from command history
source-plugin zsh-autosuggestions
# Disable non end-of-line autosuggest accept widgets
ZSH_AUTOSUGGEST_ACCEPT_WIDGETS=(end-of-line vi-end-of-line)

# Search history with a command substring
source-plugin zsh-history-substring-search

# Command syntax highlighting
source-plugin zsh-syntax-highlighting

# Build system helper commands
source-plugin build

# Project sandboxing commands
source-plugin sandbox

# Various shell utilities
source-plugin utilities

# Automatically source .enter and .exit scripts on cd
source-plugin autoenv

# Layout tmux window commands
[ "$TMUX" != "" ] && source-plugin layout

# Note taking commands
source-plugin notes

# Remove duplicates from history
setopt histignoredups

# Enable multi-terminal history
setopt share_history

# Disable error when no glob matches are found
setopt nonomatch

# Enable comments in the prompt
setopt interactive_comments

# Disable '<Ctrl>D' to logout
setopt ignore_eof

# Disable sound
setopt nobeep

# Disable tty flow control, allows vim to use '<Ctrl>S'
setopt noflowcontrol; stty -ixon

# Enable completions in the middle of a word
setopt completeinword

# Initialize completions
autoload -U compinit
compinit

# Add pip to the old completion engine if present
if which pip &> /dev/null; then
  function _pip_completion {
    local words cword
    read -Ac words
    read -cn cword
    reply=( $( COMP_WORDS="$words[*]" \
               COMP_CWORD=$(( cword-1 )) \
               PIP_AUTO_COMPLETE=1 $words[1] ) )
  }
  compctl -K _pip_completion pip
fi

# Enable prompt themes
autoload -Uz promptinit
promptinit
prompt fresh

# Enable vi mode line editor keymap
bindkey -v

# Enable backspace after returning to viins from vicmd mode
bindkey '^?' backward-delete-char

# Enable yank, change, and delete whole line with 'Y', 'cc', and 'dd'
bindkey -M vicmd 'Y' vi-yank-whole-line

# Edit the command line in vim
bindkey -M vicmd '^F' edit-command-line

# Enable undo with 'u' and redo with 'U'
bindkey -M vicmd 'u' undo
bindkey -M vicmd 'U' redo

# Enable toggle comment at start of line al la vim-commentary
bindkey -M vicmd 'gcc' vi-pound-insert

# TODO: vi-pipe???

# Enable accepting autosuggestions
bindkey '^O' forward-word
bindkey '^P' autosuggest-accept

# Enable substring history search with 'j' and 'k'
bindkey -M vicmd 'k' history-substring-search-up
bindkey -M vicmd 'j' history-substring-search-down

# Replace '<Esc>h' with 'K' to view help
bindkey -r '^[h'
bindkey -M vicmd 'K' run-help

# Disable Ex mode with ':'
bindkey -rM vicmd ':'

# Enable '<Shirt><Tab>' reverse order completions
bindkey '^[[Z' reverse-menu-complete

# Use editor to edit command line with '<Ctrl>V'
autoload -U edit-command-line
zle -N edit-command-line
bindkey -M vicmd '^V' edit-command-line

# Enable HOME and END keys
if [[ `uname` = Linux ]]; then
  # If Home and End are not working as expected setup zkbd mappings.
  [ -f ~/.zkbd/$TERM-${${DISPLAY:t}:-$VENDOR-$OSTYPE} ] && \
    source ~/.zkbd/$TERM-${${DISPLAY:t}:-$VENDOR-$OSTYPE}
  [[ -n ${key[Home]} ]] && bindkey "${key[Home]}" beginning-of-line
  [[ -n ${key[End]} ]] && bindkey "${key[End]}" end-of-line
fi

# Get the shells parent process name.
ppid_name() { echo $(ps -p $(ps -p $(echo $$) -o ppid=) -o comm=) }

# Enable changing cursor shape based on vi mode
if [ "$ITERM_PROFILE" != "" ] && [ "$TMUX" = "" ]; then
  # iTerm2 cursor shape escape sequences outside tmux
  cursor_block="\e]50;CursorShape=0\C-G"
  cursor_line="\e]50;CursorShape=1\C-G"
elif [ "$(ppid_name)" != "python2" ]; then
  # iTerm2 inside tmux or VTE compatible cursor shape escape sequences,
  # exclude Guake even though it's VTE based it doesn't like these
  cursor_block="\e[2 q"
  cursor_line="\e[6 q"
fi

if [[ ! -z "$cursor_block" && ! -z "$cursor_line" ]]; then
  # Change cursor shape when vi mode changes
  function zle-keymap-select zle-line-init {
    case $KEYMAP in
      vicmd)      print -n -- "$cursor_block" ;;
      viins|main) print -n -- "$cursor_line" ;;
    esac
    zle reset-prompt
    zle -R
  }

  # Change cursor shape when line editing is finished
  function zle-line-finish { print -n -- "$cursor_block" }

  # Register cursor shape hooks
  zle -N zle-keymap-select
  zle -N zle-line-init
  zle -N zle-line-finish
fi

# Load work related config
[ -f ~/.config/work/zshrc ] && source ~/.config/work/zshrc

# Aliases
alias grep='grep --color=always'
which cmake &> /dev/null && \
  alias cninja='cmake -GNinja -DCMAKE_EXPORT_COMPILE_COMMANDS=ON'
which ssh &> /dev/null && \
  alias ssh='TERM=xterm-256color ssh'
alias weather="curl wttr.in"

case `uname` in
  Linux)
    [ "$TMUX" = "" ] && \
      alias cls="printf '\ec'" || \
      alias cls="clear && printf '\e[3J'"
    alias ls='ls -F --color=auto'
    if which cgdb &> /dev/null; then
      alias debug='cgdb --args'
    elif which gdb &> /dev/null; then
      alias debug='gdb --args'
    fi
    ;;
  Darwin)
    alias cls="clear && printf '\e[3J'"
    alias ls='ls -GFh'
    which lldb &> /dev/null && \
      alias debug='lldb --'
    ;;
esac

# Hashed Directories
hash -d Projects="$HOME/Projects"