How to Configure Zsh Aliases and Functions in the dotfiles Repository
The dotfiles repository organizes Zsh customizations through a three-layer architecture using Zgen for plugin management, followed by automatic sourcing of all *.zsh files in zsh/config and zsh/aliases, plus an optional local override file.
This guide walks through the configuration system in the issmirnov/dotfiles repository, showing exactly where to place aliases and functions, how the loading mechanism works, and how to extend the setup without breaking existing conventions.
Overview of the Three-Layer Architecture
The zsh/zshrc file implements a strict loading order that separates concerns between external plugins and custom code:
- Plugin Manager (Zgen) – Loads Oh-My-Zsh, plugins, and syntax highlighting first (lines 20–48)
- Custom Configuration – Sources every
*.zshfile fromzsh/configandzsh/aliasesdirectories in alphabetical order (lines 52–58) - Local Overrides – Sources
~/.zshrc.locallast for machine-specific tweaks without version control (line 66)
This structure ensures that your custom aliases in zsh/aliases/ always override plugin defaults, while maintaining a clean separation between shared and private configuration.
Where Aliases Live
All alias definitions reside in the zsh/aliases/ directory as plain Zsh statements. The repository ships with several categorized files:
Utility Aliases
The zsh/aliases/utilities.zsh file contains general-purpose shortcuts:
alias o='open'
alias gurl='curl --compressed'
alias week='date +%V'
alias zsh-reload='source ~/.zshrc'
System-Specific Aliases
Platform-aware definitions live in zsh/aliases/system.zsh and platform-specific files like ubuntu.zsh or osx.zsh:
alias sudo='sudo '
alias ll='ls -lha --color'
alias open='xdg-open'
Suffix Aliases
Special "suffix aliases" defined in zsh/aliases/suffixes.zsh automatically invoke commands based on file extensions:
alias -s pdf='open'
alias -s html='open'
When you type report.pdf, Zsh automatically expands it to open report.pdf.
Where Functions Live
Reusable shell functions are defined alongside aliases, primarily in zsh/aliases/utilities.zsh. These are automatically available because the zshrc loader sources every *.zsh file found in the directories.
Example functions from the source:
function to {
if [[ -z "$1" ]]; then
echo "Usage: to <file name>"
else
echo "Now writing out to $1. Type ^D to finish."
cat >| "$1"
fi
}
function pdfsearch() {
[ -z "$1" ] && echo "Error: No search term supplied" && exit 1
find . -name '*.pdf' | xargs -I {} sh -c "pdftotext \"{}\" - | grep --with-filename --label=\"{}\" --color $1"
}
Adding New Aliases and Functions
To extend the configuration, create or edit files in the zsh/aliases/ directory:
- Create a new file (e.g.,
zsh/aliases/docker.zsh) or edit an existing one likeutilities.zsh - Add your definitions using standard Zsh syntax:
# zsh/aliases/git_custom.zsh
alias gco='git checkout'
alias gl='git log --oneline --graph'
function mkcd() {
mkdir -p "$1" && cd "$1"
}
- Reload the shell using the provided alias:
zsh-reload
Or source a specific file directly:
source ~/.dotfiles/zsh/aliases/git_custom.zsh
Understanding the Loading Order
The sourcing mechanism in zsh/zshrc (lines 52–58) uses a deterministic alphabetical loading strategy:
find ~/.dotfiles/zsh/config ~/.dotfiles/zsh/aliases -type f -name '*.zsh' -print0 |
sort -z |
while IFS= read -r -d $'\0' line; do
source "$line"
done
Key implementation details:
- Alphabetical ordering –
sort -zensures files load predictably regardless of filesystem order - Null-terminated strings –
-print0and-d $'\0'handle filenames with spaces safely - Sourcing scope – Each file executes in the current shell context via
source, making aliases and functions immediately available
Because this block executes after Zgen initializes plugins, any definitions in zsh/aliases/ automatically override plugin defaults of the same name.
Best Practices for Organizing Zsh Configuration
When extending the dotfiles repository, follow these patterns established in the source code:
- Group logically – Create separate files for different concerns (e.g.,
docker.zsh,kubernetes.zsh) rather than dumping everything intoutilities.zsh - Use descriptive filenames – The alphabetical sort means
10-utils.zshloads before99-local.zshif you need explicit ordering - Check for collisions – Run
alias | grep 'your-alias'before adding new shortcuts to avoid unexpected overwrites - Prefer functions for complexity – When logic requires conditionals or loops, defined a function in
utilities.zshrather than a complex alias - Leverage suffix aliases – For file types you frequently open, use
alias -s ext='command'syntax inzsh/aliases/suffixes.zsh
Summary
- The three-layer architecture loads plugins first, then custom
*.zshfiles fromzsh/configandzsh/aliases, finally~/.zshrc.local - Aliases belong in
zsh/aliases/*.zshfiles, categorized by purpose (utilities, system, suffixes) - Functions are defined in the same
*.zshfiles and sourced automatically by thefindloop inzsh/zshrc - The loading mechanism uses alphabetical sorting (
sort -z) to ensure deterministic behavior - Use
zsh-reloadto refresh configuration after making changes
Frequently Asked Questions
How do I override a plugin alias with my own definition?
Add the conflicting alias to any file in zsh/aliases/ (such as system.zsh). Because these files source after Zgen loads Oh-My-Zsh and plugins, your definition wins. For example, if a plugin defines alias ll='ls -l', add alias ll='ls -lha --color' to override it.
Can I organize aliases into subdirectories within zsh/aliases?
The current find command in zsh/zshrc searches only for *.zsh files within the top-level directories zsh/config and zsh/aliases. While find traverses subdirectories, keep aliases in the root of zsh/aliases/ to ensure predictable loading order and prevent naming collisions.
What is the difference between zsh/config and zsh/aliases?
zsh/config/ contains environment settings, prompt configuration, bindkeys, and tool integrations (like fzf). zsh/aliases/ contains command shortcuts, suffix aliases, and function definitions. Both directories are sourced identically, but the separation helps maintain organization as the configuration grows.
How do I temporarily disable an alias without deleting the file?
Add an unalias command to your ~/.zshrc.local file, which sources last. For example, unalias ll removes the alias for that session. Alternatively, prepend the command with \ (backslash) to bypass alias expansion for a single execution: \ll runs the original binary regardless of aliases.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →