January 16, 2016 zsh

'(How to Structure a .zshrc)

Audience: intermediate


I often recommend that people “stick this-or-that in their .zshrc.” But what I really mean is to “put this-or-that into the appropriate subfile that makes up a bit of their grander Zsh configuration.” There are some great benefits to piecing apart a single monolithic .zshrc file into individual files.

At the top level, you still have your ~/.zshrc, but it’s mostly just responsible for `source`ing the meatier files.

It looks something like:

# Some envars
    actions.sh  # super fast
    options.zsh # potential to be slow
my_plugins=( $my_shdir/zsh/plugins/*.zsh )

# Time the stuff.
integer t0=$(date '+%s')

# Source all the Zsh-specific and sh-generic files.
for f in $my_configs; do
    ##print starting $f
    [[ -f $my_shdir/$f ]] && . $my_shdir/$f
    ##print finished $f

# Plugin stuff omitted
# Site-specific stuff omitted

function {
    local -i t1 startup
    t1=$(date '+%s')
    startup=$(( t1 - t0 ))
    [[ $startup -gt 1 ]] && print "Hmm, poor shell startup time: $startup"
    ##print "startup time: $startup"
unset t0

This is helpful in that it:

  • keeps things well organized

  • enables reloading of any particular piece

The key commands I use to change, say, a single alias or function in a config file are aliases themselves:

alias re-env=". $my_shdir/envars.sh"
alias re-funcs=". $my_shdir/functions.sh"
re-aliases() { . $my_shdir/aliases.sh; . $my_shdir/aliases.zsh }
alias re-opts=". $my_shdir/options.zsh"

# Bonus
alias a=alias
alias fn='declare -f'

If you are simply re-source-ing a giant .zshrc, you’re possibly overriding or double-setting environment variables, or undoing setting you’ve made manually in your shell session.

I recommend you come up with your own, mostly from scratch, but here’s mine if you’re curious.

This StackOverflow answer has more details about how to profile your shell start-up time.