My .zshrc has gone through a lot of churn — entire plugin frameworks added and later ripped out, elaborate prompt configurations that eventually got simplified back down. The things that survived all of that were a handful of small, boring functions that solve one specific annoyance each.
Jumping Into a Project by Partial Name
I keep all my projects under one directory, and typing out full paths got old fast. This function fuzzy-matches a directory name and cds into it:
proj() {
local dir
dir=$(find ~/Desktop/Project -maxdepth 2 -type d -iname "*$1*" | head -n 1)
if [[ -z "$dir" ]]; then
echo "no project matching: $1"
return 1
fi
cd "$dir" || return
}
proj ghost gets me into this repo without remembering or typing the exact folder name. It's a small thing, but it's probably the single most-used function in the whole config, purely by frequency.
Cleaning Up Merged Branches
After a PR merges I almost always forget to delete the local branch, and eventually git branch output turns into a scroll of stale names. This checks out the default branch, prunes remotes, and deletes anything already merged:
git-clean-merged() {
local default_branch
default_branch=$(git symbolic-ref refs/remotes/origin/HEAD | sed 's@^refs/remotes/origin/@@')
git checkout "$default_branch"
git pull
git fetch --prune
git branch --merged "$default_branch" \
| grep -v "^\*\|$default_branch" \
| xargs -r git branch -d
}
The --merged flag is doing the safety work here — it only lists branches that are fully merged into the default branch, so this can't accidentally delete something with unmerged work sitting in it.
Finding (and Optionally Killing) Whatever's on a Port
This one exists because "something is already listening on port 3000" used to send me to lsof documentation every single time instead of just remembering the flags:
port() {
if [[ -z "$1" ]]; then
echo "usage: port <number> [kill]"
return 1
fi
local pid
pid=$(lsof -ti tcp:"$1")
if [[ -z "$pid" ]]; then
echo "nothing listening on port $1"
return 0
fi
if [[ "$2" == "kill" ]]; then
kill -9 "$pid"
echo "killed pid $pid on port $1"
else
lsof -i tcp:"$1"
fi
}
port 3000 shows what's there; port 3000 kill ends it. Small enough that I never bothered turning it into a real script, but used often enough that it earned a permanent spot in .zshrc.
Why These and Not the Fancier Ones
I've written and eventually deleted far more elaborate functions than these three — multi-step project scaffolding, interactive fuzzy pickers with preview panes, functions that tried to guess what I meant. Almost all of them died from complexity outpacing how often I actually used them. The ones that survived share one trait: each does exactly one thing, has an obvious name, and I can remember what it does without re-reading its source six months later.
The Test I Apply Before Adding a New One
At this point I have an informal filter before any new function gets added to .zshrc: would I actually type this by hand often enough this week that memorizing a shortcut is worth it? Most candidates fail that test — they solve something I hit once a month, which isn't frequent enough to justify the mental overhead of remembering a custom command exists. Those go into a separate scripts/ directory instead, discoverable by name when I need them, but not cluttering the shell config or my working memory of what shortcuts are available.