This is my personal development environment that I use daily across different machines. Since all my development happens primarily in the terminal, this setup is very important to me - it's been evolving since 2004 to create an efficient, powerful command-line workflow.
I keep it here primarily to sync my configurations between my macOS and Fedora systems, but I'm sharing it publicly in case others find it useful for learning or inspiration.
It's an opinionated setup that works well for my terminal-centric workflow - your mileage may vary.
- What's Here
- Using This Setup
- Requirements
- Configuration Overview
- Keyboard Bindings
- My Utility Scripts
- Cross-Platform Support
- Package Lists
- Maintenance
- File Structure
- Common Issues I've Encountered
- Notes
- License
This setup includes the tools I use for my terminal-centric development workflow:
- Shell: Zsh with Zinit plugin manager - the foundation of terminal-based development
- Editor: Neovim configured with AstroNvim (OceanicNext theme) - powerful terminal-based editing
- Terminal Emulator: Ghostty with Monaco Nerd Font and iTerm2 Dark Background theme
- Terminal Multiplexer: tmux with Catppuccin Frappé theme - essential for managing multiple sessions
- AI Tools: Claude Code, GitHub Copilot (in Neovim), Gemini CLI, and Codex
- CLI Tools: Evolved alternatives that enhance terminal productivity (see CLI Tools Evolution)
- Scripts: Personal utilities for maintenance, backups, and health checks
- Package Lists: What I install on new systems to recreate this terminal environment
This is primarily my personal configuration, but if you want to explore or test it:
git clone --recursive https://github.com/ankurs/dotfiles.git ~/code/dotfiles
cd ~/code/dotfiles
./setup.shImportant: This is an opinionated setup that will change your shell configuration and install packages. I'd recommend reviewing the code first to see if it aligns with what you want on your system.
- Homebrew
- Xcode Command Line Tools
- DNF package manager
- Development tools group
- Git
- Zsh (will be set as default shell)
- tmux
- Neovim
- curl
- Single Config File: Consolidated dot-zshrc with optimized loading order
- Plugin Manager: Zinit with interactive installation
- Plugins: Oh My Zsh plugins for git, docker, kubectl, tmux, brew, and more
- Modern Aliases:
ls→eza(modern ls with icons)cat→bat(syntax-highlighted cat)grep→rg(ripgrep for fast searching)cd→zoxideintegration for smart directory jumping
- Tools: fzf integration for fuzzy finding files and history
- Performance: Lazy loading for NVM, RVM to speed up shell startup
- Cross-Platform: Automatic macOS/Fedora detection and PATH configuration
- Distribution: AstroNvim for out-of-the-box IDE experience
- Theme: OceanicNext colorscheme
- Package Manager: Lazy.nvim for plugin management
- LSP Manager: Mason for 56+ language servers, formatters, linters, and debuggers
- Languages: Go, Python, JavaScript/TypeScript, Rust, and more
- AI Completion: GitHub Copilot integration
- Plugin Manager: TPM (Tmux Plugin Manager)
- Theme: Catppuccin Frappé with clean, muted status bar
- Status Bar: Displays session info, load averages, CPU usage, battery status, and date/time
- Session Management: Automatic session save/restore every 15 minutes
- Prefix Key:
Ctrl+a(instead of defaultCtrl+b) - see Keyboard Bindings section for all shortcuts - Cross-Platform: Platform-aware clipboard integration
- Font: Monaco Nerd Font, size 12
- Theme: iTerm2 Dark Background
- Scrollback: 10 million lines - I never want to lose output
- Keybindings: Uses
Superkey to avoid conflicts with tmux'sCtrl+aprefix - Splits:
Cmd+d(horizontal),Cmd+Shift+d(vertical) for quick splitting outside of tmux - Shell Integration: Cursor, sudo, and title detection
I've been integrating AI tools into my terminal workflow as they've matured:
- Claude Code: My primary AI coding assistant, installed via brew cask. Configured with MCP servers for Go (gopls) and Svelte. Settings and plugins live in
claude/ - claude-code-templates: CLI tool for configuring and managing Claude Code templates
- GitHub Copilot: Integrated directly into Neovim for inline completions
- Gemini CLI & Codex: Installed via Homebrew for quick terminal access
- SSH-first: All GitHub URLs are rewritten from HTTPS to SSH automatically
- Default Branch:
main - Global Gitignore: Shared ignore rules across all repos
- Work Config: Conditional includes for work-specific settings when working with internal repos
Since all my development happens in the terminal, I've been curating command-line tools since 2004. This setup represents that evolution:
- most → Pager that replaced
less- better handling of long output and code files - bat → Syntax-highlighted
cat- essential for reading code files in terminal - eza → Modern
lswith icons - evolved throughls→exa→ezafor better file browsing - rg (ripgrep) → Fast recursive search - replaced
grepandackafter years of searching for speed - nvim → Modern vim - evolved from
vi→vim→neovimfor better plugin ecosystem - tmux → Terminal multiplexing - evolved from
screentotmuxfor session management - zoxide → Smart directory jumping - evolved from manual
cdto variouszimplementations
Personal Workflow Preferences:
- tmuxifier - session layout management for consistent project setups
- Custom
code()function - searches multiple directories (~/code/ss/,~/code/,~/code/jek/, etc.) to find a project and opens it in tmux. Usage:code project-name - Cross-platform clipboard - unified copy/paste commands across macOS and Linux
- todo.sh - terminal-based task management
Each tool represents finding better solutions as they became available, while maintaining the terminal-first workflow that's been central to my development process for 20+ years.
Here are the key bindings I use daily in this setup:
- Prefix Key:
Ctrl+a(instead of defaultCtrl+b) Ctrl+a+r- Reload configuration fileCtrl+a+?- Show all key bindings
Ctrl+a+|- Split window horizontally (left/right panes)Ctrl+a+-- Split window vertically (top/bottom panes)Ctrl+a+h- Move to pane on the leftCtrl+a+j- Move to pane belowCtrl+a+k- Move to pane aboveCtrl+a+l- Move to pane on the rightCtrl+a+Ctrl+a- Quick cycle through panes
Ctrl+a+c- Create new windowCtrl+a+n- Next windowCtrl+a+p- Previous windowCtrl+a+Ctrl+a- Switch to last active windowCtrl+a+&- Kill current window
Ctrl+a+Ctrl+s- Save session (tmux-resurrect)Ctrl+a+Ctrl+r- Restore session (tmux-resurrect)Ctrl+a+y- Synchronize input across all panes (ON)Ctrl+a+u- Turn off pane synchronization (OFF)
Ctrl+a+[- Enter copy modev- Begin selection (in copy mode)y- Copy selection to system clipboardEnter- Copy selection to system clipboardCtrl+v- Toggle rectangle/block selectionEscape- Exit copy mode
Ctrl+r- Reverse history search (incremental)Ctrl+l- Clear screen- Up/Down arrows - Navigate through history
- Vi-mode enabled - Use
Escthen vi commands for editing
Ctrl+t- fzf file finder (when fzf available)Alt+c- fzf directory navigator (when fzf available)z <partial_name>- Smart directory jumping with zoxide
tmux shortcuts (when tmux plugin loaded):
ta- tmux attach-sessionts- tmux new-sessiontl- tmux list-sessionstkss- tmux kill-sessiontksv- tmux kill-server
Git shortcuts (from OMZ git plugin):
gs- git statusga- git addgc- git commitgp- git pushgl- git pullgd- git diffgb- git branchgco- git checkout
Docker shortcuts (when docker command available):
dps- docker psdpa- docker ps -adi- docker images
Kubernetes shortcuts (when kubectl available):
k- kubectlkg- kubectl getkd- kubectl describe
- Leader:
\(backslash) - Local Leader:
,(comma)
<tab>- Switch between windows<Leader><Leader>- Switch to last buffert- File finder (FzfLua)<Leader>k- Search word under cursor<Leader>fg- Live grep]b/[b- Next/previous buffer
<Leader>tt- Run nearest test<Leader>tf- Run test file<Leader>ts- Test summary<Leader>to- Test output<Leader>tr- Run test<Leader>tS- Stop test
<Leader>cc- Toggle coverage<Leader>cs- Coverage summary<Leader>cl- Load coverage
<Leader>ca- Code action (in visual mode)
For standard AstroNvim keybindings (LSP, file explorer, diagnostics, etc.), see: AstroNvim Mappings Documentation
I've created a few scripts to help maintain this setup across my machines:
The main installation script. Handles everything from SSH key generation to package installation to symlinking dotfiles. It also supports an update mode (./setup.sh update) which updates the repo, submodules, all package managers, plugin managers, and language tools in one go.
My "did I set this up right?" script. It verifies essential commands (git, zsh, tmux, nvim), modern CLI tools (fzf, bat, eza, rg, zoxide), AI tools (claude, gemini, codex), symlink integrity, plugin managers (Zinit, TPM, AstroNvim), SSH keys, git config, and shell configuration loading. I run this after setting up a new machine to make sure nothing was missed.
Updates all the packages, plugins, and dependencies. I run this periodically to keep everything current - it handles brew/dnf, Zinit, TPM, Neovim plugins, Mason tools, npm globals, and cargo packages.
Creates compressed, timestamped backups to ~/.dotfiles-backup/. It backs up config files and directories (including SSH keys and cargo config), captures git state (status, diff, stash, recent commits), records installed packages, and generates a manifest. It automatically cleans up old backups, keeping the last 10.
An interactive menu-driven script I use after a fresh Fedora install. It detects whether I'm on a desktop, laptop, or VM, then lets me selectively install things like browsers, Docker, Kubernetes tools, power management, virtualization, and security hardening (fail2ban).
The dotfiles automatically detect the platform and adapt accordingly:
- Package Management: Uses brew on macOS, dnf on Fedora
- Clipboard: Platform-specific clipboard integration
- Tools: Installs appropriate versions for each platform
- Paths: Handles different binary locations across platforms
Organized package lists by category:
- Development Tools: Languages (Go, Rust, Python, Node.js), compilers, LSP tools
- CLI Utilities: Modern replacements (bat, eza, ripgrep, fzf, zoxide)
- DevOps & Cloud: Kubernetes, Docker, Terraform, AWS/GCP tools
- System Tools: Process management, networking, monitoring
./setup.sh update # Full update: repo, submodules, packages, plugins, language tools
./update.sh # Update packages, plugins, and dependencies
./check.sh # Verify setup health./backup.sh # Create timestamped backup- Add to appropriate package list (
Brewfileon macOS ordnf_liston Fedora) - Run
./update.shto install - Add configuration as needed
dot-zshrc: Unified shell configuration (Zsh with all settings)dot-tmux.conf: tmux configurationdot-ghostty: Ghostty terminal emulator configdot-mostrc:mostpager configurationdot-todo.cfg: todo.sh task management configdot-gitignore: Global git ignore rulesdotgitconfig: Git user config, SSH auth, URL rewrites
nvim/: Neovim configuration with AstroNvim, Mason, and all plugin configsclaude/: Claude Code settings, MCP server configs, and project instructionsfonts/: Powerline/Nerd fonts (git submodule)fedora/: Fedora-specific configs (fail2ban, btrbk backups, sysctl tuning, etc.)
setup.sh: Main installation script (also supports./setup.sh update)check.sh: Health check - verifies tools, symlinks, plugins, and configsupdate.sh: Update all packages, plugins, and dependenciesbackup.sh: Compressed timestamped backups with auto-cleanupfedora_post_setup.sh: Interactive post-install wizard for Fedora
Brewfile: macOS Homebrew Bundle file (taps, CLI packages, and GUI casks)dnf_list/dnf_remove_list: Fedora packages to install and removenpm_global_list: Global npm packages (neovim provider)snap_list: Snap packages for Fedoracargo-config: Rust Cargo configuration
A few things that have tripped me up when setting up on new machines:
Zinit not installing automatically
# Manual installation if needed
git clone https://github.com/zdharma-continuum/zinit.git ~/.local/share/zinit/zinit.gittmux plugins not loading
# Reset TPM if needed
git clone https://github.com/tmux-plugins/tpm ~/.tmux/plugins/tpm
# In tmux: Ctrl+a + I to install pluginsShell changes not taking effect
# Reload configuration
source ~/.zshrcThis repository serves as my personal configuration sync between machines and as a public reference for anyone curious about my setup. Feel free to browse through it, copy ideas, or use it as inspiration for your own dotfiles.
The configurations reflect my personal preferences and workflow - they might not work perfectly for everyone, but hopefully they're useful examples of how to set up a modern development environment.
MIT License - feel free to use any part of this configuration.