Skip to content

Instantly share code, notes, and snippets.

@joshcough
Last active July 21, 2025 13:30
Show Gist options
  • Save joshcough/6c532f2cb7eb8cb2cef633ba6582ecbd to your computer and use it in GitHub Desktop.
Save joshcough/6c532f2cb7eb8cb2cef633ba6582ecbd to your computer and use it in GitHub Desktop.
My zshrc
# =============================================================================
# ZSH CONFIGURATION
# =============================================================================
# =============================================================================
# HISTORY CONFIGURATION
# =============================================================================
# Unlimited history
export HISTSIZE=1000000000
export SAVEHIST=1000000000
# Append immediately so nothing is lost
setopt INC_APPEND_HISTORY
# Prevent consecutive duplicates
setopt HIST_IGNORE_DUPS
# Show timestamps in history
setopt EXTENDED_HISTORY
export HIST_STAMPS="yyyy-mm-dd"
# Uncomment to have history immediately available in across all sessions
# setopt SHARE_HISTORY
# =============================================================================
# COMMAND TIMING DISPLAY
# =============================================================================
# Color definitions for timing display
TIMING_LABEL_COLOR="\033[94m" # Soft blue for labels
TIMING_FAST_COLOR="\033[92m" # Soft green for fast commands (<1s)
TIMING_MEDIUM_COLOR="\033[93m" # Light yellow for medium commands (1-10s)
TIMING_SLOW_COLOR="\033[31m" # Red for slow commands (10s+)
TIMING_RESET="\033[0m" # Reset color
# Smart command timing display - always show command, layout based on length
preexec() {
timer=$(date +%s.%N)
export COMMAND_START_TIME=$(date)
export CURRENT_COMMAND="$1"
}
precmd() {
if [[ -n $timer ]]; then
local end_timer=$(date +%s.%N)
local duration=$(echo "$end_timer - $timer" | bc -l)
local end_time=$(date)
# Add blank line before timing info
echo
# Determine timing color
local timing_color
if (( $(echo "$duration < 0.001" | bc -l) )); then
timing_color="${TIMING_FAST_COLOR}(<1ms)${TIMING_RESET}"
elif (( $(echo "$duration < 1" | bc -l) )); then
timing_color="${TIMING_FAST_COLOR}($(echo "$duration * 1000" | bc -l | xargs printf "%.0f")ms)${TIMING_RESET}"
elif (( $(echo "$duration < 10" | bc -l) )); then
timing_color="${TIMING_MEDIUM_COLOR}($(printf "%.2f" $duration)s)${TIMING_RESET}"
else
timing_color="${TIMING_SLOW_COLOR}($(printf "%.2f" $duration)s)${TIMING_RESET}"
fi
# Show start time for commands that took 1+ seconds
if (( $(echo "$duration >= 1" | bc -l) )); then
echo -e " ${TIMING_LABEL_COLOR}Started at:${TIMING_RESET} \033[37m$COMMAND_START_TIME\033[0m"
fi
# Show command and timing based on command length
local cmd_length=${#CURRENT_COMMAND}
if [[ $cmd_length -le 20 ]]; then
# Short command - single line
echo -e " ${TIMING_LABEL_COLOR}Command:${TIMING_RESET} $CURRENT_COMMAND ${TIMING_LABEL_COLOR}Ended at:${TIMING_RESET} \033[37m$end_time\033[0m $timing_color"
else
# Long command - two lines
echo -e " ${TIMING_LABEL_COLOR}Command:${TIMING_RESET} $CURRENT_COMMAND"
echo -e " ${TIMING_LABEL_COLOR}Ended at:${TIMING_RESET} \033[37m$end_time\033[0m $timing_color"
fi
echo # Add blank line for spacing
unset timer COMMAND_START_TIME CURRENT_COMMAND
fi
}
# =============================================================================
# PROMPT AND GIT INTEGRATION
# =============================================================================
project_info() {
if [[ -f package.json ]]; then
local name=$(jq -r '.name // "unknown"' package.json 2>/dev/null)
local version=$(jq -r '.version // "unknown"' package.json 2>/dev/null)
echo " 📦 $name@$version"
elif [[ -f spago.dhall ]]; then
echo " 🟣 PureScript"
elif [[ -f stack.yaml ]]; then
echo " λ Haskell"
elif [[ -f build.sbt ]]; then
echo " 🔥 Scala"
elif [[ -f requirements.txt || -f pyproject.toml ]]; then
echo " 🐍 Python"
fi
}
git_prompt_detailed() {
if git rev-parse --git-dir > /dev/null 2>&1; then
local branch=$(git branch --show-current 2>/dev/null)
local git_info=""
local file_changes=""
# Check for uncommitted changes
if ! git diff --quiet 2>/dev/null; then
git_info="*"
fi
# Check for untracked files
if git ls-files --other --exclude-standard --directory --no-empty-directory 2>/dev/null | grep -q .; then
git_info="${git_info}+"
fi
# Check ahead/behind status with origin
local ahead_behind=$(git rev-list --left-right --count origin/$branch...$branch 2>/dev/null)
if [[ -n "$ahead_behind" ]]; then
local ahead=$(echo $ahead_behind | cut -f2)
local behind=$(echo $ahead_behind | cut -f1)
[[ $ahead -gt 0 ]] && git_info="${git_info} ${ahead} commits ahead"
[[ $behind -gt 0 ]] && git_info="${git_info} ${behind} commits behind"
fi
# Count changed files
local changed_files=$(git diff --name-only 2>/dev/null | wc -l | tr -d ' ')
local staged_files=$(git diff --cached --name-only 2>/dev/null | wc -l | tr -d ' ')
if [[ $changed_files -gt 0 || $staged_files -gt 0 ]]; then
local total_changed=$((changed_files + staged_files))
file_changes=", ${total_changed} files changed"
fi
# Color based on status
if [[ -n "$git_info" ]]; then
echo "(%F{magenta}${branch}${git_info}${file_changes}%f)"
else
echo "(%F{green}${branch}%f)"
fi
else
echo "(%F{red}no git%f)"
fi
}
# Enable prompt substitution and set the enhanced prompt
# setopt PROMPT_SUBST
# PS1='%F{240}[%D{%m/%d %H:%M}]%f %F{cyan}%1~%f$(git_prompt_info) $ '
# Multiline prompt with project info
#PS1='%F{240}[%D{%m/%d %H:%M}]%f %F{cyan}%1~%f$(git_prompt_info)$(project_info)
#$ '
# Four-line prompt setup
setopt PROMPT_SUBST
PS1='%F{240}[%D{%m/%d %H:%M}]%f$(project_info)
%F{cyan}%~%f
$(git_prompt_detailed)
$ '
# =============================================================================
# TERMINAL LOGGING SYSTEM
# =============================================================================
# Load the complete logging system
export TERMINAL_LOG_DIR="$HOME/.terminal_logs"
source ~/.terminal_logging_rc
# Initialize logging on startup
init_terminal_logging
# =============================================================================
# lsh command
# =============================================================================
lsh() {
local dir="."
local show_date=0
# Parse arguments
if [[ "$1" == "-d" || "$1" == "--date" ]]; then
show_date=1
[[ -n "$2" ]] && dir="$2"
else
[[ -n "$1" ]] && dir="$1"
[[ "$2" == "-d" || "$2" == "--date" ]] && show_date=1
fi
local files=($(ls -1 "$dir"))
local maxlen=0
for f in "${files[@]}"; do
[[ -f "$dir/$f" ]] || continue
(( ${#f} > maxlen )) && maxlen=${#f}
done
for f in "${files[@]}"; do
[[ -f "$dir/$f" ]] || continue
local hsize=$(du -h "$dir/$f" | awk '{print $1}')
if (( show_date )); then
local lsline=$(ls -l "$dir/$f")
local lsd=$(echo "$lsline" | awk '{print $6, $7, $8}')
printf "%-*s %-13s %8s\n" "$maxlen" "$f" "$lsd" "$hsize"
else
printf "%-*s %8s\n" "$maxlen" "$f" "$hsize"
fi
done
}
# =============================================================================
# YOUR OTHER ZSH CONFIGURATION
# =============================================================================
# Add any other aliases, PATH modifications, etc. below this line
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment