Personal shell configuration files and environment settings for macOS/Linux development environments.
This repository contains my personal dotfiles including shell configurations (bash/zsh), terminal multiplexer settings (tmux), and various development environment configurations. The setup is optimized for software development with features like git-aware prompts, modern shell options, and convenient aliases.
- Bash: Enhanced history, safety aliases, git-aware prompt, OS-specific configurations
- Zsh: Modern shell options, auto-completion, directory navigation shortcuts, git integration
- Cross-platform: Works on macOS, Linux, and Cygwin
- Tmux: Custom key bindings, enhanced status bar, optimized for development workflows
- Git completion and branch information in prompts
- Docker shortcuts and utilities
- Node.js (nvm), Ruby (rvm), Rust, Python (virtualenv) support
- Google Cloud SDK integration
- Kubernetes (kubectl) completion
- Git
- GNU Stow
- tmux 3.2 or newer (the config uses
terminal-featuresandextended-keys) - On Linux, a clipboard tool for tmux-yank:
xclip,xsel, orwl-copy(fromwl-clipboard) on Wayland. macOS haspbcopybuilt in.
macOS:
brew install stowLinux (Ubuntu/Debian):
sudo apt-get install stowLinux (CentOS/RHEL):
sudo yum install stow- Clone the repository:
git clone https://github.com/yourusername/dotfiles.git ~/dotfiles
cd ~/dotfiles- Create symlinks using GNU Stow:
make link- Install the tmux plugins (tpm, catppuccin, tmux-yank):
make tmux-pluginsEach plugin is checked out at the commit pinned in scripts/tmux-plugins.txt.
Rerun it after changing a pin. Skip it and tmux still starts, but with the
default status bar and no clipboard integration.
- Reload your shell:
# For bash
source ~/.bashrc
# For zsh
source ~/.zshrc# Create symlinks manually
stow --target=$HOME .If make link refuses because files already exist in $HOME, move them aside
to <name>.bak and link in one step:
make force-linkIt never overwrites: if a .bak already exists it stops without changing
anything, and if stow still fails it undoes the renames.
To pull your existing $HOME copies into this repo, overwriting the tracked
versions (review with git diff afterwards):
make adopt| File | Purpose |
|---|---|
.bashrc |
Bash shell configuration, aliases, and functions |
.zshrc |
Zsh shell configuration with modern features |
.zshenv |
Zsh, every invocation; dedupes PATH and sources .profile |
.bash_profile |
Bash login shell; sources .profile then .bashrc |
.tmux.conf |
Tmux terminal multiplexer configuration |
.gitignore |
Files to ignore in this repository |
.profile |
POSIX base: PATH, EDITOR/VISUAL and exported env, shared by sh, bash and zsh |
.stow-local-ignore |
Files for Stow to ignore when symlinking (must be named .stow-local-ignore; Stow does not read a .stow-global-ignore placed inside a package) |
- Enhanced history: 50K entries with timestamps and deduplication
- Safety aliases: Interactive prompts for
rm,cp,mv - Git integration: Branch information in prompt
- OS detection: Platform-specific aliases and settings
- Development tools: Integration with Docker, Node.js, Python, etc.
- Modern shell options: Auto-completion, directory navigation, history management
- Git-aware prompt: Shows branch name and status indicators
- Smart aliases: Directory shortcuts, safety features, productivity helpers
- Performance optimized: Fast startup with efficient plugin loading
- Custom prefix:
Ctrl-g(better for Emacs users) - Intuitive bindings:
|for horizontal split,-for vertical split - Enhanced status bar: Catppuccin (mocha) theme, via a plugin
- Clipboard: tmux-yank copies to the system clipboard, including over SSH
- Pinned plugins: installed by
make tmux-pluginsat exact commits, not the latest code. Avoid tpm'sprefix + Iandprefix + U, which fetch the latest code; change the pin inscripts/tmux-plugins.txtinstead - Mouse support: Enabled for modern terminal interaction
The configurations support loading additional personal files:
Bash:
~/.bash_profile_ps- PostScript/work-specific settings~/.bash_profile_do- DigitalOcean-specific settings~/.bash_profile_personal- Personal settings~/.bash_linux- Linux-specific settings~/.bash_osx- macOS-specific settings
Zsh:
You can add custom configurations at the end of .zshrc or create separate files and source them.
Set environment variables in:
.zshenv(for zsh).bash_profile(for bash)
ll- Long listing with human-readable sizesla- List all files including hidden..,...,....- Navigate up directoriesdev- Quick navigate to development directoryc- Clear terminalweather- Get weather for NYC
rm='rm -i'- Interactive removecp='cp -i'- Interactive copymv='mv -i'- Interactive move
tmux='tmux -2'- Force 256 color modeec- Open file in Emacs clientgbp- Git branch and push function
All three shells (bash, zsh, fish) show the state of the repository you are in.
Which VCS is reported is decided by walking up from the current directory: the
first .jj or .git found wins, so a colocated repo reports as jj.
| Marker | Meaning |
|---|---|
+ |
staged changes (index differs from HEAD) |
* |
unstaged changes (working tree differs from index) |
? |
untracked files present |
On a detached HEAD — including git bisect and git worktree add --detach —
there is no branch name, so the short commit is shown instead: (@a1b2c3d).
| Marker | Meaning |
|---|---|
* |
working copy is not empty (as of the last snapshot — see below) |
! |
the change is conflicted |
? |
the change is divergent |
The markers differ from git because the models do. jj has no index, so there is
no staged/unstaged split and no +. jj tracks everything in the workspace, so
there is no untracked state either, and ? is reused for divergent changes.
bookmark is the nearest bookmark in the ancestry, not a "current branch" — jj
has no such concept, and the working copy @ usually carries no bookmark at
all. When there is none anywhere above you, the prompt shows just (@changeid).
Snapshot accuracy. The prompt runs jj with --ignore-working-copy. Without
that flag, every prompt render would snapshot the working copy, writing a
snapshot working copy entry to the operation log and running roughly 5x
slower. The trade-off is that * reflects the last snapshot rather than this
instant; it catches up the next time any jj command runs. Set
DOTFILES_JJ_SNAPSHOT=1 to get an always-accurate marker at the cost of
mutating the repo on every prompt.
If you get conflicts when running make link:
# Rename the conflicting files to *.bak, then link
make force-linkEnsure proper permissions:
chmod 600 ~/.bashrc ~/.zshrcInstall missing tools as needed:
# macOS
brew install git stow tmux
# Linux (add xsel or wl-clipboard instead of xclip if you prefer)
sudo apt-get install git stow tmux xclipThe plugins are not installed. Run make tmux-plugins, then reload with
tmux source-file ~/.tmux.conf.
Licensed under the BSD License. See the repository for full license details.
Feel free to fork this repository and adapt it to your needs. Pull requests for improvements are welcome!