+# List all files in the current directory when pressing tab on an empty input,
+# behave like complete-word otherwise. Thanks to John Eikenberry [1] for the
+# code, read on 2014-03-15.
+#
+# [1]: http://unix.stackexchange.com/a/32426
+complete-word-or-complete-list-of-files() {
+ if [[ $#BUFFER == 0 ]]; then
+ BUFFER='ls '
+ CURSOR=3
+ zle list-choices
+ zle backward-kill-word
+ else
+ zle complete-word
+ fi
+}
+zle -N complete-word-or-complete-list-of-files
+# Let the completion system handle all completions, including expanding of
+# shell wildcards (which is handled by other shell mechanisms if the default
+# expand-or-complete is used).
+bindkey '^I' complete-word-or-complete-list-of-files
+# If there are multiple matches after pressing <Tab> always display them
+# immediately without requiring another <Tab>. a<Tab> completes to aa and
+# lists aaa, aab, aac as possible completions if the directory contains aaa,
+# aab, aac, bbb instead of only completing to aa.
+setopt nolistambiguous
+# Support completions in the middle of a word, without this option zsh jumps
+# to the end of the word before the completion process begins. Is required for
+# the _prefix completer.
+setopt completeinword
+
+# Force a reload of the completion system if nothing matched; this fixes
+# installing a program and then trying to tab-complete its name. Thanks to
+# Alex Munroe [1] for the code, read on 2014-03-03.
+#
+# [1]: https://github.com/eevee/rc/blob/master/.zshrc
+_force_rehash() {
+ if (( CURRENT == 1 )); then
+ rehash
+ fi
+ # We didn't really complete anything.
+ return 1
+}
+
+zstyle ':completion:::::' completer \
+ _force_rehash _expand _complete _prefix _ignored _approximate
+
+# Match specification to be tried when completing items. Each group ('...') is
+# tried after another if no matches were found, once matches are found no
+# other groups are tried. Thanks to Mikachu in #zsh on Freenode (2012-08-28
+# 18:48 CEST) for explanations.
+#
+# When matching also include the uppercase variant of typed characters
+# ('m:{a-z}={A-Z}'); using '' before this group would try the unmodified match
+# first, but I prefer to get all matches immediately (e.g. if Makefile and
+# makefile exist in the current directory echo m<tab> matches both, with '' it
+# would only match makefile because it found one match). This allows typing in
+# lowercase most of the time and completion fixes the case, which is faster.
+#
+# Don't perform these fixes in _approximate to prevent it from changing the
+# input too much. Thanks to the book "From Bash to Z Shell" page 249.
+zstyle ':completion:*:(^approximate):*' matcher-list 'm:{a-z}={A-Z}'
+
+# Allow one mistake per three characters. Thanks to the book "From Bash to Z
+# Shell" page 248.
+zstyle -e ':completion:*:approximate:*' max-errors \
+ 'reply=( $(( ($#PREFIX + $#SUFFIX) / 3 )) )'
+
+# Expand shell wildcards to all matching files after <Tab>. echo *<Tab>
+# results in a b c if the directory contains the files a, b, c. Thanks to the
+# book "From Bash to Z Shell" page 246.
+zstyle ':completion:*:expand:*' tag-order all-expansions
+# Keep prefixes unexpanded if possible: $HOME/<Tab> doesn't expand $HOME,
+# while $HOME<Tab> does.
+zstyle ':completion:*:expand:*' keep-prefix yes
+
+# When completing multiple path components display all matching ambiguous
+# components. For example /u/s/d/r/README<Tab> lists all matching READMEs
+# instead of just the matching paths up to the r/ component. Can be slow if
+# there are many matching files.
+zstyle ':completion:*' list-suffixes yes
+
+# Use ls-like colors for completions.
+zstyle ':completion:*' list-colors ${(s.:.)LS_COLORS}
+
+# Make completion lists scrollable so "do you wish to see all n possibilities"
+# is no longer displayed. Display current position in percent (%p).
+zstyle ':completion:*:default' list-prompt '%p'
+# Display group name (%d) (like 'external command', 'alias', etc.), in bold.
+# Also display a message if _approximate found errors and no matches were
+# found.
+zstyle ':completion:*' format ' %B%d%b:'
+zstyle ':completion:*:corrections' format ' %B%d%b (errors: %e)'
+zstyle ':completion:*:warnings' format ' %Bno matches for %d%b'
+# Display different types of matches separately.
+zstyle ':completion:*' group-name ''
+
+# Separate man pages by section.
+zstyle ':completion:*' separate-sections yes
+
+# Don't draw trailing / in bold (new in zsh 4.3.11). Thanks to Mikachu in #zsh
+# on Freenode for the fix (2010-12-17 13:46 CET).
+zle_highlight=(suffix:none)
+
+# Ignore completion functions.
+zstyle ':completion:*:functions' ignored-patterns '_*'
+
+# When offering typo corrections, do not propose anything which starts with an
+# underscore (such as many of Zsh's shell functions). Thanks to paradigm [1]
+# for the idea (read on 2013-04-07).
+#
+# [1]: https://github.com/paradigm/dotfiles/blob/master/.zshrc
+CORRECT_IGNORE='_*'
+
+# Ignore parent directory.
+zstyle ':completion:*:(cd|mv|cp):*' ignore-parents parent pwd
+# Always complete file names only once in the current line. This makes it easy
+# to complete multiple file names because I can just press tab to get all
+# possible values. Otherwise I would have to skip the first value again and
+# again. Thanks to Mikachu in #zsh on Freenode (2011-08-11 14:42 CEST) for the
+# hint to use other. other is necessary so prefix<Tab> lists both prefix and
+# prefixrest if the directory contains prefix and prefixrest.
+zstyle ':completion:*:all-files' ignore-line other
+# Except for mv and cp, because I often want to use to similar names, so I
+# complete to the same and change it.
+zstyle ':completion:*:(mv|cp):all-files' ignore-line no
+
+# Don't complete ./config.* files, this makes running ./configure much
+# simpler. Thanks to Nomexous in #zsh on Freenode (2010-03-16 01:54 CET)
+zstyle ':completion:*:*:-command-:*' ignored-patterns './config.*'
+# Don't complete unwanted files with Vim. Thanks to Nomexous in #zsh on
+# Freenode (2010-06-06 04:54 CEST). See below for a way to complete them.
+zstyle ':completion:*:*:vim:*:all-files' ignored-patterns \
+ '*.aux' '*.log' '*.pdf' '*.bbl' '*.blg' '*.out' '*-blx.bib' '*.run.xml' \
+ '*.o' \
+ '*.pyc' \
+ '*.class'
+
+# Provide a fallback completer which always completes files. Useful when Zsh's
+# completion is too "smart". Thanks to Frank Terbeck <ft@bewatermyfriend.org>
+# (http://www.zsh.org/mla/users/2009/msg01038.html).
+zle -C complete-files complete-word _generic
+zstyle ':completion:complete-files:*' completer _files
+bindkey '^F' complete-files
+
+# Completion for my wrapper scripts.
+compdef slocate=locate
+compdef srsync=rsync
+compdef srsync-incremental=rsync
+compdef svalgrind=valgrind
+compdef sc=systemctl
+
+
+# CUSTOM ALIASES AND FUNCTIONS
+
+# If ^C is pressed while typing a command, add it to the history so it can be
+# easily retrieved later and then abort like ^C normally does. This is useful
+# when I want to abort an command to do something in between and then finish
+# typing the command.
+#
+# Thanks to Vadim Zeitlin <vz-zsh@zeitlins.org> for a fix (--) so lines
+# starting with - don't cause errors; and to Nadav Har'El
+# <nyh@math.technion.ac.il> for a fix (-r) to handle whitespace/quotes
+# correctly, both on the Zsh mailing list.
+TRAPINT() {
+ # Don't store this line in history if histignorespace is enabled and the
+ # line starts with a space.
+ if [[ -o histignorespace && ${BUFFER[1]} = ' ' ]]; then
+ return $1
+ fi
+
+ # Store the current buffer in the history.
+ zle && print -s -r -- $BUFFER
+
+ # Return the default exit code so Zsh aborts the current command.
+ return $1
+}
+
+# Load aliases and similar functions also used by other shells.
+if [[ -f ~/.shell/aliases ]]; then
+ . ~/.shell/aliases
+fi
+
+# Make sure aliases are expanded when using sudo.
+alias sudo='sudo '
+
+# Global aliases for often used redirections.
+alias -g E='2>&1'
+alias -g N='>/dev/null'
+alias -g EN='2>/dev/null'
+alias -g L='2>&1 | less'
+alias -g LS='2>&1 | less -S' # -S prevents wrapping of long lines
+alias -g D='2>&1 | colordiff | less'
+# Global aliases for often used commands.
+alias -g A='| awk'
+alias -g A1="| awk '{ print \$1 }'"
+alias -g A2="| awk '{ print \$2 }'"
+alias -g A3="| awk '{ print \$3 }'"
+alias -g G='| grep'
+alias -g GB='| grep -vE "^Binary file .+ matches\$"'
+alias -g H='| head'
+alias -g P='| perl'
+alias -g S='| sort'
+alias -g SL='| sort | less'
+alias -g T='| tail'
+alias -g U='| uniq'
+alias -g X='`xsel -p || xclip -o`' # X selection