#
# zsh rc file for Uli "youam" Martens <uli@youam.net>
#

#
# path settings
#

# if my home has a bin/ directory, I want it to be the first entry in my $PATH
if [ -d "$HOME/bin" ]; then
	export PATH="$HOME/bin:$PATH"
fi

if [ -e "$HOME/.alias" ]; then
	source "$HOME/.alias"
fi

# add private path for latex files
#   trailing colon -> append standard search path to TEXINPUTS
#   trailing double slash -> search directory recursively
if [ -e "$HOME/.tex" ]; then
	export TEXINPUTS="$HOME/.tex//:"
fi

#
# keybinding settings
#

# select VI keybindings
bindkey -v

bindkey "^R" history-incremental-search-backward
bindkey "^P" history-beginning-search-backward


#
# prompt settings
#

PROMPT=$'%0(?..%{\033[31m%}%B%?%b:)%(!.%{\033[31m%}%B.%{\033[34m%}%B%n@)%m%b:%B%30<...<%~%b%(!.#.$) '
PROMPT=$'%0(?..%{\033[31m%}%B%?%b:)%(!.%{\033[31m%}%B.%{\033[34m%}%B%n@)%m%b:%B%30<...<%~%b%(1v.%F{green}%1v%f.)%(!.#.$) '
#        ^^^^^^^^^^^^^^^^^^^^^^^^^^
# print the return status of the last executed command if it is not null

#                                  ^^^^^^^^^^^^^^^^^^^                 ^                    ^^^^^ ^
# if we're root, print the hostname bold red, suffix the prompt with a hash
# mark
#                                  ^^^^              ^^^^^^^^^^^^^^^^^^^                    ^^^ ^^^
# if we're not root, prepend the hostname with the user name, printed in bold
# blue, suffix the prompt with a dolar sign.

#                                                                              ^^^^^^^^^^^^^^^^^^^^^
# limit the rest of the prompt to a total of 30 characters, of which the first
# chars will be replaced by '...'

fpath+=(~/.zsh/functions)

# this is taken from grml's zshrc
# autoload wrapper - use this one instead of autoload directly
function zrcautoload() {
	emulate -L zsh
	setopt extended_glob
	local fdir ffile
	local -i ffound


	ffile=$1
	(( found = 0 ))
	for fdir in ${fpath} ; do
		[[ -e ${fdir}/${ffile} ]] && (( ffound = 1 ))
	done

	(( ffound == 0 )) && return 1
	if [[ $ZSH_VERSION == 3.1.<6-> || $ZSH_VERSION == <4->* ]] ; then
		autoload -U ${ffile} || return 1
	else
		autoload ${ffile} || return 1
	fi
	return 0
}

# utility functions {{{
# this function checks if a command exists and returns either true
# or false. This avoids using 'which' and 'whence', which will
# avoid problems with aliases for which on certain weird systems. :-)
# Usage: check_com [-c|-g] word
#   -c  only checks for external commands
#   -g  does the usual tests and also checks for global aliases
check_com() {
	emulate -L zsh
	local -i comonly gatoo

	if [[ $1 == '-c' ]] ; then
		(( comonly = 1 ))
		shift
	elif [[ $1 == '-g' ]] ; then
		(( gatoo = 1 ))
	else
		(( comonly = 0 ))
		(( gatoo = 0 ))
	fi

	if (( ${#argv} != 1 )) ; then
		printf 'usage: check_com [-c] <command>\n' >&2
		return 1
	fi

	if (( comonly > 0 )) ; then
		[[ -n ${commands[$1]}  ]] && return 0
		return 1
	fi

	if   [[ -n ${commands[$1]}    ]] \
	  || [[ -n ${functions[$1]}   ]] \
	  || [[ -n ${aliases[$1]}     ]] \
	  || [[ -n ${reswords[(r)$1]} ]] ; then

		return 0
	fi

	if (( gatoo > 0 )) && [[ -n ${galiases[$1]} ]] ; then
		return 0
	fi

	return 1
}

# creates an alias and precedes the command with
# sudo if $EUID is not zero.
salias() {
	emulate -L zsh
	local only=0 ; local multi=0
	while [[ $1 == -* ]] ; do
		case $1 in
			(-o) only=1 ;;
			(-a) multi=1 ;;
			(--) shift ; break ;;
			(-h)
				printf 'usage: salias [-h|-o|-a] <alias-expression>\n'
				printf '  -h      shows this help text.\n'
				printf '  -a      replace '\'' ; '\'' sequences with '\'' ; sudo '\''.\n'
				printf '          be careful using this option.\n'
				printf '  -o      only sets an alias if a preceding sudo would be needed.\n'
				return 0
				;;
			(*) printf "unkown option: '%s'\n" "$1" ; return 1 ;;
		esac
		shift
	done

	if (( ${#argv} > 1 )) ; then
		printf 'Too many arguments %s\n' "${#argv}"
		return 1
	fi

	key="${1%%\=*}" ;  val="${1#*\=}"
	if (( EUID == 0 )) && (( only == 0 )); then
		alias -- "${key}=${val}"
	elif (( EUID > 0 )) ; then
		(( multi > 0 )) && val="${val// ; / ; sudo }"
		alias -- "${key}=sudo ${val}"
	fi

	return 0
}

# Remove these functions again, they are of use only in these
# setup files. This should be called at the end of .zshrc.
xunfunction() {
	emulate -L zsh
	local -a funcs
	funcs=(salias xcat xsource xunfunction zrcautoload)

	for func in $funcs ; do
		[[ -n ${functions[$func]} ]] \
			&& unfunction $func
	done
	return 0
}

zrcautoload vcs_info || vcs_info() {return 1}

if check_com -c vim ; then
	export EDITOR=${EDITOR:-vim}
else
	export EDITOR=${EDITOR:-vi}
fi

export PAGER=${PAGER:-less}

REPORTTIME=5       # report about cpu-/system-/user-time of command if running longer than 5 seconds

# automatically remove duplicates from these arrays
typeset -U path cdpath fpath manpath

precmd_vcs_info() {
	psvar=()
	vcs_info
	[[ -n $vcs_info_msg_0_ ]] && psvar[1]="$vcs_info_msg_0_"
}



#
# screen colaboration
#

# set the screen window title to the current command
preexec () {
	if [[ "$TERM" == "screen" ]]; then
		# needs: setopt extended_glob
		local CMD=${1[(wr)^(*=*|sudo|man|vi|-*)]}
		echo -ne "\ek$CMD\e\\"
	fi
}

# reset the screen window titel to "zsh"
precmd_screen_title () {
	 if [[ "$TERM" == "screen" ]]; then
		 echo -ne "\ekzsh\e\\"
	 fi
}

precmd () {
	precmd_vcs_info
	precmd_screen_title
}

#
# command line history
#

HISTFILE=~/.histfile
HISTSIZE=100000
SAVEHIST=100000

# append to the history file when executing commands, not on exit
setopt INC_APPEND_HISTORY

# reload the history file before adding to it
setopt SHARE_HISTORY

setopt hist_find_no_dups hist_ignore_dups
#
# shell features
#

# use extended globbing, (^ for inverted matches etc)
setopt EXTENDED_GLOB

###############################################################################
###############################################################################
###############################################################################
###############################################################################
#
# beep on error in zle
setopt beep

# press esc-m for inserting last typed word again (thanks to caphuso!)
insert-last-typed-word() { zle insert-last-word -- 0 -1 };
zle -N insert-last-typed-word;

#k# Insert last typed word
bindkey "\em" insert-last-typed-word


# run command line as user root via sudo:
sudo-command-line() {
	[[ -z $BUFFER ]] && zle up-history
	[[ $BUFFER != sudo\ * ]] && BUFFER="sudo $BUFFER"
}
zle -N sudo-command-line

#k# Put the current command line into a \kbd{sudo} call
bindkey "^Os" sudo-command-line

### jump behind the first word on the cmdline.
### useful to add options.
function jump_after_first_word() {
	local words
	words=(${(z)BUFFER})

	if (( ${#words} <= 1 )) ; then
		CURSOR=${#BUFFER}
	else
		CURSOR=${#${words[1]}}
	fi
}
zle -N jump_after_first_word

bindkey '^x1' jump_after_first_word
# notify background job changes at once, don't wait for prompt
setopt notify

# Wait for KEYTIMEOUT ms if the input could be the prefix to some longer command
#KEYTIMEOUT=40



# The following lines were added by compinstall

zstyle ':completion:*' completer _complete
zstyle ':completion:*' completions 1
zstyle ':completion:*' glob 1
zstyle ':completion:*' substitute 1
zstyle :compinstall filename '/home/youam/.zshrc'

autoload -Uz compinit
compinit

setopt auto_pushd

unsetopt autocd nomatch

if [ -d $HOME/.perl ]; then
	export PERL5LIB=$HOME/.perl
fi

# precmd() {
#	local escape colno lineno
#	IFS='[;' read -s -d R escape\?$'\e[6n' lineno colno
#	(( colno > 1 )) && echo ''
# }


export EDITOR=vim
