Modern macOS dotfiles for developers focused on Rust 🦀, Python 🐍, and data workflows. Optimized for MLOps and Data Science work.
- Quick Start
- What's Included
- Prerequisites
- Installation
- Configuration
- Fox's Toolbox
- File Structure
- Usage Tips
- Troubleshooting
- Acknowledgements
Tip
Preview the script before running: curl -LsSf https://bit.ly/42YwVdi | less
curl -L https://bit.ly/42YwVdi | sh- Terminal: Ghostty with zsh & Starship prompt
- Window Management: AeroSpace
- File Manager: Yazi
- Hotkeys: skhd
- Editor: Neovim with LazyVim
- Terminal Multiplexer: tmux
- Session Management: sesh
- Python: uv, pixi with Python 3.13
- Rust: Full toolchain with cargo
- Go: Latest stable version
- Node.js: Managed via n
- JavaScript/TypeScript: Bun toolkit
- Navigation: zoxide, fzf
- File Operations: eza, fd, ripgrep
- Git: lazygit, serie for rich git logs, gitlogue for cinematic commit replay, enhanced aliases
- AI: OpenCode, LLM, local models via Ollama
Important
Grant Full Disk Access to your terminal before installation: System Preferences → Privacy → Full Disk Access
- macOS (tested on recent versions)
- Stable internet connection for initial setup
The install script will:
- Install Xcode Command Line Tools
- Install Homebrew and all packages from Brewfile
- Set up Python, Node, and Bun environments
- Configure shell environment and dotfiles via GNU Stow
- Install additional tools and configurations
# Full installation
curl -L https://bit.ly/42YwVdi | sh
# Manual installation
git clone https://github.com/proteusiq/dotfiles ~/dotfiles
cd ~/dotfiles
./install.sh📜 Install Script Deep Dive
The install script is split into modular components for maintainability:
dotfiles/
├── install.sh # Main script (465 lines) - CLI, setup functions
└── scripts/
├── logging.sh # Logging, spinner, execute helpers
├── ui.sh # Table drawing, formatting
└── versions.sh # Version detection, --versions command
📋 Checking prerequisites
📁 Creating directories
🔨 Installing Xcode CLI
🍺 Installing Homebrew packages ← spinner animation
📦 Installing Node.js tools ← spinner animation
🐍 Creating Python virtual environments
💻 Installing tmux plugins
🎨 Installing Yazi themes
🔧 Installing CLI utilities
🔗 Linking dotfiles
🧹 Cleaning up
| Command | Description |
|---|---|
update |
Full installation (quiet mode) |
update <tool> |
Update a single tool (auto-detects package manager) |
update --outdated |
Show packages with available updates |
update --all |
Update all packages (brew, uv, cargo, git) |
update -v |
Verbose output with timestamps |
update -vv |
Debug mode (show all commands) |
update --dry-run |
Preview changes without executing |
update --versions |
Show installed tool versions |
update --versions brew |
Show specific group (brew|cask|uv|cargo|llm|git|other) |
update --info <tool> |
Show info about a specific tool |
update --list |
List available functions |
update --only <fn> |
Run only a specific function |
update --help |
Show help message |
Note: If
updatealias is unavailable, use~/dotfiles/install.shdirectly.
| Level | Flag | Output |
|---|---|---|
| Quiet | (default) | Section headers + spinner |
| Verbose | -v |
+ timestamps, status messages |
| Debug | -vv |
+ all executed commands |
| Function | Name | Description |
|---|---|---|
dirs |
create_dirs | Create ~/Codes and ~/Documents/Screenshots |
xcode |
install_xcode_tools | Install Xcode Command Line Tools |
brew |
install_brew | Install Homebrew and Brewfile packages |
node |
configure_node | Install n (Node version manager) and Bun |
venv |
create_virtualenvs | Create Python venvs (neovim, debugpy) |
tmux |
install_tmux_plugins | Install tmux plugin manager (tpm) |
yazi |
install_yazi_themes | Install Yazi file manager themes |
utils |
setup_utils | Install UV tools, LLM, Goose, gh-dash, etc. |
stow |
stow_dotfiles | Symlink dotfiles with GNU Stow |
cleanup |
cleanup | Run Homebrew cleanup and autoremove |
The script tracks versions before and after installation. Changes are always shown (even in quiet mode):
📊 Version Changes:
┌──────────────────┬────────────────┬────────────────┬──────────┐
│ Tool │ Previous │ Current │ Status │
├──────────────────┼────────────────┼────────────────┼──────────┤
│ bun │ 1.2.18 │ 1.2.19 │ Updated │
│ llm │ - │ 0.28 │ New │
│ tpm │ 99469c4 │ a1b2c3d │ Updated │
└──────────────────┴────────────────┴────────────────┴──────────┘
Check installed versions anytime:
update --versions # All tools
update --versions brew # Filter by group
update --info bat # Info about specific tool# Preview what would happen
update --dry-run
# Run only Homebrew installation
update --only brew
# Update just the utilities
update --only utils
# Full install with verbose output
update -v
# Update a single tool (auto-detects package manager)
update bat # brew formula
update zen # brew cask
update harlequin # uv tool
update repgrep # cargo
# Check tool versions and info
update --versions
update --info fzf| Variable | Default | Description |
|---|---|---|
DOTFILES_DIR |
$HOME/dotfiles |
Path to dotfiles directory |
LOG_FILE |
$HOME/macos-setup.log |
Path to installation log |
Update your Git configuration:
# Edit the global gitconfig
nvim ~/dotfiles/git/.gitconfig
# Or set directly
git config --global user.name "Your Name"
git config --global user.email "your.email@example.com"Note
After first installation, configure SSH for passwordless GitHub access.
# Generate SSH key (follow GitHub's guide)
ssh-keygen -t ed25519 -C "your.email@example.com"
gh auth login
gh ssh-key add ~/.ssh/id_ed25519.pub --type signing
# Switch to SSH remote
git remote set-url origin git@github.com:Proteusiq/dotfiles.gitNote
All tools use the Catppuccin Mocha theme for a consistent look.
Ghostty • Tmux • Neovim • fzf
Two built-in CLI/TUI tools to explore your shell aliases and installed packages:
aliases # Show all categories
aliases -s git # Show git aliases
aliases -d ga # Describe 'ga' alias
aliases --tui # Interactive TUI browserCategories: git files nav term pkg sys gnu fn
tools # Show all categories
tools -s cli # Show modern CLI tools
tools -d lazygit # Describe lazygit with examples
tools --tui # Interactive TUI browserCategories: shell edit cli files vc data dev infra lang ai gnu media apps wm sys
Tip
Both tools support --tui for interactive browsing with cross-category search (/), vim navigation (j/k), and instant filtering. Each tool in Fox's Den shows practical "aha!" examples.
dotfiles/
├── aerospace/ # Window management config
├── bin/ # Custom scripts (aliases, tools)
├── fzf/ # Fuzzy finder config
├── ghostty/ # Terminal emulator config
├── git/ # Git configuration
├── nvim/ # Neovim configuration
├── scripts/ # Install script modules
│ ├── logging.sh # Logging, spinner, helpers
│ ├── ui.sh # Table drawing
│ └── versions.sh # Version detection
├── sesh/ # Session manager config
├── starship/ # Shell prompt config
├── tmux/ # Terminal multiplexer config
├── yazi/ # File manager config
├── zsh/ # Shell configuration
│ ├── .aliases # Command aliases
│ ├── .exports # Environment variables
│ ├── .zlogin.sh # Login shell config
│ ├── .zshenv.sh # Environment setup
│ └── .zshrc # Main zsh config
├── Brewfile # Homebrew packages
└── install.sh # Main setup script
- Shell Environment: Antigen for zsh plugin management
- Package Management: Brewfile contains all Homebrew packages, casks, and Mac App Store apps
- Language Setup: uv for Python, n for Node.js, Bun for TypeScript/JavaScript
🖥️ Tmux Session Management
Key Bindings (leader = Ctrl-b):
<leader> + I # Install plugins
<leader> + c # New session
<leader> + n # Next session
<leader> + " # Horizontal split
<leader> + % # Vertical split
<leader> + hjkl # Navigate panes
<leader> + z # Zoom/unzoom pane
<leader> + p # Popup terminal
<leader> + O # Popup session switcher
# Aliases
iexit # Kill current session
ikill # Kill all sessions
iswitch # Interactive session switcherMore extras? tmux's cheatsheet and man wiki
⚡ Neovim/LazyVim - Complete Plugin Guide
This configuration includes 23 powerful plugins organized by category. Below is the complete reference guide with keybindings, purposes, and practical examples.
Extras are managed in nvim/.config/nvim/lua/plugins/extras.lua. To add/remove extras, edit this file:
-- nvim/.config/nvim/lua/plugins/extras.lua
return {
{ import = "lazyvim.plugins.extras.coding.yanky" },
{ import = "lazyvim.plugins.extras.dap.core" },
-- ... add or remove lines here
}Currently enabled extras:
| Extra | Purpose | Key Features |
|---|---|---|
coding.yanky |
Enhanced yank/paste | Yank history, paste cycling |
dap.core |
Debug Adapter Protocol | Breakpoints, stepping, REPL |
editor.leap |
Fast motion | s/S to jump anywhere |
editor.neo-tree |
File explorer | <leader>e sidebar |
lang.python |
Python support | LSP, formatting, debugging |
lang.rust |
Rust support | rust-analyzer, cargo integration |
test.core |
Test runner | <leader>tt run nearest test |
ui.mini-animate |
Smooth animations | Cursor, scroll, window animations |
util.dot |
Dotfile syntax | Highlighting for config files |
util.gh |
GitHub CLI | gh command integration |
util.gitui |
GitUI integration | Alternative git TUI |
util.octo |
GitHub in Neovim | Issues, PRs, code review |
Test keymaps from test.core:
| Keymap | Action |
|---|---|
<leader>tt |
Run nearest test |
<leader>tT |
Run current file tests |
<leader>tr |
Run last test |
<leader>ts |
Toggle test summary |
<leader>to |
Show test output |
<leader>tO |
Toggle output panel |
<leader>tS |
Stop tests |
To add more extras, browse available options with :LazyExtras in Neovim, then add the import line to extras.lua. After saving, restart Neovim and run :Lazy sync.
| Plugin | Purpose | Keymap | Notes |
|---|---|---|---|
| Snacks | Find files | <leader><leader> |
Find files (like <leader>ff) |
| Search & Replace | <leader>sr |
BROKEN - needs fix | |
| Telescope | Fuzzy file finder | <leader>ff |
Find files project-wide |
| Live grep search | <leader>fg |
Search file contents | |
| Buffer list | <leader>fb |
Quick buffer switcher | |
| Help tags | <leader>fh |
Documentation search | |
| Harpoon | Add bookmark | <leader>a |
Mark current file for quick access |
| View bookmarks | <C-e> |
Toggle harpoon menu (Telescope) | |
| Jump to file 1-4 | <C-h>/<C-t>/<C-n>/<C-s> |
Direct jump to bookmarked file | |
| Next/prev file | <C-S-P>/<C-S-N> |
Cycle through bookmarks | |
| Yazi | Open file manager | <leader>- |
Browse files in current directory |
| Open in cwd | <leader>cw |
Browse from working directory |
| Plugin | Purpose | Keymap | Notes |
|---|---|---|---|
| Navbuddy | Open code navigator | <leader>nv |
LSP-powered symbol tree browser |
| Navigate structure | k/i/j/l |
Previous/next/parent/children | |
| Atone | Open undo history | :Atone |
Visualize and navigate undo history |
| Plugin | Purpose | Keymap | Notes |
|---|---|---|---|
| Surround | Add surrounding | ys<motion><char> |
Example: ysiw" wraps word in quotes |
| Change surrounding | cs<old><new> |
Example: cs"' changes "text" to 'text' |
|
| Delete surrounding | ds<char> |
Example: ds" removes quotes |
|
| Better Escape | Fast escape | jk or jj |
Alternative to <Esc> (customizable) |
| Live Command | Preview commands | :s/foo/bar/ |
Real-time preview while typing |
| Plugin | Purpose | Keymap | Notes |
|---|---|---|---|
| Snacks | Open Lazygit | <leader>gg |
Full Git UI in Neovim |
| File history | <leader>gf |
Lazygit history for current file | |
| Git log | <leader>gl |
Lazygit log for working directory | |
| Blame line | <leader>gb |
Show who changed this line | |
| Browse on GitHub | <leader>gB |
Open file on GitHub | |
| Octo | List issues | <space>il |
GitHub issues on current repo |
| Close/reopen | <space>ic/<space>io |
Issue state management | |
| Checkout PR | <space>po |
Checkout a pull request | |
| Merge PR | <space>pm |
Merge commit the PR | |
| PR diff | <space>pd |
View PR changes | |
| Add reviewer | <space>va |
Request PR review | |
| Start review | <space>vs |
Start/submit code review | |
| Add comment | <space>ca |
Comment on PR/issue | |
| Add label | <space>la |
Label issue/PR | |
| Add assignee | <space>aa |
Assign to user | |
| Open in browser | <C-b> |
Open PR/issue on GitHub.com | |
| Reactions | <space>r+ <space>rh |
Add 👍 ❤️ 👎 reactions | |
| Git Conflict | Resolve conflicts | Auto-triggered | Tools appear on merge conflicts |
| Plugin | Purpose | Keymap | Notes |
|---|---|---|---|
| DAP Python | Debug test method | <leader>dm |
Step through test methods |
| Debug test class | <leader>dc |
Debug entire test class | |
| Debug file | <leader>df |
Debug current Python file | |
| Debug function | <leader>du |
Debug function under cursor | |
| Debug class | <leader>dk |
Debug class under cursor | |
| Rustaceanvim | Code action | <leader>cR |
Rust LSP code actions |
| Debuggables | <leader>dr |
List Rust debug targets |
| Plugin | Purpose | Keymap | Notes |
|---|---|---|---|
| OpenCode | Ask about code | <leader>oa |
Ask with @this context |
| Select prompt | <leader>os |
Choose predefined prompt | |
| Add context | <leader>o+ |
Add @this to context |
|
| Toggle panel | <leader>ot |
Show/hide OpenCode panel | |
| Select command | <leader>oc |
Pick from available commands | |
| New session | <leader>on |
Start fresh AI session | |
| Interrupt | <leader>oi |
Stop current operation | |
| Cycle agent | <leader>oA |
Switch between agents | |
| Scroll messages | <S-C-u>/<S-C-d> |
Half-page scroll in messages |
| Plugin | Purpose | Keymap | Notes |
|---|---|---|---|
| Snacks | Scratch buffer | <leader>. |
Quick temporary buffer |
| Delete buffer | <leader>bd |
Close current buffer | |
| Rename file | <leader>cR |
Rename with preview | |
| Floating terminal | <C-/> |
Toggle terminal overlay |
| Feature | Keymap | Purpose |
|---|---|---|
| Spelling | <leader>us |
Toggle spell check |
| Wrapping | <leader>uw |
Toggle line wrapping |
| Relative numbers | <leader>uL |
Toggle relative line numbers |
| Diagnostics | <leader>ud |
Show/hide LSP diagnostics |
| Line numbers | <leader>ul |
Toggle line number display |
| Treesitter | <leader>uT |
Toggle syntax highlighting |
| Background | <leader>ub |
Toggle dark/light mode |
| Inlay hints | <leader>uh |
Toggle LSP inlay hints |
| Plugin | Purpose | Keymap | Notes |
|---|---|---|---|
| Snacks | Next reference | ]] |
Jump to next symbol reference |
| Prev reference | [[ |
Jump to previous reference | |
| Notification history | <leader>n |
Show notification history | |
| Neovim news | <leader>N |
View Neovim news & updates |
| Command | Purpose | Example |
|---|---|---|
:!<command> |
Execute shell | :!ls -al |
:'<,'>!sort |
Sort selection | Select lines, then run |
:'<,'>!jq |
Format JSON | Pretty-print JSON selection |
:r !<command> |
Insert output | :r !date inserts current date |
:Telescope keymap |
Show keymaps | Searchable keymap reference |
:Telescope live_grep |
Search project | Live grep across files |
:Telescope git_branches |
Git branches | Interactive branch switcher |
| Prefix | Purpose | Examples |
|---|---|---|
<leader>f |
Find/Fuzzy | ff files, fg grep, fb buffers |
<leader>g |
Git | gg lazygit, gb blame, gf history |
<leader>o |
OpenCode (AI) | oa ask, os select, on session |
<space> |
Octo (GitHub) | il issues, po checkout PR, pm merge |
<leader>u |
UI Toggles | us spell, uw wrap, ud diagnostics |
<leader>d |
Debug | dm method, dc class, df file |
<leader>. |
Scratch | . toggle, bd delete, S select |
<leader>n |
Navigate | nv navbuddy, n notifications |
<leader>- |
Files | - current, cw working directory |
<Space> # Leader key
<Ctrl-w>w # Switch to file tree
[b ]b # Navigate buffers (Alt+8/9)
<Ctrl-h/j/k/l> # Navigate windows- @this context: Use
<leader>oawith@thisto ask OpenCode about your current code - Fuzzy matching: Telescope uses fuzzy search - type partial names and it finds matches
- Git workflow:
<leader>ggopens Lazygit for complex operations,<space>ilfor issues - File history: If you're disciplined with commits,
<leader>Gh(:Telescope git_file_history) is your best friend for tracking how a file evolved over time - Quick edits: Surround plugin (
ys,cs,ds) makes text transformation fast and repeatable - Markdown:
.nvim/README.mdand other markdown files render beautifully inline
🧘 Vim Grammar Reference
Vim follows Verb + Noun grammar for powerful text editing:
Verbs (Actions):
d- deletec- change (delete + insert mode)y- yank (copy)
Nouns (Motions):
w/b- word forward/backwardgg/G- top/bottom of file{/}- paragraph navigation
Text Objects (preferred for repeatability):
iw/aw- inner/around wordi"/a"- inner/around quotesi(/a(- inner/around parentheses
Examples:
diw- delete inner wordci"- change inside quotesyap- yank around paragraph
Pro tip: Text objects work regardless of cursor position and support the . repeat command.
💡 Pragmatic Goodies & Guides
One of the most powerful features in this setup is the ability to see how a file has changed throughout your git history. This is incredibly useful for:
- Understanding the evolution of code changes
- Tracking when bugs were introduced
- Learning from your own past edits
- Reviewing refactoring decisions
Keymap: <leader>Gh or :Telescope git_file_history
How to Use:
- Open any file in your project
- Press
<leader>Gh(or run:Telescope git_file_history) to open the git file history picker - Browse through all commits that touched this file
- Select a commit to view how the file looked at that point in time
- Use Telescope's navigation keys to explore previous versions side-by-side with diffs
Example Workflow:
<leader>Gh " Open history for current file
" Browse commits with j/k, preview with ?
" Press <CR> to view the selected commit version
" Use Telescope's diff view to see what changedThis integration combines Telescope's powerful fuzzy finding with git-file-history extension to give you instant access to temporal navigation of your codebase.
Change editor's appearance instantly without leaving Neovim. Perfect for:
- Finding the right theme for different times of day (dark mode at night, light mode during day)
- Testing how code looks in different color schemes
- Matching your editor theme to your mood or lighting conditions
- Discovering new themes and comparing them instantly
Keymap: <leader>uC
How to Use:
- Press
<leader>uCto open the colorscheme picker - Type to filter available themes (supports fuzzy search)
- Use
j/kor arrow keys to navigate through themes - Press
<CR>to apply the selected theme immediately - Press
?in the picker to see all available actions
Example Workflow:
<leader>uC " Open colorscheme picker
tokyonight " Type to filter (fuzzy search)
<CR> " Apply selected theme instantlyAll installed colorschemes are available with live preview as you browse!
Efficient multi-cursor editing directly in Neovim. Perfect for:
- Simultaneous editing across multiple locations
- Fast refactoring and bulk text operations
- Reducing repetitive edits on similar patterns
- Maintaining productivity without leaving the editor
Keymaps: Arrow keys to add cursors, <leader>n/N to match word/selection
How to Use:
- Position cursor on target word/selection
- Press
<up>/<down>to add cursor above/below current line - Or press
<leader>nto add cursor at next match of word under cursor - Edit normally - changes apply to all cursor locations simultaneously
- Press
<Esc>to clear all cursors
Example Workflow:
<down> " Add cursor below current line
<down> " Add another cursor below
i " Enter insert mode
new_text " Type - applies to all cursor positions
<Esc> " Exit and clear cursors
" Or match-based:
<leader>n " Add cursor at next match of word
<leader>n " Add another cursor at next matchPro Tips:
- All cursors are bufwin-local - they persist when switching between windows with the same buffer
- Use
<leader><up>/<down>to skip a line when adding cursors - Use
<leader>Nto match previous occurrence (backwards) - Use
<C-q>to toggle (disable/enable) cursors - Use
<left>/<right>to select different cursor as main (when multiple cursors active) - Use
<leader>xto delete the main cursor
Use cases: Variable renaming across file, bulk find-and-replace, consistent formatting updates, batch code modifications
Command-line tools for various tasks. Here are quick how-tos for the essential ones:
View and analyze log files with an interactive terminal UI. Perfect for debugging and monitoring logs from multiple sources.
lnav /var/log/system.log # View a specific log file
lnav # Interactive log file picker
# Inside lnav: Use j/k to navigate, / to search, q to quitUse cases: Debug application errors, monitor system logs, analyze multiple log files side-by-side
Interact with Git repositories through an intuitive terminal UI. Also accessible in Neovim via <leader>gg.
lazygit # Open Git UI in current repo
# Inside: Stage files, commit, branch management with vim-like keybindsUse cases: Visual staging, interactive rebasing, branch management, blame view
View a beautiful, rich git commit graph in your terminal with image rendering support.
serie # Open git commit graph in current repo
serie --order topo # View commits topologically sorted
serie --order chrono # View commits chronologically (default)
serie --preload # Preload all graph images for smoother scrolling
# Inside: j/k navigate, Enter to show details, ? for help, / to searchUse cases: Visualizing commit history, understanding branch structure, exploring complex git workflows
A cinematic Git commit replay tool that turns your Git history into a living, animated story with realistic typing animations and syntax highlighting.
gitlogue # Start cinematic screensaver mode
gitlogue --commit HEAD~5..HEAD # Replay a range of commits
gitlogue --commit abc123 --loop # Loop a specific commit
gitlogue --author "john" # Filter commits by author
gitlogue --theme dracula # Use a different theme
gitlogue --speed 20 # Adjust typing speed (ms per char)
gitlogue theme list # List available themesUse cases: Screensaver, presentations, content creation, education, visualizing code evolution
Interactive GitHub CLI dashboard for viewing pull requests, issues, and more directly from your terminal.
gh-dash # Open GitHub dashboard
# Inside: View PRs, issues, repos with vim-like navigationUse cases: Quick PR review, issue tracking, repository status overview, GitHub activity monitoring
Manage Docker containers, images, and networks with an interactive TUI.
lazydocker # Open Docker UI
# Inside: View containers, logs, exec commands with vim-like navigationUse cases: Container debugging, quick logs viewing, resource monitoring, container lifecycle management
Run and test SQL queries interactively with connection management and results formatting.
harlequin # Open SQL IDE
harlequin --dialect duckdb # Specify SQL dialect (duckdb, sqlite, postgres, etc.)
# Inside: Write queries, view results, explore databasesUse cases: SQL development, database exploration, query testing, data analysis
View and query CSV, Parquet, JSON, Arrow, and Excel files with SQL support and vim-style keybindings.
tw data.csv # Open CSV file
tw data.parquet # Open Parquet file
tw *.csv # Open multiple files as tabs
curl -s "url/data.csv" | tw # Pipe data from curl
# Inside: Use SQL with :Q SELECT * FROM df WHERE col > 100Use cases: Data exploration, quick CSV/Parquet viewing, SQL queries on files, data analysis
glow renders markdown beautifully in the terminal. dawn is a distraction-free markdown editor with live preview.
# glow - Read/view markdown
glow README.md # Render markdown with styling
glow -p README.md # Pager mode (scrollable)
glow -w 80 README.md # Set width
glow . # Browse markdown files in directory
# dawn - Write markdown
dawn # Open editor
dawn notes.md # Edit specific file
# Inside: Split-pane with editor on left, live preview on rightUse cases: Reading docs in terminal, writing notes, distraction-free writing, markdown preview
Measure and compare command execution time with statistical analysis.
hyperfine 'command1' 'command2' # Compare two commands
hyperfine --runs 10 'your_command' # Run benchmark 10 times
hyperfine --show-output 'cmd' # Show command output while benchmarkingUse cases: Performance comparison, optimization validation, CI/CD benchmarking
Execute commands when files change. Auto-run tests, rebuild projects, restart servers.
watchexec -e py -- pytest # Run tests on .py changes
watchexec -e rs -- cargo build # Rebuild on Rust file changes
watchexec --restart -- python server.py # Restart server on changes
watchexec -w src -w tests -- make # Watch multiple directories
watchexec -c -e js,ts -- npm test # Clear screen, watch js/tsUse cases: Auto-testing, live reload, build automation, development workflow
Human-friendly HTTP CLI client (better than curl).
http GET example.com # Simple GET request
http --auth user:pass POST httpbin.org/post name=value # POST with auth
http --headers GET github.com # Show only headers
http < request.json POST httpbin.org/post # Send from fileUse cases: API testing, REST debugging, quick HTTP requests, webhook testing
Run Linux virtual machines natively on macOS. Lighter than Docker Desktop, uses Apple's Virtualization.framework.
limactl start # Start default Ubuntu VM
limactl start --name=arch archlinux # Start Arch Linux VM
lima # Open shell in default VM
lima nerdctl run -it alpine # Run containers (like docker)
lima nerdctl compose up # Docker Compose equivalent
limactl list # List VMs
limactl stop default # Stop VMWhy lima over Docker Desktop:
- Native Apple virtualization (fast, low overhead)
- Automatic file sharing and port forwarding
- No Docker Desktop license needed
nerdctlis Docker-compatible CLI
Use cases: Running Linux tools, container development, testing Linux-specific code, Docker alternative
Interactive terminal UI for find-and-replace operations with preview, regex support, and editor integration.
scooter # Open scooter in current directory
scooter ../path/to/dir # Search in specific directory
echo "text" | scooter # Process stdin
scooter --search-text "old" --replace-text "new" --immediate-search # Pre-populate fieldsKey features:
- Interactive toggling: Select which instances to replace using spacebar
- Regex & fixed strings: Switch between regex patterns and literal string matching
- Capture groups: Use
(\d)in search and$1in replacement - Editor integration: Press
eto open selected file at the correct line in your$EDITOR - Respects .gitignore: Automatically ignores files per your
.gitignoreand.ignore - Glob filtering: Include/exclude files using glob patterns (e.g.,
*.rs,*.py) - Performance: Built on ripgrep's file walker for blazing-fast searches
Workflow example:
scooter " Open scooter
# Type search pattern, replacement, and toggle desired instances with space
# Press Enter to execute replacements
# Press e to open any file in your editor at that lineUse cases: Refactoring code, bulk renaming, updating imports, batch text replacements
🐱 Shortcat - Keyboard-Driven UI Navigation
Navigate macOS applications entirely with your keyboard using Shortcat. Perfect for:
- Clicking buttons, links, and UI elements without a mouse
- Speeding up repetitive GUI tasks
- Accessibility and RSI prevention
- Vim-like navigation in any application
Key Binding:
| Shortcut | Description |
|---|---|
Cmd + S |
Activate Shortcat search mode |
How to Use:
- Press
Cmd + Sto activate Shortcat - Type to filter visible UI elements (buttons, links, menus)
- Press
Enterto click the highlighted element - Use arrow keys to navigate between matches
🔍 CLI Commands Reference
A curated collection of useful CLI commands for macOS, organized by when you need them.
Can't start your server? Something's already using the port.
lsof -i tcp:3000 # Find what's hogging the port
kill -9 <pid> # Kill it
# Or one-liner: find and kill
lsof -ti tcp:3000 | xargs kill -9What is this process doing? Where is it running from?
lsof -p <pid> | grep cwd # Working directory of a process
lsof -i -nP # All network connections (debug connectivity)
ps aux | grep <name> # Find process by nameJust typed a long command and forgot sudo? Use
sudo !!
sudo !! # Run last command with sudo
!! # Repeat last command
!$ # Reuse last argument: mv file.txt !$
^typo^fixed # Fix typo in last command
cd !$:h # cd to directory of last file argument
until !!; do :; done # Retry flaky command until it worksCan't remember the exact filename? Fuzzy find it.
nvim **<TAB> # Fuzzy find files to edit
cd **<TAB> # Fuzzy find directories to jump to
kill -9 **<TAB> # Fuzzy find process to kill
ssh **<TAB> # Fuzzy find SSH hosts
<Ctrl-r> # Search command history| Key | When to Use |
|---|---|
Ctrl+C |
Stop runaway process |
Ctrl+Z |
Pause to do something else, resume with fg |
Ctrl+L |
Clear clutter, keep scrollback |
Ctrl+R |
"What was that command I ran last week?" |
Ctrl+A/E |
Jump to fix start/end of long command |
Ctrl+U |
Clear line and start over |
Ctrl+W |
Delete last word (fix typo faster) |
Ctrl+X Ctrl+E |
Command too complex? Edit in your editor |
Schedule tasks or set reminders without leaving the terminal.
echo "backup.sh" | at midnight # Schedule one-time task
leave +15 # Terminal reminder in 15 min
timeout 30s ./slow-script # Kill if takes too long
watch -n 5 "kubectl get pods" # Monitor every 5 secondsThe power of Unix: chain commands together. Use
<()to treat command output as a file.
# Classic pipes: output -> input
cat file | grep error | wc -l
# Process substitution: treat command output as a file
diff <(ls dir1) <(ls dir2) # Compare directory contents
comm -13 <(sort file1) <(sort file2) # Lines only in file2
vimdiff <(curl -s url1) <(curl -s url2) # Diff two URLs
paste <(cut -f1 data.tsv) <(cut -f3 data.tsv) # Combine columns
# Here-string: pass string as stdin (no echo pipe needed)
bc <<< "2^10" # Quick math: 1024
grep "error" <<< "$log_output" # Search in variableFind large files, remove empty directories, clean up the mess.
# Find files
grep -lir "TODO" . # Which files contain "TODO"?
find . -size +100M # Files over 100MB
find . -mtime +30 -delete # Delete files older than 30 days
find . -type d -empty -delete # Remove empty directories
# Quick operations
cp file{,.bak} # Backup: file -> file.bak
chmod $(stat -f%A src) dest # Copy permissions from another file
touch ./-i # Create "-i" file: blocks accidental rm -rf *Rename 100 files from
IMG_001.JPGtovacation_001.jpgin one command.
# Pure bash: lowercase + spaces to underscores
for f in *; do
mv "$f" "$(echo "$f" | tr '[:upper:]' '[:lower:]' | tr ' ' '_')"
done
# Perl rename (brew install rename) - more powerful
rename 's/IMG_/vacation_/' *.JPG # Prefix replacement
rename 'y/A-Z/a-z/' * # Lowercase all
rename 's/\.jpeg$/.jpg/i' * # Normalize extensionsParse logs, format data, count occurrences.
less +F app.log # Follow log (better than tail -f, can scroll)
tac file.txt # Reverse lines (last first)
column -s, -t data.csv # Pretty-print CSV as table
sort file | uniq -c | sort -rn # Count occurrences, most frequent first
curl -s "$url" | jq . # Pretty-print JSON (or python3 -m json.tool)Watch logs with timestamps and color-coded severity levels.
# Add timestamps to any output
tail -f app.log | while read line; do echo "$(date +%T) $line"; done
# Color-coded by severity (ERROR=red, WARN=yellow, rest=green)
tail -f app.log | awk '{
ts = strftime("%T")
if ($0 ~ /ERROR/) color="\033[31m"
else if ($0 ~ /WARN/) color="\033[33m"
else color="\033[32m"
printf "\033[90m%s\033[0m %s%s\033[0m\n", ts, color, $0
}'Create encrypted backups. Will prompt for password.
# Create encrypted archive (will prompt for password)
tar czf - secret_folder | openssl enc -e -aes256 -pbkdf2 -out backup.enc
# Decrypt and extract
openssl enc -d -aes256 -pbkdf2 -in backup.enc | tar xzf -Stage smartly, clean up deleted files, find contributors.
git add -u # Stage only modified/deleted (not new files)
git rm $(git ls-files --deleted) # Remove all deleted files from git
git log --format='%aN' | sort -u # Who contributed to this repo?
git diff --name-only main # What files changed vs main?Is it your network or the server? Test connectivity and ports.
curl ifconfig.me # What's my public IP?
curl 'wttr.in/copenhagen' # Quick weather check
nc -zv host 443 # Test if port is open
ssh-copy-id user@host # Setup passwordless SSH
# Download stuff
wget -mkEpnp example.com # Mirror entire website
wget --accept pdf -rl1 url # Download only PDFs from pageKeep jobs running after you disconnect from SSH.
disown -a && exit # Exit shell, keep background jobs running
nohup ./long-job.sh & # Run immune to hangups
sudo -K # Clear sudo password (security habit)Alias getting in the way? Bypass it with
\orcommand.
\ls # Run real ls, ignore alias
command ls # Same thing, more explicit
type ls # See what ls actually runs
some_command | : # Discard output (faster than >/dev/null)Script not working? Debug with
-xor analyze withshellcheck.
bash -x script.sh # Print each command as it runs
set -euo pipefail # Strict mode: fail on errors
shellcheck script.sh # Static analysis for bugsbc <<< 'scale=2; 100/3' # Division with decimals: 33.33
bc <<< 'obase=16; 255' # Decimal to hex: FF
bc <<< 'obase=2; 42' # Decimal to binary: 101010
printf '%d\n' 0xFF # Hex to decimal: 255Run shell commands and insert output without leaving vim.
:r !date " Insert current date
:r !curl -s api.example.com " Insert API response
:%!jq . " Format entire buffer as JSON
:x " Save and quit (shorter than :wq)Running sensitive commands? Disable history for this session.
unset HISTFILE # Don't save commands this session
read -s p; echo $p | md5 | base64 | cut -c-16 # Generate password from phraseMultiple ways to get help, from official docs to community cheatsheets.
man <command> # Official manual
tldr <command> # Community examples (brew install tlrc)
curl cheat.sh/tar # Cheatsheet from web
apropos "search term" # Search all man pagesKeep macOS tools updated and clean up old versions.
brew update && brew upgrade # Update everything
brew cleanup --prune=all # Remove old versions, free space
brew doctor # Diagnose issuesImpress coworkers or pretend to be hacking in a movie.
ASCII Clock - Looks cool on a spare monitor
while true; do clear; date +%T | figlet; sleep 1; doneMatrix Effect - The classic
printf '\033[32m'; while :; do
for i in {1..16}; do
(( RANDOM % 5 == 1 )) && printf '%d ' $((RANDOM%2)) || printf ' '
done; echo
donePretend to be busy - When the boss walks by
cat /dev/urandom | hexdump -C | grep "ca fe"Some commands require Homebrew packages:
figlet,rename,wget,jq
Warning
Running into issues? Check these common problems first.
| Problem | Solution |
|---|---|
| Homebrew installation fails | Ensure Xcode Command Line Tools are installed first |
| Stow conflicts | Remove existing dotfiles before running stow |
| Permission errors | Grant Full Disk Access to your terminal |
| Python/Node issues | Check that uv and n are properly installed |
| Terminal theme issues | Restart terminal after font installation |
Tip
Run ./install.sh --verbose for detailed debugging output, or check ~/macos-setup.log for error details.
Useful resources:
- cheat.sh -
curl https://cheat.sh/<command> - Command reference:
tldr <command>(install withbrew install tlrc) - Vim help:
:help <topic>or:Telescope help_tags
Inspired by Sara Pope's dotfiles and the broader dotfiles community.
A fork focused on modern development workflows with Rust, Python, and AI tooling.

