← All Skills

Dev Terminal

v1.0.0 Tooling
1 files, 17.0 KB ~1,104 words · 5 min read Updated 2026-03-26

Complete terminal setup for macOS and Windows. Powerlevel10k, iTerm2, fzf, zoxide, eza, bat, delta — 30 minutes from scratch.

$ npx snappy-skills install dev-terminal
zip ↓
Documents
SKILL.md
17.0 KB

Dev Terminal Setup#

A fast, beautiful, productive terminal. Everything here is field-tested — no "cool but never use it" tools. Every tool earns its place by saving time daily.

What You Get#

┌─────────────────────────────────────────────────────────┐
│ ~/Projects/my-app main*                    02:45:30 PM  │
│ ❯ git diff                                              │
│                                                          │
│  ┌─ src/index.ts ──────────┬─ src/index.ts ───────────┐ │
│  │ 1  const old = "before" │ 1  const new = "after"   │ │
│  │                         │ 2  const added = true     │ │
│  └─────────────────────────┴──────────────────────────┘ │
│                                                          │
│ ❯ p                                                      │
│  > my-app                                                │
│    client-project                                        │
│    mcp-servers                                           │
│    dashboard                                             │
│  4/47 ─────────────────────────────────────────────────  │
│                                                          │
│ ❯ ls                                                     │
│  📁 src   📁 public   📄 package.json   📄 tsconfig.json│
└─────────────────────────────────────────────────────────┘

The prompt shows directory + git branch + dirty indicator. No clutter.

git diff shows side-by-side with syntax highlighting (via delta).

p fuzzy-searches all your projects (via fzf).

ls shows icons and colors (via eza).

Setup Order#

Step Tool What It Does Time
1 iTerm2 (Mac) / Windows Terminal Terminal emulator 5 min
2 Oh My Zsh Zsh framework + plugin manager 2 min
3 Powerlevel10k Fast, informative prompt 5 min
4 Nerd Font Icons in terminal 2 min
5 Modern CLI tools fzf, zoxide, eza, bat, delta, fd, ripgrep 5 min
6 Shell functions Project navigation, port killing 5 min
7 Git config Delta integration, useful aliases 5 min

Mac Setup#

iTerm2#

The default Terminal.app works but iTerm2 is better — split panes, profiles, shell integration, better font rendering.

bashbrew install --cask iterm2

Create a profile called "Pro" and set it as default:

Setting Value Why
Font JetBrains Mono Nerd Font, 14pt Nerd Font icons, clean at all sizes
Columns x Rows 140 x 40 Comfortable for side-by-side diffs
Transparency 12% Subtle, lets you see windows behind
Blur On, radius 30 Pairs with transparency for readability
Scrollback 10,000 lines Enough for long build output
Cursor Blinking block Easy to spot
Option key Esc+ (send escape sequence) Enables alt+arrow word navigation

Shell Integration#

bash# iTerm2 → Install Shell Integration (from menu)
# Or manually:
curl -L https://iterm2.com/shell_integration/zsh -o ~/.iterm2_shell_integration.zsh
echo 'source ~/.iterm2_shell_integration.zsh' >> ~/.zshrc

Shell integration enables: click-to-select command output, command history with timestamps, automatic profile switching.


Oh My Zsh + Powerlevel10k#

bash# Install Oh My Zsh
sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"

# Install Powerlevel10k theme
git clone --depth=1 https://github.com/romkatv/powerlevel10k.git \
  ${ZSH_CUSTOM:-$HOME/.oh-my-zsh/custom}/themes/powerlevel10k

# Set theme in ~/.zshrc
# ZSH_THEME="powerlevel10k/powerlevel10k"

# Run configuration wizard
p10k configure

When p10k configure runs, choose:

  • Prompt style: Pure (clean, minimal)
  • Character set: Unicode
  • Prompt colors: Original
  • Show time: 12-hour format
  • One-line prompt: Yes
  • Prompt spacing: Sparse
  • Transient prompt: No

This gives you a prompt like:

~/Projects/my-app main*
❯

The is magenta on success, red on failure. Git info shows in grey. Long commands (>5s) show execution time in yellow.

Instant Prompt#

Powerlevel10k has an "instant prompt" feature — the prompt appears immediately, before zsh finishes loading plugins. Enable it:

bash# At the TOP of ~/.zshrc (before everything else):
if [[ -r "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh" ]]; then
  source "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh"
fi

Plugins#

bash# Install zsh-autosuggestions (fish-style inline suggestions)
git clone https://github.com/zsh-users/zsh-autosuggestions \
  ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-autosuggestions

# Install zsh-syntax-highlighting (colors as you type)
git clone https://github.com/zsh-users/zsh-syntax-highlighting.git \
  ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-syntax-highlighting

In ~/.zshrc:

bashplugins=(git zsh-autosuggestions zsh-syntax-highlighting)

What each does:

  • git — built-in aliases (gst, gco, gd, etc.)
  • zsh-autosuggestions — grey suggestions from your history as you type. Press → to accept.
  • zsh-syntax-highlighting — valid commands turn green, invalid turn red. Instantly.

Nerd Font#

Nerd Fonts patch developer fonts with icons (file type, git, folder icons). Required for Powerlevel10k and eza.

bashbrew install --cask font-jetbrains-mono-nerd-font

# Then set it in iTerm2:
# Profiles → Pro → Text → Font → JetBrains Mono Nerd Font

Modern CLI Tools#

Every tool here replaces a built-in with something faster and more informative. Install all at once:

bashbrew install fzf zoxide eza bat git-delta fd ripgrep

fzf — Fuzzy Finder#

The single most impactful tool. Fuzzy-searches anything — files, directories, command history, git branches.

bash# Set up shell integration
echo 'eval "$(fzf --zsh)"' >> ~/.zshrc

What it gives you:

  • Ctrl+R — fuzzy search command history (replaces the default reverse search)
  • Ctrl+T — fuzzy find files in current directory
  • Alt+C — fuzzy find and cd into directories

zoxide — Smart cd#

Learns your frequently visited directories. Type z proj instead of cd ~/Projects.

bashecho 'eval "$(zoxide init zsh)"' >> ~/.zshrc

Add the alias so it replaces cd entirely:

bashalias cd="z"

Now cd proj works. cd dash jumps to your dashboard project. It learns from usage.

eza — Modern ls#

ls with icons, colors, git status, and tree view.

bashalias ls="eza --icons"
alias ll="eza -la --icons"
alias lt="eza --tree --level=2 --icons"

bat — cat with Wings#

cat with syntax highlighting, line numbers, and git diff markers.

bashalias cat="bat"

git-delta — Beautiful Diffs#

Side-by-side diffs with syntax highlighting. The Dracula theme works well on dark terminals. Configured in .gitconfig (see Git Config section below).

fd — Fast find#

bash# Find all TypeScript files
fd -e ts

# Find file by name
fd "config" --type f

ripgrep — Fast grep#

bash# Search for a pattern across all files
rg "TODO" --type ts

# Search with context
rg "function.*export" -C 3

Shell Functions#

Add these to ~/.zshrc. These are the ones that get used daily.

Project Navigation (the p command)#

bash# Fuzzy-search all projects, cd into selection
p() {
  local dir
  dir=$(find ~/Projects -maxdepth 2 -type d \
    -not -path '*/node_modules/*' \
    -not -path '*/.git/*' \
    -not -path '*/dist/*' \
    -not -path '*/.next/*' | fzf --height 40% --reverse)
  if [[ -n "$dir" ]]; then
    cd "$dir"
  fi
}

Type p, start typing a project name, arrow to select, Enter. Instant navigation.

File Finder (the f command)#

bash# Fuzzy-find a file with bat preview
f() {
  local file
  file=$(fzf --height 80% --preview 'bat --color=always --style=numbers --line-range :200 {}' --preview-window=right:60%)
  if [[ -n "$file" ]]; then
    echo "$file"
  fi
}

Port Management#

bash# Kill process on a port
killport() {
  local pid
  pid=$(lsof -ti :"$1")
  if [[ -n "$pid" ]]; then
    kill -9 "$pid"
    echo "Killed PID $pid on port $1"
  else
    echo "No process on port $1"
  fi
}

# Show all listening ports
alias ports="lsof -i -P -n | grep LISTEN"

Project Scaffolding#

bash# Create a new project with git + npm
mkproj() {
  mkdir -p ~/Projects/"$1" && cd ~/Projects/"$1"
  git init
  npm init -y
  echo "node_modules/\n.env\n.DS_Store" > .gitignore
  echo "Created project: $1"
}

Node Modules Cleanup#

bash# Show all node_modules and their sizes
nm-clean() {
  find "${1:-.}" -name "node_modules" -type d -prune | \
    xargs -I {} du -sh {} | sort -rh
}

# Delete all node_modules (careful!)
nm-nuke() {
  find "${1:-.}" -name "node_modules" -type d -prune -exec rm -rf {} +
  echo "All node_modules deleted"
}

Quick Info#

bashalias ip="curl -s ifconfig.me"
alias weather="curl -s wttr.in/?format=3"
alias path='echo $PATH | tr ":" "\n" | nl'
alias reload="source ~/.zshrc"

Git Config#

Add to ~/.gitconfig:

ini[user]
  name = Your Name
  email = your-email@example.com

[core]
  editor = nano        # or code --wait, or vim
  pager = delta        # use delta for all git output

[interactive]
  diffFilter = delta --color-only

[delta]
  navigate = true       # use n/N to jump between diff sections
  side-by-side = true   # two-column diff view
  line-numbers = true   # show line numbers
  syntax-theme = Dracula

[merge]
  conflictstyle = diff3  # shows base + both sides in conflicts

[diff]
  colorMoved = default   # highlight moved code blocks

[init]
  defaultBranch = main

[push]
  autoSetupRemote = true  # auto-create remote branch on first push

[alias]
  s = status -sb                           # compact status
  lg = log --oneline --graph --decorate -20 # visual log
  lga = log --oneline --graph --all         # all branches
  today = log --since='6am' --oneline       # today's work
  week = log --since='1 week ago' --oneline # this week
  oops = commit --amend --no-edit           # fix last commit
  undo = reset --soft HEAD~1               # undo last commit (keep changes)
  branches = branch -a --sort=-committerdate # branches by recency
  cleanup = "!git branch --merged | grep -v '\\*\\|main\\|master' | xargs -n 1 git branch -d"

Shell Aliases for Git#

bashalias gs="git s"
alias gl="git lg"
alias gp="git push"
alias gpl="git pull"
alias gc="git commit"
alias gca="git commit -a"
alias gco="git checkout"
alias gb="git branches"
alias gd="git diff"
alias gds="git diff --staged"

Windows Setup#

The same productivity on Windows, using Windows Terminal + WSL2.

Windows Terminal#

Install from the Microsoft Store. It's the modern terminal for Windows — tabs, profiles, GPU-accelerated rendering.

WSL2 (Windows Subsystem for Linux)#

WSL2 gives you a full Linux environment inside Windows. All the tools above work identically.

powershell# In PowerShell (as admin):
wsl --install
# Restart, then set up Ubuntu

After WSL2 is running, everything from the Mac section applies:

bash# Inside WSL2:
sudo apt update && sudo apt upgrade -y

# Install Homebrew (yes, it works on Linux)
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

# Then follow the same steps:
# Oh My Zsh → Powerlevel10k → plugins → CLI tools → shell functions → git config

Windows Terminal Profile#

Set WSL2 as your default profile:

json{
  "defaultProfile": "{guid-of-wsl-profile}",
  "profiles": {
    "list": [
      {
        "name": "Ubuntu",
        "source": "Windows.Terminal.Wsl",
        "font": {
          "face": "JetBrains Mono Nerd Font",
          "size": 12
        },
        "opacity": 90,
        "useAcrylic": true,
        "colorScheme": "One Half Dark",
        "startingDirectory": "//wsl$/Ubuntu/home/youruser"
      }
    ]
  }
}

Nerd Font on Windows#

Download from nerdfonts.com:

  1. Download "JetBrains Mono Nerd Font"
  2. Extract the zip
  3. Select all .ttf files → Right-click → "Install for all users"
  4. Set the font in Windows Terminal profile settings

Windows-Specific Tools#

Mac Tool Windows/WSL Equivalent Notes
iTerm2 Windows Terminal Comes with Windows 11, installable on 10
Homebrew Homebrew (in WSL2) Same package manager, works identically
pbcopy / pbpaste clip.exe / powershell.exe Get-Clipboard Clipboard from WSL
open . explorer.exe . Open directory in Explorer from WSL
Spotlight PowerToys Run Alt+Space to launch

WSL2 Clipboard Integration#

bash# Add to ~/.zshrc in WSL2:
alias pbcopy="clip.exe"
alias pbpaste="powershell.exe -command 'Get-Clipboard' | tr -d '\r'"

Now cat file.txt | pbcopy works from WSL2 just like on Mac.

SSH from Windows#

Windows Terminal + WSL2 handles SSH natively. The same ~/.ssh/config patterns from the Mac section work. For connecting to a Mac Mini from Windows:

Host mini
  HostName 100.x.y.z      # Tailscale IP
  User youruser
  ControlMaster auto
  ControlPersist 600
  ServerAliveInterval 60

Complete ~/.zshrc Template#

Here's the full config in order. Customize paths and project directory.

bash# Instant prompt (MUST be at the very top)
if [[ -r "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh" ]]; then
  source "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh"
fi

# Oh My Zsh
export ZSH="$HOME/.oh-my-zsh"
ZSH_THEME="powerlevel10k/powerlevel10k"
plugins=(git zsh-autosuggestions zsh-syntax-highlighting)
source $ZSH/oh-my-zsh.sh

# Powerlevel10k config
[[ ! -f ~/.p10k.zsh ]] || source ~/.p10k.zsh

# Tools
eval "$(fzf --zsh)"
eval "$(zoxide init zsh)"

# Aliases — files
alias ls="eza --icons"
alias ll="eza -la --icons"
alias lt="eza --tree --level=2 --icons"
alias cat="bat"
alias cd="z"

# Aliases — git
alias gs="git s"
alias gl="git lg"
alias gp="git push"
alias gpl="git pull"
alias gc="git commit"
alias gca="git commit -a"
alias gco="git checkout"
alias gb="git branches"
alias gd="git diff"
alias gds="git diff --staged"

# Aliases — utils
alias ports="lsof -i -P -n | grep LISTEN"
alias ip="curl -s ifconfig.me"
alias weather="curl -s wttr.in/?format=3"
alias path='echo $PATH | tr ":" "\n" | nl'
alias reload="source ~/.zshrc"

# Aliases — project dirs
alias proj="cd ~/Projects"

# Functions
p() {
  local dir
  dir=$(find ~/Projects -maxdepth 2 -type d \
    -not -path '*/node_modules/*' \
    -not -path '*/.git/*' \
    -not -path '*/dist/*' \
    -not -path '*/.next/*' | fzf --height 40% --reverse)
  [[ -n "$dir" ]] && cd "$dir"
}

f() {
  local file
  file=$(fzf --height 80% --preview 'bat --color=always --style=numbers --line-range :200 {}' --preview-window=right:60%)
  [[ -n "$file" ]] && echo "$file"
}

killport() {
  local pid=$(lsof -ti :"$1")
  [[ -n "$pid" ]] && kill -9 "$pid" && echo "Killed PID $pid on port $1" || echo "No process on port $1"
}

mkproj() {
  mkdir -p ~/Projects/"$1" && cd ~/Projects/"$1"
  git init && npm init -y
  echo "node_modules/\n.env\n.DS_Store" > .gitignore
  echo "Created project: $1"
}

nm-clean() {
  find "${1:-.}" -name "node_modules" -type d -prune | xargs -I {} du -sh {} | sort -rh
}

nm-nuke() {
  find "${1:-.}" -name "node_modules" -type d -prune -exec rm -rf {} +
  echo "All node_modules deleted"
}

# Node version manager
eval "$(fnm env --use-on-cd)"

# iTerm2 shell integration (Mac only)
[[ -f ~/.iterm2_shell_integration.zsh ]] && source ~/.iterm2_shell_integration.zsh

Anti-Patterns#

Wrong Right
Default Terminal.app with bash iTerm2 with zsh + P10k
Stock ls, cat, grep, find eza, bat, ripgrep, fd
cd ~/Projects/client/dashboard/src z dash or p + fuzzy search
Plain git diff Delta with side-by-side + Dracula theme
Manually finding ports to kill killport 3000
No command history search Ctrl+R with fzf fuzzy matching
Copy config from blog posts Use the template above as a starting point
Install tools you never use Every tool here earns daily usage
---
name: dev-terminal
category: Tooling
description: >
  Complete terminal setup for developers on macOS and Windows. Powerlevel10k prompt, iTerm2 profiles, modern CLI tools (fzf, zoxide, eza, bat, delta), shell functions for project navigation, and git config with beautiful diffs. Reproducible from scratch in under 30 minutes.
---

# Dev Terminal Setup

A fast, beautiful, productive terminal. Everything here is field-tested — no "cool but never use it" tools. Every tool earns its place by saving time daily.

## What You Get

```
┌─────────────────────────────────────────────────────────┐
│ ~/Projects/my-app main*                    02:45:30 PM  │
│ ❯ git diff                                              │
│                                                          │
│  ┌─ src/index.ts ──────────┬─ src/index.ts ───────────┐ │
│  │ 1  const old = "before" │ 1  const new = "after"   │ │
│  │                         │ 2  const added = true     │ │
│  └─────────────────────────┴──────────────────────────┘ │
│                                                          │
│ ❯ p                                                      │
│  > my-app                                                │
│    client-project                                        │
│    mcp-servers                                           │
│    dashboard                                             │
│  4/47 ─────────────────────────────────────────────────  │
│                                                          │
│ ❯ ls                                                     │
│  📁 src   📁 public   📄 package.json   📄 tsconfig.json│
└─────────────────────────────────────────────────────────┘
```

**The prompt** shows directory + git branch + dirty indicator. No clutter.
**`git diff`** shows side-by-side with syntax highlighting (via delta).
**`p`** fuzzy-searches all your projects (via fzf).
**`ls`** shows icons and colors (via eza).

## Setup Order

| Step | Tool | What It Does | Time |
|------|------|-------------|------|
| 1 | iTerm2 (Mac) / Windows Terminal | Terminal emulator | 5 min |
| 2 | Oh My Zsh | Zsh framework + plugin manager | 2 min |
| 3 | Powerlevel10k | Fast, informative prompt | 5 min |
| 4 | Nerd Font | Icons in terminal | 2 min |
| 5 | Modern CLI tools | fzf, zoxide, eza, bat, delta, fd, ripgrep | 5 min |
| 6 | Shell functions | Project navigation, port killing | 5 min |
| 7 | Git config | Delta integration, useful aliases | 5 min |

---

## Mac Setup

### iTerm2

The default Terminal.app works but iTerm2 is better — split panes, profiles, shell integration, better font rendering.

```bash
brew install --cask iterm2
```

#### Recommended Profile Settings

Create a profile called "Pro" and set it as default:

| Setting | Value | Why |
|---------|-------|-----|
| Font | JetBrains Mono Nerd Font, 14pt | Nerd Font icons, clean at all sizes |
| Columns x Rows | 140 x 40 | Comfortable for side-by-side diffs |
| Transparency | 12% | Subtle, lets you see windows behind |
| Blur | On, radius 30 | Pairs with transparency for readability |
| Scrollback | 10,000 lines | Enough for long build output |
| Cursor | Blinking block | Easy to spot |
| Option key | Esc+ (send escape sequence) | Enables alt+arrow word navigation |

#### Shell Integration

```bash
# iTerm2 → Install Shell Integration (from menu)
# Or manually:
curl -L https://iterm2.com/shell_integration/zsh -o ~/.iterm2_shell_integration.zsh
echo 'source ~/.iterm2_shell_integration.zsh' >> ~/.zshrc
```

Shell integration enables: click-to-select command output, command history with timestamps, automatic profile switching.

---

### Oh My Zsh + Powerlevel10k

```bash
# Install Oh My Zsh
sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"

# Install Powerlevel10k theme
git clone --depth=1 https://github.com/romkatv/powerlevel10k.git \
  ${ZSH_CUSTOM:-$HOME/.oh-my-zsh/custom}/themes/powerlevel10k

# Set theme in ~/.zshrc
# ZSH_THEME="powerlevel10k/powerlevel10k"

# Run configuration wizard
p10k configure
```

#### Recommended P10k Style: Pure

When `p10k configure` runs, choose:
- **Prompt style**: Pure (clean, minimal)
- **Character set**: Unicode
- **Prompt colors**: Original
- **Show time**: 12-hour format
- **One-line prompt**: Yes
- **Prompt spacing**: Sparse
- **Transient prompt**: No

This gives you a prompt like:
```
~/Projects/my-app main*
❯
```

The `❯` is magenta on success, red on failure. Git info shows in grey. Long commands (>5s) show execution time in yellow.

#### Instant Prompt

Powerlevel10k has an "instant prompt" feature — the prompt appears immediately, before zsh finishes loading plugins. Enable it:

```bash
# At the TOP of ~/.zshrc (before everything else):
if [[ -r "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh" ]]; then
  source "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh"
fi
```

### Plugins

```bash
# Install zsh-autosuggestions (fish-style inline suggestions)
git clone https://github.com/zsh-users/zsh-autosuggestions \
  ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-autosuggestions

# Install zsh-syntax-highlighting (colors as you type)
git clone https://github.com/zsh-users/zsh-syntax-highlighting.git \
  ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-syntax-highlighting
```

In `~/.zshrc`:
```bash
plugins=(git zsh-autosuggestions zsh-syntax-highlighting)
```

**What each does:**
- `git` — built-in aliases (`gst`, `gco`, `gd`, etc.)
- `zsh-autosuggestions` — grey suggestions from your history as you type. Press → to accept.
- `zsh-syntax-highlighting` — valid commands turn green, invalid turn red. Instantly.

### Nerd Font

Nerd Fonts patch developer fonts with icons (file type, git, folder icons). Required for Powerlevel10k and eza.

```bash
brew install --cask font-jetbrains-mono-nerd-font

# Then set it in iTerm2:
# Profiles → Pro → Text → Font → JetBrains Mono Nerd Font
```

---

## Modern CLI Tools

Every tool here replaces a built-in with something faster and more informative. Install all at once:

```bash
brew install fzf zoxide eza bat git-delta fd ripgrep
```

### fzf — Fuzzy Finder

The single most impactful tool. Fuzzy-searches anything — files, directories, command history, git branches.

```bash
# Set up shell integration
echo 'eval "$(fzf --zsh)"' >> ~/.zshrc
```

**What it gives you:**
- `Ctrl+R` — fuzzy search command history (replaces the default reverse search)
- `Ctrl+T` — fuzzy find files in current directory
- `Alt+C` — fuzzy find and cd into directories

### zoxide — Smart cd

Learns your frequently visited directories. Type `z proj` instead of `cd ~/Projects`.

```bash
echo 'eval "$(zoxide init zsh)"' >> ~/.zshrc
```

Add the alias so it replaces `cd` entirely:
```bash
alias cd="z"
```

Now `cd proj` works. `cd dash` jumps to your dashboard project. It learns from usage.

### eza — Modern ls

`ls` with icons, colors, git status, and tree view.

```bash
alias ls="eza --icons"
alias ll="eza -la --icons"
alias lt="eza --tree --level=2 --icons"
```

### bat — cat with Wings

`cat` with syntax highlighting, line numbers, and git diff markers.

```bash
alias cat="bat"
```

### git-delta — Beautiful Diffs

Side-by-side diffs with syntax highlighting. The Dracula theme works well on dark terminals. Configured in `.gitconfig` (see Git Config section below).

### fd — Fast find

```bash
# Find all TypeScript files
fd -e ts

# Find file by name
fd "config" --type f
```

### ripgrep — Fast grep

```bash
# Search for a pattern across all files
rg "TODO" --type ts

# Search with context
rg "function.*export" -C 3
```

---

## Shell Functions

Add these to `~/.zshrc`. These are the ones that get used daily.

### Project Navigation (the `p` command)

```bash
# Fuzzy-search all projects, cd into selection
p() {
  local dir
  dir=$(find ~/Projects -maxdepth 2 -type d \
    -not -path '*/node_modules/*' \
    -not -path '*/.git/*' \
    -not -path '*/dist/*' \
    -not -path '*/.next/*' | fzf --height 40% --reverse)
  if [[ -n "$dir" ]]; then
    cd "$dir"
  fi
}
```

Type `p`, start typing a project name, arrow to select, Enter. Instant navigation.

### File Finder (the `f` command)

```bash
# Fuzzy-find a file with bat preview
f() {
  local file
  file=$(fzf --height 80% --preview 'bat --color=always --style=numbers --line-range :200 {}' --preview-window=right:60%)
  if [[ -n "$file" ]]; then
    echo "$file"
  fi
}
```

### Port Management

```bash
# Kill process on a port
killport() {
  local pid
  pid=$(lsof -ti :"$1")
  if [[ -n "$pid" ]]; then
    kill -9 "$pid"
    echo "Killed PID $pid on port $1"
  else
    echo "No process on port $1"
  fi
}

# Show all listening ports
alias ports="lsof -i -P -n | grep LISTEN"
```

### Project Scaffolding

```bash
# Create a new project with git + npm
mkproj() {
  mkdir -p ~/Projects/"$1" && cd ~/Projects/"$1"
  git init
  npm init -y
  echo "node_modules/\n.env\n.DS_Store" > .gitignore
  echo "Created project: $1"
}
```

### Node Modules Cleanup

```bash
# Show all node_modules and their sizes
nm-clean() {
  find "${1:-.}" -name "node_modules" -type d -prune | \
    xargs -I {} du -sh {} | sort -rh
}

# Delete all node_modules (careful!)
nm-nuke() {
  find "${1:-.}" -name "node_modules" -type d -prune -exec rm -rf {} +
  echo "All node_modules deleted"
}
```

### Quick Info

```bash
alias ip="curl -s ifconfig.me"
alias weather="curl -s wttr.in/?format=3"
alias path='echo $PATH | tr ":" "\n" | nl'
alias reload="source ~/.zshrc"
```

---

## Git Config

Add to `~/.gitconfig`:

```ini
[user]
  name = Your Name
  email = your-email@example.com

[core]
  editor = nano        # or code --wait, or vim
  pager = delta        # use delta for all git output

[interactive]
  diffFilter = delta --color-only

[delta]
  navigate = true       # use n/N to jump between diff sections
  side-by-side = true   # two-column diff view
  line-numbers = true   # show line numbers
  syntax-theme = Dracula

[merge]
  conflictstyle = diff3  # shows base + both sides in conflicts

[diff]
  colorMoved = default   # highlight moved code blocks

[init]
  defaultBranch = main

[push]
  autoSetupRemote = true  # auto-create remote branch on first push

[alias]
  s = status -sb                           # compact status
  lg = log --oneline --graph --decorate -20 # visual log
  lga = log --oneline --graph --all         # all branches
  today = log --since='6am' --oneline       # today's work
  week = log --since='1 week ago' --oneline # this week
  oops = commit --amend --no-edit           # fix last commit
  undo = reset --soft HEAD~1               # undo last commit (keep changes)
  branches = branch -a --sort=-committerdate # branches by recency
  cleanup = "!git branch --merged | grep -v '\\*\\|main\\|master' | xargs -n 1 git branch -d"
```

### Shell Aliases for Git

```bash
alias gs="git s"
alias gl="git lg"
alias gp="git push"
alias gpl="git pull"
alias gc="git commit"
alias gca="git commit -a"
alias gco="git checkout"
alias gb="git branches"
alias gd="git diff"
alias gds="git diff --staged"
```

---

## Windows Setup

The same productivity on Windows, using Windows Terminal + WSL2.

### Windows Terminal

Install from the Microsoft Store. It's the modern terminal for Windows — tabs, profiles, GPU-accelerated rendering.

### WSL2 (Windows Subsystem for Linux)

WSL2 gives you a full Linux environment inside Windows. All the tools above work identically.

```powershell
# In PowerShell (as admin):
wsl --install
# Restart, then set up Ubuntu
```

After WSL2 is running, everything from the Mac section applies:

```bash
# Inside WSL2:
sudo apt update && sudo apt upgrade -y

# Install Homebrew (yes, it works on Linux)
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

# Then follow the same steps:
# Oh My Zsh → Powerlevel10k → plugins → CLI tools → shell functions → git config
```

### Windows Terminal Profile

Set WSL2 as your default profile:

```json
{
  "defaultProfile": "{guid-of-wsl-profile}",
  "profiles": {
    "list": [
      {
        "name": "Ubuntu",
        "source": "Windows.Terminal.Wsl",
        "font": {
          "face": "JetBrains Mono Nerd Font",
          "size": 12
        },
        "opacity": 90,
        "useAcrylic": true,
        "colorScheme": "One Half Dark",
        "startingDirectory": "//wsl$/Ubuntu/home/youruser"
      }
    ]
  }
}
```

### Nerd Font on Windows

Download from [nerdfonts.com](https://www.nerdfonts.com/font-downloads):
1. Download "JetBrains Mono Nerd Font"
2. Extract the zip
3. Select all `.ttf` files → Right-click → "Install for all users"
4. Set the font in Windows Terminal profile settings

### Windows-Specific Tools

| Mac Tool | Windows/WSL Equivalent | Notes |
|----------|----------------------|-------|
| iTerm2 | Windows Terminal | Comes with Windows 11, installable on 10 |
| Homebrew | Homebrew (in WSL2) | Same package manager, works identically |
| `pbcopy` / `pbpaste` | `clip.exe` / `powershell.exe Get-Clipboard` | Clipboard from WSL |
| `open .` | `explorer.exe .` | Open directory in Explorer from WSL |
| Spotlight | PowerToys Run | `Alt+Space` to launch |

### WSL2 Clipboard Integration

```bash
# Add to ~/.zshrc in WSL2:
alias pbcopy="clip.exe"
alias pbpaste="powershell.exe -command 'Get-Clipboard' | tr -d '\r'"
```

Now `cat file.txt | pbcopy` works from WSL2 just like on Mac.

### SSH from Windows

Windows Terminal + WSL2 handles SSH natively. The same `~/.ssh/config` patterns from the Mac section work. For connecting to a Mac Mini from Windows:

```
Host mini
  HostName 100.x.y.z      # Tailscale IP
  User youruser
  ControlMaster auto
  ControlPersist 600
  ServerAliveInterval 60
```

---

## Complete ~/.zshrc Template

Here's the full config in order. Customize paths and project directory.

```bash
# Instant prompt (MUST be at the very top)
if [[ -r "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh" ]]; then
  source "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh"
fi

# Oh My Zsh
export ZSH="$HOME/.oh-my-zsh"
ZSH_THEME="powerlevel10k/powerlevel10k"
plugins=(git zsh-autosuggestions zsh-syntax-highlighting)
source $ZSH/oh-my-zsh.sh

# Powerlevel10k config
[[ ! -f ~/.p10k.zsh ]] || source ~/.p10k.zsh

# Tools
eval "$(fzf --zsh)"
eval "$(zoxide init zsh)"

# Aliases — files
alias ls="eza --icons"
alias ll="eza -la --icons"
alias lt="eza --tree --level=2 --icons"
alias cat="bat"
alias cd="z"

# Aliases — git
alias gs="git s"
alias gl="git lg"
alias gp="git push"
alias gpl="git pull"
alias gc="git commit"
alias gca="git commit -a"
alias gco="git checkout"
alias gb="git branches"
alias gd="git diff"
alias gds="git diff --staged"

# Aliases — utils
alias ports="lsof -i -P -n | grep LISTEN"
alias ip="curl -s ifconfig.me"
alias weather="curl -s wttr.in/?format=3"
alias path='echo $PATH | tr ":" "\n" | nl'
alias reload="source ~/.zshrc"

# Aliases — project dirs
alias proj="cd ~/Projects"

# Functions
p() {
  local dir
  dir=$(find ~/Projects -maxdepth 2 -type d \
    -not -path '*/node_modules/*' \
    -not -path '*/.git/*' \
    -not -path '*/dist/*' \
    -not -path '*/.next/*' | fzf --height 40% --reverse)
  [[ -n "$dir" ]] && cd "$dir"
}

f() {
  local file
  file=$(fzf --height 80% --preview 'bat --color=always --style=numbers --line-range :200 {}' --preview-window=right:60%)
  [[ -n "$file" ]] && echo "$file"
}

killport() {
  local pid=$(lsof -ti :"$1")
  [[ -n "$pid" ]] && kill -9 "$pid" && echo "Killed PID $pid on port $1" || echo "No process on port $1"
}

mkproj() {
  mkdir -p ~/Projects/"$1" && cd ~/Projects/"$1"
  git init && npm init -y
  echo "node_modules/\n.env\n.DS_Store" > .gitignore
  echo "Created project: $1"
}

nm-clean() {
  find "${1:-.}" -name "node_modules" -type d -prune | xargs -I {} du -sh {} | sort -rh
}

nm-nuke() {
  find "${1:-.}" -name "node_modules" -type d -prune -exec rm -rf {} +
  echo "All node_modules deleted"
}

# Node version manager
eval "$(fnm env --use-on-cd)"

# iTerm2 shell integration (Mac only)
[[ -f ~/.iterm2_shell_integration.zsh ]] && source ~/.iterm2_shell_integration.zsh
```

---

## Anti-Patterns

| Wrong | Right |
|-------|-------|
| Default Terminal.app with bash | iTerm2 with zsh + P10k |
| Stock `ls`, `cat`, `grep`, `find` | eza, bat, ripgrep, fd |
| `cd ~/Projects/client/dashboard/src` | `z dash` or `p` + fuzzy search |
| Plain `git diff` | Delta with side-by-side + Dracula theme |
| Manually finding ports to kill | `killport 3000` |
| No command history search | `Ctrl+R` with fzf fuzzy matching |
| Copy config from blog posts | Use the template above as a starting point |
| Install tools you never use | Every tool here earns daily usage |

Keyboard Shortcuts

Search in document⌘K
Focus search/
Previous file tab
Next file tab
Close overlayEsc
Show shortcuts?