# =========================================== # ZSH Hacks - Dreams of Code # =========================================== # Add these to your .zshrc file # =========================================== # ------------------------------------------- # 1. Edit Command Buffer # ------------------------------------------- # Open the current command in your $EDITOR (e.g., neovim) # Press Ctrl+X followed by Ctrl+E to trigger autoload -Uz edit-command-line zle -N edit-command-line bindkey '^X^E' edit-command-line # For Vi mode users: # bindkey -M vicmd 'v' edit-command-line # ------------------------------------------- # 2. Undo in ZSH # ------------------------------------------- # Press Ctrl+_ (Ctrl+Underscore) to undo # This is built-in, no configuration needed! # Redo widget exists but has no default binding: # bindkey '^Y' redo # Example binding if you want it # ------------------------------------------- # 3. Magic Space - Expand History # ------------------------------------------- # Expands history expressions like !! or !$ when you press space bindkey ' ' magic-space # ------------------------------------------- # 4. chpwd Hook - Run Commands on Directory Change # ------------------------------------------- # NOTE: Only one chpwd hook can be defined at once # To merge them, use add-zsh-hook which is mentioned below # Example: List directory contents on cd chpwd() { ls } # Example: Auto-activate Python virtual environments chpwd() { if [[ -d .venv ]]; then source .venv/bin/activate fi } # Example: Auto-load Nix development shells chpwd() { if [[ -f flake.nix ]] && [[ -z "$IN_NIX_SHELL" ]]; then nix develop fi } # Example: Auto-use correct Node version with nvm chpwd() { if [[ -f .nvmrc ]]; then nvm use fi } # ------------------------------------------- # 4.1. Bonus: Merging Hooks # ------------------------------------------- # To merge hooks, use add-zsh-hook autoload -Uz add-zsh-hook # Then Define separate functions function auto_venv() { # If already in a virtualenv, do nothing if [[ -n "$VIRTUAL_ENV" && "$PWD" != *"${VIRTUAL_ENV:h}"* ]]; then deactivate return fi [[ -n "$VIRTUAL_ENV" ]] && return local dir="$PWD" while [[ "$dir" != "/" ]]; do if [[ -f "$dir/.venv/bin/activate" ]]; then source "$dir/.venv/bin/activate" return fi dir="${dir:h}" done } function auto_nix() { # If we're already in a nix develop shell, do nothing [[ -n "$IN_NIX_SHELL" ]] && return # Walk up to find a flake local dir="$PWD" while [[ "$dir" != "/" ]]; do if [[ -f "$dir/flake.nix" ]]; then # If this project already has .envrc, just allow it (you can remove this if you prefer) if [[ ! -f "$dir/.envrc" ]]; then # Create .envrc that loads the dev env (fast, no interactive shell) cat > "$dir/.envrc" <<'EOF' # autogenerated: load flake dev environment eval "$(nix print-dev-env)" EOF command direnv allow "$dir" >/dev/null 2>&1 fi command direnv reload >/dev/null 2>&1 return fi dir="${dir:h}" done } function auto_nvm() { [[ -f .nvmrc ]] && nvm use } # Register them all add-zsh-hook chpwd auto_venv add-zsh-hook chpwd auto_nix add-zsh-hook chpwd auto_nvm # ------------------------------------------- # 5. Suffix Aliases - Open Files by Extension # ------------------------------------------- # Just type the filename to open it with the associated program alias -s json=jless alias -s md=bat alias -s go='$EDITOR' alias -s rs='$EDITOR' alias -s txt=bat alias -s log=bat alias -s py='$EDITOR' alias -s js='$EDITOR' alias -s ts='$EDITOR' alias -s html=open # macOS: open in default browser # ------------------------------------------- # 6. Global Aliases - Use Anywhere in Commands # ------------------------------------------- # Redirect stderr to /dev/null alias -g NE='2>/dev/null' # Redirect stdout to /dev/null alias -g NO='>/dev/null' # Redirect both stdout and stderr to /dev/null alias -g NUL='>/dev/null 2>&1' # Pipe to jq alias -g J='| jq' # Copy output to clipboard (macOS) alias -g C='| pbcopy' # Copy output to clipboard (Linux with xclip) # alias -g C='| xclip -selection clipboard' # ------------------------------------------- # 7. zmv - Advanced Batch Rename/Move # ------------------------------------------- # Enable zmv autoload -Uz zmv # Usage examples: # zmv '(*).log' '$1.txt' # Rename .log to .txt # zmv -w '*.log' '*.txt' # Same thing, simpler syntax # zmv -n '(*).log' '$1.txt' # Dry run (preview changes) # zmv -i '(*).log' '$1.txt' # Interactive mode (confirm each) # Helpful aliases for zmv alias zcp='zmv -C' # Copy with patterns alias zln='zmv -L' # Link with patterns # ------------------------------------------- # 8. Named Directories - Bookmark Folders # ------------------------------------------- # Access with ~name syntax, e.g., cd ~yt or ls ~yt hash -d yt=~/projects/youtube hash -d dot=~/.dotfiles hash -d dl=~/Downloads # Add your own commonly used directories here # ------------------------------------------- # 9. Custom Widgets # ------------------------------------------- # Clear screen but keep current command buffer function clear-screen-and-scrollback() { echoti civis >"$TTY" printf '%b' '\e[H\e[2J\e[3J' >"$TTY" echoti cnorm >"$TTY" zle redisplay } zle -N clear-screen-and-scrollback bindkey '^Xl' clear-screen-and-scrollback # Copy current command buffer to clipboard (macOS) function copy-buffer-to-clipboard() { echo -n "$BUFFER" | pbcopy zle -M "Copied to clipboard" } zle -N copy-buffer-to-clipboard bindkey '^Xc' copy-buffer-to-clipboard # For Linux with wl-copy: # function copy-buffer-to-clipboard() { # echo -n "$BUFFER" | wl-copy # zle -M "Copied to clipboard" # } # ------------------------------------------- # 10. Hotkey Insertions - Text Snippets # ------------------------------------------- # Insert git commit template (Ctrl+X, G, C) # \C-b moves cursor back one position bindkey -s '^Xgc' 'git commit -m ""\C-b' # More examples: bindkey -s '^Xgp' 'git push origin ' bindkey -s '^Xgs' 'git status\n' bindkey -s '^Xgl' 'git log --oneline -n 10\n'