My ZSH configuration

A while (read: over 4 years) ago I moved from Bash to ZSH, and never looked back. Initially I tried it out because Bash was getting quite slow with its tab completion, and ZSH was considerably faster. After switching, I also noted that ZSH is smarter in other areas. For example, when typing chmod -x {tab}, it’ll only auto-complete with files that are executable. When typing chmod -x file1 {tab} it will even skip file1 because you already used that one.

Another advantage is that you can paste some commands into the shell and it will not execute them until you press Enter. Even when there are newlines in the pasted text, ZSH won’t execute until you actually press the Enter key. This IMO is good for security, but also helps to avoid errors when accidentally pasting the wrong thing.

To get things working juuuust right, I had to tweak some settings. Note that this doesn’t list everything in my ~/.zshrc, just some parts that I think may be of interest to others.

Auto-completion

# The following lines were added by compinstall
zstyle :compinstall filename '/home/sybren/.zshrc'

autoload -Uz compinit
compinit
# End of lines added by compinstall

# Get Git/Mercurial/SVN info in the prompt (current branch, current action, etc.)
autoload -Uz vcs_info
zstyle ':vcs_info:*' enable hg git svn
# Display current HG action (like 'merging')
zstyle ':vcs_info:hg*' get-mq true
zstyle ':vcs_info:*'         formats '%F{5}(%f%s%F{5})%F{3}-%F{5}[%F{2}%b|%m%F{5}]%f'
zstyle ':vcs_info:hg*' actionformats '%F{5}(%f%s|%F{red}%a%F{5})%F{3}-%F{5}[%F{2}%b|%m%F{5}]%f'

precmd () { vcs_info }
export PS1='
%F{2}%n@%m%f %F{3}%~%f ${vcs_info_msg_0_}%E
%# '

# Custom completions
zstyle ":completion:*:*:abcecho:*" file-patterns "*.abc *(-/)"
zstyle ":completion:*:*:abcls:*" file-patterns "*.abc *(-/)"
zstyle ":completion:*:*:abcview:*" file-patterns "*.abc *(-/)"
zstyle ":completion:*:*:usdview:*" file-patterns "*.usd[ac] *.usd *.abc *(-/)"
zstyle ":completion:*:*:usdcat:*" file-patterns  "*.usd[ac] *.usd *.abc *(-/)"
zstyle ":completion:*:*:usdtree:*" file-patterns  "*.usd[ac] *.usd *.abc *(-/)"
zstyle ":completion:*:*:blender:*" file-patterns "*.blend *(-/)"
zstyle ":completion:*:*:blenderdebug:*" file-patterns "*.blend *(-/)"
zstyle ":completion:*:*:dot2png:*" file-patterns "*.dot *(-/)"
zstyle ":completion:*:*:gaffer:*" file-patterns "*.gfr *(-/)"
zstyle ':completion:*' completer _complete
zstyle ':completion:*' matcher-list '' 'm:{[:lower:][:upper:]}={[:upper:][:lower:]}' '+l:|=* r:|=*'

The last line is some magic that makes ZSH autocomplete using substrings instead of prefixes. In other words, it has tab completion also on the middle of a filename. This makes it possible to type mplayer mjpeg{tab} and get mplayer llama.mjpeg (this file was the only .mjpeg file in the directory).

Key Bindings

bindkey -e
bindkey "^[[3~"  delete-char
bindkey "^[3;5~" delete-char
bindkey "^K" kill-line

# Ctrl left/right for word skipping
bindkey ';5D' backward-word
bindkey ';5C' forward-word

my-backward-delete-word() {
    local WORDCHARS=${WORDCHARS/\//}
    zle backward-delete-word
}
zle -N my-backward-delete-word
bindkey '^W' my-backward-delete-word

The last big is to make Ctrl+W erase only a word, and not the entire line.

Fuzzy Finder

For searching through history I use Fuzzy Finder. It makes it much easier to find previous commands, as it doesn’t require you to search for it exactly. This means that you can just do {Ctrl+R}code blender to find code ~/workspace/blender-git/blender.code-workspace.

Another very nice thing is that Enter only selects the command from history. You then have the opportunity to edit it, before pressing Enter again to execute it.

dr. Sybren A. Stüvel
dr. Sybren A. Stüvel
Open Source software developer, photographer, drummer, and electronics tinkerer

Related