zsh

1. .zshrc

1.1. Startup

Autoload compinit, a module that provides completions for zsh.

autoload -Uz compinit

Speed up compinit by using zcompdump, a completion caching solution.

compinit -d /home/grtcdr/.cache/zsh/zcompdump

1.2. Completions

Configure the completion system.

zstyle ':completion:*' menu select      # Display completions
zstyle ':completion:*' use-cache on     # Cache completions
zstyle ':completion:*' file-sort access # Sort files by access

For more information, see zshcompsys(1).

1.3. Common options

Configure some of zsh's options.

setopt   HIST_IGNORE_SPACE
setopt   HIST_IGNORE_DUPS
setopt   HIST_REDUCE_BLANKS
setopt   COMPLETE_ALIASES
setopt   SHARE_HISTORY
setopt   IGNOREEOF
unsetopt completealiases

1.4. Prompt

Configure the prompt:

PROMPT="%F{blue}%(4~|.../%3~|%~)%f $ "

1.5. Plugins

Source system-installed plugins:

ZSH_PLUGINS=/usr/share/zsh/plugins
. "$ZSH_PLUGINS"/zsh-autosuggestions/zsh-autosuggestions.zsh
. "$ZSH_PLUGINS"/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh

Change the foreground color for autosuggested text:

ZSH_AUTOSUGGEST_HIGHLIGHT_STYLE='fg=4'

1.6. Aliases

I prefer to have commands that perform changes to the filesystem to be verbose and to always prompt me for my confirmation (a protective measure).

To bypass the prompts, use the yes command, e.g. yes | <cp,rm,mv> [OPTIONS].

alias cp='cp -iv'
alias mv='mv -iv'
alias rm='rm -iv'

What is the possibly the most used command should be the quickest to access, here's a few aliases that make it less boring.

alias ls='ls --color=always --group-directories-first'
alias la='ls -la'
alias ll='ls -l'

cd is aliased to cdls to automate discovery, making movement between directories a bit more intuitive.

alias cd='cdls'
alias ..='cd ..'

Browse the list of installed packages and their metadata:

alias pkglist='pacman -Qq | fzf --preview-window sharp --preview "pacman -Qi {1}"'

Browse the list of packages available for download:

alias pkgsearch='pacman -Slq | fzf --multi --preview "pacman -Si {1}" | xargs -ro sudo pacman -S'

And everything else…

alias open='xdg-open'
alias wget='wget --no-hsts'

1.7. Functions

Define a function that lists the contents of directories upon entering them, it is aliased to cd section 1.6.

cdls() {
   builtin cd "$@" && ls
}

Define a function that lets us bring programs to the foreground the same way we placed them in the background, originally authored by Adam Stankiewicz in his How to boost your Vim productivity publication.

fancy-ctrl-z() {
    if [[ $#BUFFER -eq 0 ]]; then
        BUFFER="fg"
        zle accept-line -w
    else
        zle push-input -w
        zle clear-screen -w
    fi
}

Set the window title dynamically:

precmd () {
    case "$TERM" in
        foot) print -Pn "\e]0;%n@%m\[%2~\]\a" ;;
        esac
}

preexec () {
    print -Pn "\e]0;${1:q}\e\\"
}

Load the functions:

zle -N fancy-ctrl-z

1.8. Keybindings

Bind fancy-ctrl-z to Ctrl + Z.

bindkey '^Z' fancy-ctrl-z

Import common Emacs keybindings, they're very handy!

bindkey -e

2. .zshenv

Configure the PATH:

PATH="$HOME/.local/bin:$PATH"
PATH="$HOME/.local/share/cargo/bin:$PATH"
PATH="$HOME/.local/share/gem/ruby/3.0.0/bin:$PATH"
export PATH

gpg-agent(1) says to export this:

export GPG_TTY=$(tty)

3. .zprofile

Export the usual stuff:

export EDITOR="emacsclient -c -a="
export VISUAL="$EDITOR"

Add some colors to man:

export MANPAGER="less -R --use-color -Dd+r -Du+b"

Instruct less not to create a ~/.lesshst file:

export LESSHISTFILE=-

Keep track of only the last 1000 commands:

export HISTSIZE=1000
export SAVEHIST=1000

SSH has the ability to remember my passphrase for me - for that to work, I need to set a location for the socket:

export SSH_AUTH_SOCK="$XDG_RUNTIME_DIR"/ssh-agent.socket

This next section deals with relocating the files of certain programs that don't natively respect the XDG base directory specification.

XDG_DATA_HOME="${XDG_DATA_HOME:-$HOME/.local/share}"
XDG_CONFIG_HOME="${XDG_CONFIG_HOME:-$HOME/.config}"
XDG_STATE_HOME="${XDG_STATE_HOME:-$HOME/.local/state}"
XDG_DATA_DIRS="${XDG_DATA_DIRS:-/usr/local/share/:/usr/share/}"
XDG_CONFIG_DIRS="${XDG_CONFIG_DIRS:-/etc/xdg}"
XDG_CACHE_HOME="${XDG_CACHE_HOME:-$HOME/.cache}"
export WGETRC="$XDG_CONFIG_HOME"/wgetrc
export SCREENRC="$XDG_CONFIG_HOME"/screen/screenrc
export DOCKER_CONFIG="$XDG_CONFIG_HOME"/docker
export TEXMFCONFIG="$XDG_CONFIG_HOME"/texlive/texmf-config
export PYTHONSTARTUP="$XDG_CONFIG_HOME"/python/startup.py
export GNUPGHOME="$XDG_DATA_HOME"/gnupg
export PASSWORD_STORE_DIR="$XDG_DATA_HOME"/pass
export VAGRANT_HOME="$XDG_DATA_HOME"/vagrant
export VAGRANT_ALIAS_FILE="$XDG_DATA_HOME"/vagrant/aliases
export SOLARGRAPH_CACHE="$XDG_DATA_HOME"/solargraph
export TEXMFHOME="$XDG_DATA_HOME"/texmf
export RUSTUP_HOME="$XDG_DATA_HOME"/rustup
export CARGO_HOME="$XDG_DATA_HOME"/cargo
export GOPATH="$XDG_DATA_HOME"/go
export HISTFILE="$XDG_STATE_HOME"/zsh/history
export SQLITE_HISTORY="$XDG_STATE_HOME"/sqlite/history
export TEXMFVAR="$XDG_CACHE_HOME"/texlive/texmf-var
export ANSIBLE_HOME="$XDG_CONFIG_HOME"/ansible
export ANSIBLE_CONFIG="$XDG_CONFIG_HOME"/ansible.cfg
export ANSIBLE_GALAXY_CACHE_DIR="$XDG_CACHE_HOME"/ansible/galaxy_cache