setopt EXTENDED_HISTORY       # Write the history file in the ':start:elapsed;command' format.
setopt HIST_EXPIRE_DUPS_FIRST # Expire a duplicate event first when trimming history.
setopt HIST_FIND_NO_DUPS      # Do not display a previously found event.
setopt HIST_IGNORE_ALL_DUPS   # Delete an old recorded event if a new event is a duplicate.
setopt HIST_IGNORE_SPACE      # Do not record an event starting with a space.
setopt SHARE_HISTORY          # Share history between all sessions.

bindkey -e

bindkey '^R' history-incremental-search-backward
bindkey '^A' beginning-of-line
bindkey '^E' end-of-line
bindkey '^K' kill-line

bindkey "^[[1;5C" forward-word
bindkey "^[[1;5D" backward-word

setopt AUTO_PUSHD        # Push the current directory visited on the stack.
setopt PUSHD_IGNORE_DUPS # Do not store duplicates in the stack.
setopt PUSHD_SILENT      # Do not print the directory stack after pushd or popd.

DISABLE_AUTO_TITLE="true"

# install zsh-syntax-highlighting
case "$UNAME_STRING" in
    Linux*) {
        source /usr/share/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh
        local lesspipe_bin_location
        (($+commands[lesspipe])) && eval "$(lesspipe)"
    } ;;
    Darwin*) {
        # Use HOMEBREW_PREFIX (set in .zshenv) to avoid slow brew --prefix subprocess on every new shell
        source "${HOMEBREW_PREFIX}/share/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh"
        # make less more friendly for non-text input files, see lesspipe(1)
        export LESSOPEN="|${HOMEBREW_PREFIX}/bin/lesspipe.sh %s"
    } ;;
    *) ;;
esac

if [ -f ~/.zsh_aliases ]; then
    . ~/.zsh_aliases
fi

# Set fpath before sourcing completion.zsh
fpath=("$DOTFILES/zsh/zsh-completions/src" $fpath)
# Source completion configuration
source "$DOTFILES/zsh/completion.zsh"
source "$DOTFILES/zsh/zsh-autosuggestions/zsh-autosuggestions.zsh"

autoload -Uz vcs_info
setopt prompt_subst

zstyle ':vcs_info:*' enable git
zstyle ':vcs_info:*' max-exports 3

zstyle ':vcs_info:*+*:*' debug false

zstyle ':vcs_info:git:*' check-for-changes true
zstyle ':vcs_info:git:*' get-revision false
zstyle ':vcs_info:git:*' stagedstr '+'
zstyle ':vcs_info:git:*' unstagedstr '!'

zstyle ':vcs_info:git*:*' use-simple true
zstyle ':vcs_info:git*:*' cache-ttl 30 # Cache for 30 seconds

function preexec() {
    # Command execution timer
    timer=${timer:-$SECONDS}

    # Check if the command is a git command
    if [[ "$1" == git* || "$1" == "g "* ]]; then
        __GIT_COMMAND_EXECUTED=1
    else
        __GIT_COMMAND_EXECUTED=0
    fi
}

precmd() {
    # Tell tmux our cwd (for pane_current_path) so tmux-window-name can show the directory
    [[ -n "$TMUX" ]] && printf '\e]7;file://%s\a' "$(pwd)"

    if [[ $__GIT_COMMAND_EXECUTED -eq 1 ]]; then
        zstyle ':vcs_info:git*:*' cache-ttl 0
        __GIT_COMMAND_EXECUTED=0
    fi
    vcs_info
    zstyle ':vcs_info:git*:*' cache-ttl 30

    PS1=$'%B%(?.%F{240}--.%F{red}!%?)%f '

    if [[ -z ${vcs_info_msg_0_} ]]; then
        PS1+=$'%F{cyan}%5~%f%b '
    else
        PS1+=$'%F{cyan}%3~%f%b ${vcs_info_msg_0_} '
    fi

    if [ $timer ]; then
        timer_show=$(($SECONDS - $timer))
        if [ $timer_show -gt 3 ]; then
            PS1+=$'%F{240}-- %ftook %F{red}${timer_show}s %f'
        fi
        unset timer
    fi

    PS1+=$'\n;; '
}
zstyle ':vcs_info:git*' formats "%F{red}⎇  %b %F{blue}[%c%u] %F{240}(%F{red}%m%F{240})%f" # branch [staged unstaged(+untracked)] (misc(ahead/behind))

zstyle ':vcs_info:git*+set-message:*' hooks git-extra

function +vi-git-extra() {
    # Only run these expensive operations in git repositories
    if [[ -n ${hook_com[branch]} ]]; then
        # Check if upstream exists before trying to get ahead/behind counts
        if git rev-parse --verify ${hook_com[branch]}@{upstream} >/dev/null 2>&1; then
            local ahead_behind=$(git rev-list --left-right --count HEAD...${hook_com[branch]}@{upstream} 2>/dev/null)
            local split=($=ahead_behind)
            local ahead=$split[1]
            local behind=$split[2]
            [[ $ahead -gt 0 ]] && hook_com[misc]+="+"${ahead}
            [[ $behind -gt 0 ]] && hook_com[misc]+=${hook_com[misc]:+"/"}"-"${behind}
        fi

        if [[ -n $(git ls-files --others --exclude-standard 2>/dev/null) ]]; then
            hook_com[unstaged]+='?'
        fi
    fi
}
