Last active
July 21, 2025 13:30
-
-
Save joshcough/6c532f2cb7eb8cb2cef633ba6582ecbd to your computer and use it in GitHub Desktop.
My zshrc
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# ============================================================================= | |
# 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