Productivity¶
Tools and techniques to boost your command-line efficiency.
Shell Aliases¶
Git Aliases¶
# Add to ~/.zshrc or ~/.bashrc
alias g="git"
alias gs="git status"
alias ga="git add"
alias gc="git commit"
alias gp="git push"
alias gl="git pull"
alias gd="git diff"
alias gco="git checkout"
alias gsw="git switch"
alias gb="git branch"
alias glog="git log --oneline -15"
# Common workflows
alias gac="git add -A && git commit -m"
alias gundo="git reset HEAD~1"
alias gamend="git commit --amend --no-edit"
alias gpf="git push --force-with-lease"
Docker Aliases¶
alias d="docker"
alias dc="docker compose"
alias dps="docker ps"
alias dlog="docker logs -f"
alias dex="docker exec -it"
alias dcu="docker compose up -d"
alias dcd="docker compose down"
alias dcl="docker compose logs -f"
alias dcr="docker compose restart"
alias dprune="docker system prune -af --volumes"
Project Aliases¶
alias py="python"
alias pytest="uv run pytest"
alias lint="uv run ruff check --fix ."
alias format="uv run ruff format ."
alias migrate="uv run alembic upgrade head"
alias shell="uv run python -c 'import code; code.interact(local=locals())'"
# Node
alias dev="bun run dev"
alias build="bun run build"
alias test="bun test"
Navigation Aliases¶
alias ..="cd .."
alias ...="cd ../.."
alias ....="cd ../../.."
alias ~="cd ~"
# Project directories
alias proj="cd ~/projects"
alias work="cd ~/work"
Shell Functions¶
Quick Project Start¶
# Start a project with common services
devstart() {
echo "Starting development environment..."
docker compose up -d db redis
sleep 2
uv run alembic upgrade head
echo "Ready! Run 'uv run uvicorn app.main:app --reload'"
}
# Stop all project services
devstop() {
docker compose down
pkill -f "uvicorn"
}
Git Helpers¶
# Create branch and push
gnew() {
git checkout -b "$1"
git push -u origin "$1"
}
# Quick commit with message
gcm() {
git add -A
git commit -m "$*"
}
# Interactive branch cleanup
gclean() {
git branch --merged main | grep -v "main" | xargs -n 1 git branch -d
}
# Show recent branches
grecent() {
git for-each-ref --sort=-committerdate refs/heads/ \
--format='%(committerdate:short) %(refname:short)' \
| head -10
}
Utility Functions¶
# Create directory and cd into it
mkcd() {
mkdir -p "$1" && cd "$1"
}
# Find and kill process by port
killport() {
kill -9 $(lsof -t -i:"$1")
}
# Quick HTTP server
serve() {
local port="${1:-8000}"
python -m http.server "$port"
}
# Extract any archive
extract() {
case "$1" in
*.tar.bz2) tar xjf "$1" ;;
*.tar.gz) tar xzf "$1" ;;
*.bz2) bunzip2 "$1" ;;
*.gz) gunzip "$1" ;;
*.tar) tar xf "$1" ;;
*.tbz2) tar xjf "$1" ;;
*.tgz) tar xzf "$1" ;;
*.zip) unzip "$1" ;;
*.7z) 7z x "$1" ;;
*) echo "Unknown format: $1" ;;
esac
}
fzf (Fuzzy Finder)¶
Installation¶
Basic Usage¶
# Find files
fzf
# Pipe anything
cat file.txt | fzf
ps aux | fzf
# Preview
fzf --preview 'cat {}'
fzf --preview 'bat --color=always {}'
Key Bindings¶
After running install script:
Ctrl+R— Search command historyCtrl+T— Search filesAlt+C— Search directories and cd
Custom Commands¶
# Git branch switcher
alias gb="git branch | fzf | xargs git checkout"
# Git log browser
alias gshow="git log --oneline | fzf --preview 'git show {1}'"
# Kill process interactively
alias fkill="ps aux | fzf | awk '{print \$2}' | xargs kill"
# Docker container shell
alias dsh="docker ps --format '{{.Names}}' | fzf | xargs -I {} docker exec -it {} bash"
# Open file in editor
alias fe="fzf --preview 'bat --color=always {}' | xargs -r $EDITOR"
fzf Configuration¶
# ~/.zshrc or ~/.bashrc
export FZF_DEFAULT_COMMAND='fd --type f --hidden --follow --exclude .git'
export FZF_CTRL_T_COMMAND="$FZF_DEFAULT_COMMAND"
export FZF_ALT_C_COMMAND='fd --type d --hidden --follow --exclude .git'
export FZF_DEFAULT_OPTS="
--height 40%
--layout=reverse
--border
--preview 'bat --color=always --style=numbers --line-range=:500 {}'
"
tmux (Terminal Multiplexer)¶
Installation¶
Basic Commands¶
# Start new session
tmux
tmux new -s project
# Attach to session
tmux attach
tmux attach -t project
# List sessions
tmux ls
# Kill session
tmux kill-session -t project
Key Bindings (prefix = Ctrl+b)¶
Sessions:
- Ctrl+b d — Detach
- Ctrl+b s — List sessions
- Ctrl+b $ — Rename session
Windows:
- Ctrl+b c — New window
- Ctrl+b , — Rename window
- Ctrl+b n — Next window
- Ctrl+b p — Previous window
- Ctrl+b w — List windows
- Ctrl+b & — Kill window
Panes:
- Ctrl+b % — Split vertical
- Ctrl+b " — Split horizontal
- Ctrl+b arrow — Navigate panes
- Ctrl+b z — Toggle pane zoom
- Ctrl+b x — Kill pane
- Ctrl+b { — Move pane left
- Ctrl+b } — Move pane right
Configuration¶
~/.tmux.conf:
# Better prefix
set -g prefix C-a
unbind C-b
bind C-a send-prefix
# Mouse support
set -g mouse on
# Start numbering at 1
set -g base-index 1
setw -g pane-base-index 1
# Faster escape
set -sg escape-time 0
# Better splits
bind | split-window -h -c "#{pane_current_path}"
bind - split-window -v -c "#{pane_current_path}"
# Vim-style pane navigation
bind h select-pane -L
bind j select-pane -D
bind k select-pane -U
bind l select-pane -R
# Reload config
bind r source-file ~/.tmux.conf \; display "Reloaded!"
tmux + Development¶
# Development session script
#!/bin/bash
# dev-session.sh
SESSION="project"
tmux new-session -d -s $SESSION
# Window 1: Editor
tmux rename-window -t $SESSION:1 'editor'
tmux send-keys -t $SESSION:1 'nvim' C-m
# Window 2: Server
tmux new-window -t $SESSION:2 -n 'server'
tmux send-keys -t $SESSION:2 'docker compose up' C-m
# Window 3: Shell
tmux new-window -t $SESSION:3 -n 'shell'
# Attach to session
tmux attach -t $SESSION
direnv¶
Auto-load environment variables when entering directories.
Installation¶
# macOS
brew install direnv
# Ubuntu
sudo apt install direnv
# Add to shell
eval "$(direnv hook zsh)" # or bash
Usage¶
# Create .envrc in project
echo 'export DATABASE_URL="postgresql://localhost/dev"' > .envrc
# Allow the envrc
direnv allow
# Now entering directory automatically sets DATABASE_URL
Common .envrc Patterns¶
# Load .env file
dotenv
# Or specific file
dotenv .env.local
# Python virtual environment
source .venv/bin/activate
# Node version
use node 18
# Custom PATH
PATH_add bin
# Layout (creates and activates venv)
layout python3
# Load secrets from file
source_env_if_exists .env.secrets
zoxide (Smart cd)¶
Installation¶
Usage¶
# Jump to directory
z project # Jumps to most frequent "project" match
z doc # Jumps to most frequent directory containing "doc"
# Interactive selection
zi
# Add directory manually
zoxide add /path/to/dir
# Query database
zoxide query project
ripgrep (Fast Search)¶
Installation¶
Usage¶
# Basic search
rg "pattern"
# In specific file types
rg "pattern" -t py
rg "pattern" -t js -t ts
# Exclude patterns
rg "pattern" -g '!*.test.js'
# Case insensitive
rg -i "pattern"
# Show context
rg "pattern" -C 3
# Count matches
rg "pattern" -c
# Files only
rg "pattern" -l
# Fixed string (not regex)
rg -F "exact.string"
Configuration¶
~/.ripgreprc:
Dotfiles Management¶
Git-based Approach¶
# Initialize dotfiles repo
cd ~
git init --bare .dotfiles
# Alias for dotfiles commands
alias dotfiles='git --git-dir=$HOME/.dotfiles --work-tree=$HOME'
# Ignore untracked files
dotfiles config --local status.showUntrackedFiles no
# Add files
dotfiles add .zshrc
dotfiles add .tmux.conf
dotfiles commit -m "Add shell configs"
dotfiles push origin main
Stow-based Approach¶
# Install stow
brew install stow
# Directory structure
dotfiles/
├── zsh/
│ └── .zshrc
├── tmux/
│ └── .tmux.conf
└── git/
└── .gitconfig
# Apply configs
cd dotfiles
stow zsh tmux git
Recommended Tools Summary¶
| Tool | Purpose | Install |
|---|---|---|
| fzf | Fuzzy finder | brew install fzf |
| tmux | Terminal multiplexer | brew install tmux |
| direnv | Environment loader | brew install direnv |
| zoxide | Smart cd | brew install zoxide |
| ripgrep | Fast search | brew install ripgrep |
| fd | Fast find | brew install fd |
| bat | Better cat | brew install bat |
| eza | Better ls | brew install eza |
| jq | JSON processor | brew install jq |
| tldr | Simplified man pages | brew install tldr |