Aliases and Functions Library¶
This is a curated library of aliases and shell functions organized by
domain. The core set in conf.d/60-aliases.zsh and the baseline
functions in conf.d/80-functions.zsh cover the universal cases; the
items below are domain-specific. They are meant to be sourced
selectively — not adopted wholesale. Pick the handful that pay for
themselves in your actual daily workflow; ignore the rest.
Aliases vs. functions¶
The distinction matters. An alias is a text substitution; a function is a program. The rule for choosing between them:
- Aliases for fixed abbreviations of a single command with no
arguments.
alias gs='git status -sb'is correct;alias gc='git checkout $1'is wrong (the$1is literal, not expanded). - Functions for anything involving arguments, conditionals, loops, or error handling. If the thing you're defining has a verb followed by a parameter, it's a function.
- Never both — don't define an alias and a function with the same name, and don't alias a function name. The resolution order will surprise you.
Two safety rules
Never alias a destructive command in a way that changes its default
semantics (alias rm='rm -i' creates inconsistency between
interactive and scripted use). If you want interactive safety, bind
it to a separate name (alias rmi='rm -i').
Never alias a command that runs over SSH or in subshells in a way that assumes your alias is present — aliases are only loaded in interactive shells.
Core aliases (conf.d/60-aliases.zsh)¶
The core file covers cross-cutting concerns:
| Category | Examples | Notes |
|---|---|---|
| Navigation | .., ..., ...., - |
cd shortcuts |
| Listing | l, ll, la, lt, lS |
Auto-detects GNU vs BSD ls |
| Safety | cp -v, mv -v |
Verbose, not semantic-changing |
| Process | psa, psg, killit |
Process inspection |
| Network | myip, listening, ports |
Quick network checks |
| Git (core) | g, gs, ga, gc, gp, gpl, gd, gl |
Short forms |
| mise | m, mr, mx |
Task runner entry points |
| Ruby | be, bi, bo, rvr, rvi |
Bundler and rv |
| Python | uvr, uvs, uva |
uv commands |
| Bun | br, bx |
Bun run/exec |
| System | reload, path, now |
Shell management |
| direnv | da, de, ds |
Allow/edit/status |
Git extensions (conf.d/61-git-extensions.zsh)¶
Beyond the core aliases, the git extensions handle rebase flow, quick checkouts, and branch hygiene — cases where fixed-text aliases aren't enough.
# Rebase against a remote branch (fetches first for safety)
git-rebase-remote() {
[[ $# -eq 1 ]] || { echo "usage: git-rebase-remote <branch>" >&2; return 1; }
git fetch origin "$1" && git rebase "origin/$1"
}
alias grm='git-rebase-remote main'
alias grs='git-rebase-remote staging'
# Interactive rebase on the last N commits
gir() {
[[ $# -eq 1 ]] || { echo "usage: gir <N>" >&2; return 1; }
git rebase -i "HEAD~$1"
}
alias gra='git rebase --abort'
alias grc='git rebase --continue'
# Commit with a message (positional, quoted automatically via "$*")
gcm() {
[[ $# -ge 1 ]] || { echo "usage: gcm <message>" >&2; return 1; }
git commit -m "$*"
}
# Checkout a new branch
gcrb() {
[[ $# -eq 1 ]] || { echo "usage: gcrb <branch-name>" >&2; return 1; }
git checkout -b "$1"
}
# Clean merged local branches, excluding main/master/develop
gclean() {
git branch --merged | \
grep -vE '^\*|^\s*(main|master|develop)\s*$' | \
xargs -n 1 git branch -d
}
The gcm function uses "$*" rather than "$1" so you can write
gcm fix login bug without quoting the whole message. All functions
use argument validation because the most common shell-function bug is
invoking one without its positional argument and getting a silent,
wrong-feeling operation.
Ruby and Rails (conf.d/62-ruby-aliases.zsh)¶
alias be='bundle exec'
alias bi='bundle install'
alias rs='rails server'
alias rc='DISABLE_PRY_RAILS=1 rails console'
alias rake='bundle exec rake'
alias sidekiq='bundle exec sidekiq'
alias t-rspec='bundle exec rspec --format progress --color'
Python / uv (conf.d/63-python-aliases.zsh)¶
alias uvr='uv run'
alias uvs='uv sync'
alias uva='uv add'
alias pt='uv run pytest'
alias ptv='uv run pytest -v'
alias ptx='uv run pytest -x'
alias jn='uv run jupyter notebook'
alias jl='uv run jupyter lab'
JavaScript / bun (conf.d/64-js-aliases.zsh)¶
alias br='bun run'
alias bx='bun x'
alias bt='bun test'
alias bi='bun install'
alias biome='bun x biome'
Data and text processing (conf.d/66-data-functions.zsh)¶
Functions for CSV splitting, jq helpers, and data inspection that surface frequently in data-adjacent workflows.
Development loop (conf.d/67-devloop.zsh)¶
tmux session management, tree-trunk for project tree visualization,
and serve for quick HTTP serving of the current directory.
Diagnostics (conf.d/68-diagnostics.zsh)¶
TLS certificate checking (check-cert), Claude Code path
synchronization, and other system-level diagnostic functions.
Core functions (conf.d/80-functions.zsh)¶
| Function | Usage | Purpose |
|---|---|---|
mkcd <dir> |
mkcd tmp/scratch |
Create and cd into a directory |
up [N] |
up 3 |
cd up N directories |
path_add <dir> |
path_add ~/tools/bin |
Safely add to PATH at runtime |
mise_pin <tool> <ver> |
mise_pin ruby 3.3.4 |
Pin a tool in the project's mise.toml |
mise_tasks |
mise_tasks |
List tasks including hidden ones |
envdiff |
envdiff |
Show env vars added by mise.toml + .envrc |
extract <file> |
extract archive.tar.gz |
Unpack any common archive format |
port_kill <port> |
port_kill 3000 |
Kill the process on a given port |
timeshell [N] |
timeshell 10 |
Benchmark zsh startup time (N runs) |
keychain_get <svc> |
keychain_get github |
Cross-platform secret lookup (macOS Keychain / Linux Secret Service) |
Machine-local overrides¶
The framework supports two untracked files for per-machine
customization without forking the shared conf.d/ fragments:
$ZDOTDIR/aliases.local.zsh— local aliases and overrides$ZDOTDIR/env.local.zsh— local environment variables
Both are sourced at the end of .zshrc if they exist, so they
override anything in conf.d/.
Organizing aliases at scale¶
The framework's numbering convention keeps aliases organized:
| Range | Domain | Fragment |
|---|---|---|
| 60 | Core cross-cutting | 60-aliases.zsh |
| 61 | Git extensions | 61-git-extensions.zsh |
| 62 | Ruby/Rails | 62-ruby-aliases.zsh |
| 63 | Python/uv | 63-python-aliases.zsh |
| 64 | JavaScript/bun | 64-js-aliases.zsh |
| 66 | Data/text processing | 66-data-functions.zsh |
| 67 | Development loop | 67-devloop.zsh |
| 68 | Diagnostics | 68-diagnostics.zsh |
New language-specific or domain-specific aliases go in a new numbered fragment. The gaps between numbers exist precisely for this.
For project-local aliases, use mise tasks instead — they're
discoverable via mise tasks ls, shareable via mise.toml, and
don't pollute the global shell namespace.