After spending a year traveling the world, I've acquired a new Macbook Air and had to set up my terminal interface again.
I do not normally enjoy this process but I loved it this time.
A continuous conversation with AI (Gemini specifically) lead to every random idea I had becoming realized in my .zshrc file.
There are some goodies in here I suspect you'll enjoy too.
Basic settings and imports
# # # # # # # # # # # # #
# import things we need #
# # # # # # # # # # # # #
# load 'live' hooks to execute things every call,
# load TAB completion
autoload -Uz add-zsh-hook compinit
# # # # # # # # # # # # #
# Enable Tab Completion #
# # # # # # # # # # # # #
# 1. Prevent duplicate entries in paths
typeset -U FPATH PATH
# 2. Add Homebrew to FPATH for even better tab completion (if it's not present already)
FPATH="/opt/homebrew/share/zsh/site-functions:${FPATH}"
# 3. Enable TAB completion
compinit
# # # # # # # # # # # # #
# Toggling Misc options #
# # # # # # # # # # # # #
# make ls pretty
export CLICOLOR=1
Basic aliases
# make the current terminal tab aware of things just installed or changed
alias reload='source ~/.zshrc'
# shortcut to go to my main projects folder
alias pj="cd ~/Desktop/PropJockey"
# Launch Gemini in a frameless chrome window
alias gemini="/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --app=https://gemini.google.com/app"
Whenever you modify the .zshrc file, which I did about a hundred times during this, you either have to open a new tab or run the command I've aliased with a simple "reload".
I wound up installing Gemini using Chrome's built in "Install as App" feature which had the added benefit of getting Gemini in my dock. 🤙 Sweet.
Lock Function
One of the first things I do when setting up a mac is turn sleep into hibernate. When I close the lid, I'm done for the night, no reason to sleep.
sudo pmset -a hibernatemode 25
Unfortunately, no matter how you've configured your lock screen settings, after only a minute idle on the lock screen, the mac gets bored and falls asleep, which in my case hibernates it and I have to sit through memory reloading from the harddrive to log back in.
The fix:
First create a shortcut using the Shortcuts app that ships with mac. It's great
Add a new shortcut, search for the lock screen action, add it, name it "LockMac", and you're ready for the script
# Lock the screen without sleeping the system and keep it awake until ctrl + c to quit
# alias lock='shortcuts run "LockMac" && caffeinate -i -d -t 3600'
# ^ great but this is better because I don't have to ctrl + c!
lock() {
# Start caffeinate in the background, disown it, hide its output, and save its Process ID (PID)
caffeinate -i -d -t 3600 &>/dev/null &!
local caff_pid=$!
shortcuts run "LockMac"
# Give macOS a bit to register the locked state
sleep 3
# The Magic Loop: Poll the Mac's hardware registry.
# This specific string ONLY exists while the screen is actively locked.
while ioreg -n Root -d1 | grep -q "CGSSessionScreenIsLocked"; do
sleep 2
done
# You're back! Kill the caffeinate process silently
kill $caff_pid 2>/dev/null
# Print a Bifrost-styled welcome back message
# print -P "%F{cyan}🛸 Welcome back. Sleep prevention disabled.%f"
}
I always have at least one terminal open so I just type lock and I'm off to the bathroom in my hostel. The mac stays wide awake the whole time so I can simply type my password and continue.
I use this often
Automatic Node & NPM version mismatch warning
One of the things any seasoned node developer has done time and time again is accidentally run their project with the wrong version, or worse, installed packages.
I wanted to prevent that as best as I could so I requested a function that alerts the node version and the version specified in .nvmrc or package.json with pass/fail indicators based on a comparison of the values.
# Checks current versions against .nvmrc or package.json requirements
nvi() {
# 1. Ensure Node is actually installed
if ! command -v node &> /dev/null; then
print -P "%F{red}✘ Node.js is not installed or not in PATH.%f"
return 1
fi
local current_node=$(node -v)
local current_npm=$(npm -v)
local req_node=""
local req_npm=""
# 2. Look for project requirements (.nvmrc takes priority for node)
if [[ -f ".nvmrc" ]]; then
req_node=$(cat .nvmrc | tr -d '\n' | tr -d '\r')
fi
# Fallback to package.json engines if it exists
if [[ -f "package.json" ]]; then
if [[ -z "$req_node" ]]; then
# Safely extract engines.node using Node itself
req_node=$(node -e "try { console.log(require('./package.json').engines.node || '') } catch(e) {}" 2>/dev/null)
fi
# Extract engines.npm
req_npm=$(node -e "try { console.log(require('./package.json').engines.npm || '') } catch(e) {}" 2>/dev/null)
fi
# 3. Print Current Versions
print -P "%F{magenta}Current Node:%f %F{cyan}${current_node}%f"
print -P "%F{magenta}Current NPM:%f %F{cyan}v${current_npm}%f"
# 4. Evaluate and Print Requirements (if they exist)
if [[ -n "$req_node" || -n "$req_npm" ]]; then
echo ""
print -P "%F{242}Project Requirements:%f"
# Node Requirement Check
if [[ -n "$req_node" ]]; then
# Extract just the major version number for a reliable comparison
local clean_current=$(echo "$current_node" | grep -oE '[0-9]+' | head -1)
local clean_req=$(echo "$req_node" | grep -oE '[0-9]+' | head -1)
if [[ "$clean_current" == "$clean_req" || "$current_node" == *"$req_node"* ]]; then
print -P "%F{green}✔ Node:%f ${req_node}"
else
print -P "%F{red}✘ Node:%f ${req_node} (Mismatch detected)"
fi
fi
# NPM Requirement Check
if [[ -n "$req_npm" ]]; then
local clean_current_npm=$(echo "$current_npm" | grep -oE '[0-9]+' | head -1)
local clean_req_npm=$(echo "$req_npm" | grep -oE '[0-9]+' | head -1)
if [[ "$clean_current_npm" == "$clean_req_npm" || "$current_npm" == *"$req_npm"* ]]; then
print -P "%F{green}✔ NPM:%f ${req_npm}"
else
print -P "%F{red}✘ NPM:%f ${req_npm} (Mismatch detected)"
fi
fi
fi
}
Just run nvi (Node Version Information) and we're golden...
...but we could be platinum if we called this automatically when you change directory into one with node expected!
# # # # # # # # # # # # #
# Run nvi automatically #
# # # # # # # # # # # # #
auto_check_node_env() {
# Check if we are in a folder with Node files
if [[ -f "package.json" || -f ".nvmrc" ]]; then
echo "" # Add a blank line for visual breathing room
nvi
fi
}
# Attach it to the 'Change Directory' hook
add-zsh-hook chpwd auto_check_node_env
🤌 Great success.
Now every time I cd into the root of one of my node projects, it runs this command so I'll be shown without needing to remember to check. I stopped short of letting it nvm into the "right" version automatically hah
The Beautifully Colorful Path Highlighting and Git Info
First, I installed this color theme called Bifrost:
Then, for the current directory path, I wanted to grey out the roots of the path, highlight the project name by detecting if it's in a git repository, then highlight everything after the project name in a different color.
The end result is the most significant parts being easy to distinguish and effortlessly identified at a glance. I. Love. It.
There's all kinds of other stuff in here like basic git status indicators, the branch, separate counts of staged and unstaged files, etc.
The first part of the prompt is something that is slightly redundant indicating complete vs a failed reason, followed by a completion timestamp of the previous command AND the number of seconds the previous command took (if it was more than one).
A couple line breaks after that and the typical PROMPT shows up.
# # # # # # # # # # # # #
# Meta info of last cmd #
# # # # # # # # # # # # #
# 1. Capture the start time of a command
preexec() {
timer=${timer:-$SECONDS}
}
# 2. Calculate the difference and format it
calculate_timer() {
if [[ -n "$timer" ]]; then
timer_show=$(($SECONDS - $timer))
if [[ $timer_show -ge 1 ]]; then
export ELAPSED="%F{yellow}${timer_show}s %f"
else
export ELAPSED=""
fi
unset timer
else
# THE FIX: If no command was run, clear the old time!
export ELAPSED=""
fi
}
add-zsh-hook precmd calculate_timer
# # # # # # # # # # # # #
# Best git aware prompt #
# # # # # # # # # # # # #
# look inside the variables every time the PROMPT is printed
setopt PROMPT_SUBST
# Fetch the Mac Display Name
DISPLAY_NAME=$(id -F)
# Define the raw escape codes for Dim and Reset
DIM=$'\e[2m'
RESET=$'\e[22m'
# %{${DIM}%}%F{yellow}%~%f%{${RESET}%}
set_surgical_path() {
local exit_code=$? # capture exit code of previous command
local repo_root
# Get the absolute path to the repo root
repo_root=$(git rev-parse --show-toplevel 2>/dev/null)
local GIT_INFO="" # Start with a blank slate
if [[ -n "$repo_root" ]]; then
local full_path=$(pwd)
# 1. Everything BEFORE the repo root
# We take the directory of the repo_root (its parent)
local parent_dir=$(dirname "$repo_root")
local prefix="${parent_dir}/"
prefix="${prefix/#$HOME/~}" # Clean up Home path
# 2. The Repo folder itself
local repo_name=$(basename "$repo_root")
# 3. Everything AFTER the repo root
# We remove the repo_root path from the full_path
local suffix="${full_path#$repo_root}"
# Assemble: Dim Prefix + Bright Repo + Dim Suffix
DYNAMIC_PATH="%{${DIM}%}%F{white}${prefix}%f%{${RESET}%}"
DYNAMIC_PATH+="%F{magenta}${repo_name}%f"
DYNAMIC_PATH+="%F{blue}${suffix}%f"
# Get the branch name, fallback to short hash if in detached HEAD
local git_branch=$(git branch --show-current 2>/dev/null || git rev-parse --short HEAD 2>/dev/null)
# Check for Action States (Merging / Rebasing)
local git_action=""
if [[ -f "$repo_root/.git/MERGE_HEAD" ]]; then
git_action="%F{yellow}(merge)%f "
elif [[ -d "$repo_root/.git/rebase-merge" || -d "$repo_root/.git/rebase-apply" ]]; then
git_action="%F{yellow}(rebase)%f "
fi
# Check Clean/Dirty Status
local git_state=""
local git_status=$(git status --porcelain 2>/dev/null)
if [[ -z "$git_status" ]]; then
git_state="%F{green}✔%f" # Perfectly clean
else
# Check for staged changes (+) and unstaged/untracked files (*)# Count lines matching staged (column 1) and unstaged/untracked (column 2)
local staged_count=$(echo "$git_status" | grep -c '^[AMRCD]')
local unstaged_count=$(echo "$git_status" | grep -c '^.[MD?]')
# If there are staged files, add the yellow count
if [[ "$staged_count" -gt 0 ]]; then
git_state+="%F{yellow}+${staged_count}%f"
fi
# If there are unstaged/untracked files, add the red count
if [[ "$unstaged_count" -gt 0 ]]; then
# Add a space for readability if we also have staged files (e.g., +2 *3)
[[ -n "$git_state" ]] && git_state+=" "
git_state+="%F{red}*${unstaged_count}%f"
fi
fi
# Assemble the final Git string
GIT_INFO=" on %F{cyan}${git_branch}%f ${git_action}${git_state}"
else
# Not in a repo: Show the whole path dimmed
DYNAMIC_PATH="%{${DIM}%}%F{magenta}%~%f%{${RESET}%}"
fi
# Define the Prompt
# %D{%H:%M:%S} = Hour:Minute:Second
# %n = username
# %~ = current directory (shortened)
# %# = % for users, # for root (I replaced this with: %(!.#.$))
# %(!.#.$) = # for root, $ for users
# The %(?.X.Y) syntax means: If last exit code was 0, show X, else show Y ## %(?.%F{green}Completed.%F{red}Stopped)%f
local nl=$'\n' # ${nl}
local status_line=""
if [[ $HISTCMD -ne $LAST_HISTCMD ]]; then
local status_text=""
# 2. The Exit Code Skyscraper
case $exit_code in
0) status_text="%F{green}Completed" ;;
# The "Oh, I meant to do that" code
130) status_text="%F{yellow}Stopped" ;; # SIGINT (Ctrl+C)
# The "Wait, what just happened?" codes
126) status_text="%F{magenta}Denied (126)" ;; # Permission denied / Not executable
127) status_text="%F{magenta}Not Found (127)" ;; # Typo in command name
# The "Violent Crash" codes
137) status_text="%F{red}Killed / Out of Memory (137)" ;; # SIGKILL (Often the Out-Of-Memory killer)
139) status_text="%F{red}Segfault (139)" ;; # SIGSEGV (Memory access violation)
143) status_text="%F{yellow}Terminated (143)" ;; # SIGTERM (Graceful kill command)
# The Catch-All for standard script errors
*) status_text="%F{red}Exit code: ${exit_code}" ;;
esac
status_line="${nl}%{${DIM}%}${status_text}%f%{${RESET}%} %F{242}at %D{%H:%M:%S}%f ${ELAPSED}${nl}${nl}"
fi
LAST_HISTCMD=$HISTCMD
local name_path_git="%F{magenta}${DISPLAY_NAME}%f in ${DYNAMIC_PATH}${GIT_INFO}"
local input_indicator="${nl}%{${DIM}%}%F{yellow}%(!.#.$)%f%{${RESET}%}"
PROMPT="${status_line}${name_path_git}${input_indicator} "
}
# 4. Tell the surgical path function to run before every prompt
add-zsh-hook precmd set_surgical_path
The final touch
Place a little 👽 Extra Terrestrial emoji in right prompt so I can scroll up the wall of text and find my inputs a little more easily.
# # # # # # # # # # # # #
# A little splash of me #
# # # # # # # # # # # # #
RPROMPT='👽'
# # # # # # # # # # # # #
# This was a triumph. ♫ #
# # # # # # # # # # # # #
# I'm making a note here: Huge success.
# # # # # # # # # # # # #
# Things added by tools #
# # # # # # # # # # # # #
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads nvm bash_completion
Open Contact 👽
Please do reach out if you need help with any of this, have feature requests, or want to share what you've created!
My heart is open to receive abundance in all forms, flowing to me in many expected and unexpected ways.
Venmo
https://account.venmo.com/u/JaneOri
PayPal Donate to PropJockey
https://www.paypal.com/cgi-bin/webscr...
Ko-Fi
https://ko-fi.com/janeori
ETH
0x674D4191dEBf9793e743D21a4B8c4cf1cC3beF54
BTC
bc1qe2ss8hvmskcxpmk046msrjpmy9qults2yusgn9
XRP (XRPL Mainnet)
X7zmKiqEhMznSXgj9cirEnD5sWo3iZPqbNPChdEKV9sM9WF
XRP (Base Network)
0xb4eBF3Ec089DE7820ac69771b9634C9687e43F70





Top comments (0)