A minimal ZSH configuration

I switched to ZSH on macOS a few years ago. As part of that switch, I also installed oh-my-zsh, which was (and still is) a commonly recommended framework to install alongside ZSH. oh-my-zsh is pretty neat - I’d enable some plugins, select a theme, and within a few minutes I’d have a sensibly configured, good-looking shell that is rather enjoyable to use.

However, that out-of-the-box convenience has a trade-off in that oh-my-zsh is fairly bloated. That, and it abstracts away ZSH configurations that I would’ve been forced to learn when adopting ZSH. Having recently installed ZSH on Arch Linux, I figured it was a good opportunity to try rolling my own (minimal) ZSH configuration, instead of once again going down the oh-my-zsh route.

Completions

1 zstyle ':completion:*' menu select
2 bindkey '^[[Z' reverse-menu-complete
3
4 zstyle ':completion:*' special-dirs true
5 zstyle ':completion:*' matcher-list 'm:{a-zA-Z-_}={A-Za-z_-}' 'r:|[._-]=* r:|=*' 'l:|=* r:|=*'


As I understand it, zstyle takes a context and a style (why call it “style” instead of “configuration”?), and applies the style to the context. The context is a colon-separated string, where each subsequent colon denotes a more specific context. E.g. :vcs_info:git:* is more specific than :vcs_info:*. A style that is applied to a more specific context takes precedence over a style that is applied to a less specific one.

Snippet explanation:

• [1] Display a menu of possible completions, which can be cycled through with Tab.
• [2] Cycle through aforementioned menu in reverse with Shift + Tab.
• [4] Enable completion of special directories . and ...
• [5] Define completion rules:
• m:{a-zA-Z-_}={A-Za-z_-} set case and hyphen insensitivity.
• r:|[._-]=* r:|=* enable partial completion before a ., _, or -.
• l:|=* r:|=* enable completion on the LHS of the input string.

Left prompt

1 setopt PROMPT_PERCENT
2 setopt PROMPT_SUBST
3
4 PROMPT='%B[%n:%F{yellow}%25<..<%~%f%<<]%b'  Comprehensive documentation on configuring the prompt can be found here. My prompt is very similar to the prompt from the mh theme - it’s what I’ve used for as long as I’ve had ZSH and I like it. Snippet explanation: • [1] Apply parameter expansion, command substitution and arithmetic expansion to the prompt string. • [2] Expand certain escape sequences that begin with %. • [4] Style the left-aligned prompt string. The escape sequences I use are straightforward, but string truncation is worth a mention because it’s a tad more involved: • %25<..<%~ truncate the left of the current working directory string with .. if the length of the string exceeds 25 characters. • %<< “end” the truncation so that the subsequent characters ] are not included in the string to be truncated.

Right prompt (Git)

 1 autoload -Uz vcs_info
2 precmd_vcs_info() { vcs_info }
3 precmd_functions+=( precmd_vcs_info )
4
5 zstyle ':vcs_info:*' enable git
6 zstyle ':vcs_info:*' check-for-changes true
7 zstyle ':vcs_info:*' stagedstr '%F{green}●%f'
8 zstyle ':vcs_info:*' unstagedstr '%F{red}●%f'
9 zstyle ':vcs_info:git:*' formats '[%F{cyan}%b%f%c%u]'
10
11 RPROMPT='%B\$vcs_info_msg_0_%b'


Snippet explanation:

• [1][2][3] Call the vcs_info function before each prompt. (I copied this from the Pro Git book, but adding vcs_info directly to precmd_functions appears to achieve the same effect.)
• [5] Out of a plethora of supported backends, only enable Git.
• [7] Represent staged changes in the repository with a green dot (via the %c escape).
• [8] Represent unstaged changes in the repository with a red dot (via the %u escape).
• [11] Style the right-aligned prompt string.

Plugins

1 source /usr/share/zsh/plugins/zsh-autosuggestions/zsh-autosuggestions.zsh
2
3 source /usr/share/zsh/plugins/zsh-history-substring-search/zsh-history-substring-search.zsh
4 bindkey '^[[A' history-substring-search-up
5 bindkey '^[[B' history-substring-search-down
6
7 source /usr/share/zsh/plugins/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh


(All three plugins are downloadable via pacman.)

Snippet explanation:

• [7] Must be sourced at the end of the .zshrc file to ensure proper highlighting.

And that’s it! I’m sure the number of configurations/plugins will grow with time as I uncover more conveniences that oh-my-zsh has provided without me knowing. At the time of writing, though, the ones mentioned above have been sufficient.