# ___    ______                    _________
# __ |  / /__(_)  _______ _______________  /____
# __ | / /__  /   __  __ `__ \  __ \  __  /_  _ \
# __ |/ / _  /    _  / / / / / /_/ / /_/ / /  __/
# _____/  /_/     /_/ /_/ /_/\____/\__,_/  \___/
#
bindkey -v
export KEYTIMEOUT=15 # long enough for the 'jk' to work

# Change cursor shape for different vi modes
function vi_zle-keymap-select {
  if [[ ${KEYMAP} == vicmd ]]; then
    echo -ne '\e[1 q'
  elif [[ ${KEYMAP} == main ]] ||
       [[ ${KEYMAP} == viins ]] ||
       [[ ${KEYMAP} = '' ]]; then
    echo -ne '\e[5 q'
  fi
}
# Check for existing keymap-select widget
local existing_keymap_select_fn=$widgets[zle-keymap-select]
# zle-keymap-select is a special widget so it'll be "user:fnName" or nothing. Let's get fnName only.
existing_keymap_select_fn=${existing_keymap_select_fn//user:}
if [[ -z ${existing_keymap_select_fn} ]]; then
	zle -N zle-keymap-select vi_zle-keymap-select
else
	function vi_zle-keymap-select-wrapped {
		${existing_keymap_select_fn} "$@"
		vi_zle-keymap-select "$@"
	}
	zle -N zle-keymap-select vi_zle-keymap-select-wrapped
fi
echo -ne '\e[5 q' # Use beam shape cursor on startup.
precmd() { echo -ne '\e[5 q' ;} # Use beam shape cursor for each new prompt.

# Work with brackets/quotes
# ci", ci', ci`, di", etc
autoload -U select-quoted
zle -N select-quoted
for m in visual viopp; do
  for c in {a,i}{\',\",\`}; do
    bindkey -M $m $c select-quoted
  done
done
# ci{, ci(, ci<, di{, etc
autoload -U select-bracketed
zle -N select-bracketed
for m in visual viopp; do
  for c in {a,i}${(s..)^:-'()[]{}<>bB'}; do
    bindkey -M $m $c select-bracketed
  done
done
# surround
autoload -Uz surround
zle -N delete-surround surround
zle -N add-surround surround
zle -N change-surround surround
bindkey -a cs change-surround
bindkey -a ds delete-surround
bindkey -a ys add-surround

# __________________
# __  __ \_  /___  /_____________________
# _  / / /  __/_  __ \  _ \_  ___/_  ___/
# / /_/ // /_ _  / / /  __/  /   _(__  )
# \____/ \__/ /_/ /_/\___//_/    /____/
#
# Basics
bindkey -M viins 'jk' vi-cmd-mode # noone likes Esc
bindkey -M viins ' ' magic-space
# bindkey -M viins '^I' expand-or-complete-prefix
bindkey -M viins '^U' backward-kill-line
bindkey -M viins '^K' kill-line
bindkey -M viins '^W' backward-kill-word
bindkey -M viins '^B' backward-word
bindkey -M viins '^F' forward-word
bindkey -M viins '^G' push-line-or-edit
bindkey -M viins '^A' beginning-of-line
bindkey -M viins '^E' end-of-line
bindkey -M viins '^S' history-incremental-pattern-search-backward

bindkey -M vicmd '^U' backward-kill-line
bindkey -M vicmd '^K' kill-line
bindkey -M vicmd 'H'  run-help

# Shift + Tab
bindkey -M viins '^[[Z' reverse-menu-complete

# Open current prompt in external editor
autoload -Uz edit-command-line; zle -N edit-command-line
bindkey '^[ ' edit-command-line

# Fix the DEL key
bindkey -M vicmd "^[[3~" delete-char
bindkey "^[[3~" delete-char

# Use vim keys in tab complete menu
bindkey -M menuselect '^H' vi-backward-char
bindkey -M menuselect '^J' vi-down-line-or-history
bindkey -M menuselect '^K' vi-up-line-or-history
bindkey -M menuselect '^L' vi-forward-char
bindkey -M menuselect 'left' vi-backward-char
bindkey -M menuselect 'down' vi-down-line-or-history
bindkey -M menuselect 'up' vi-up-line-or-history
bindkey -M menuselect 'right' vi-forward-char

# C-z to toggle current process (background/foreground)
fancy-ctrl-z () {
  if [[ $#BUFFER -eq 0 ]]; then
    BUFFER="fg"
    zle accept-line
  else
    zle push-input
    zle clear-screen
  fi
}
zle -N fancy-ctrl-z
bindkey '^Z' fancy-ctrl-z
