中文 | English
After reading webpro's article, I discovered many useful dotfiles. I think they are great, but I don't want to copy them directly (I believe everyone's computer setup is unique). I want a configuration that fits me, just like mathiasbynens.
Clone the repository, then run the installer(Mac/Linux):
git clone https://github.com/genwilliam/dotfiles.git ~/dotfiles
cd ~/dotfiles
./install.shIf you want the installer to also delete any README* files under your home directory (e.g. from previous sync attempts), run:
./install.sh --remove-readmesFor Windows users, use one of these installers instead:
# PowerShell (recommended on Windows)
./install-for-windows.ps1# Git Bash shell script
./install-for-windows.shImportant
On Windows, creating symbolic links usually requires either Administrator privileges or Developer Mode. If you run into link creation errors, run your terminal as Administrator, or enable Developer Mode: Settings → Privacy & security → For developers → Developer Mode.
If you only want to validate the dotfiles links and warm up zsh startup caching, run:
./bootstrap.shAs Joshua Clayton said in a recent episode of The Changelog, if you're unhappy with your dotfiles, you're doing it wrong™. Pick and choose what you like from other people's dotfiles. Learn from everyone, follow no one. Build your own lightsaber. Rebuild it from scratch with confidence. Original: https://wynnnetherland.com/journal/dotfiles-discovery
If you don't know what dotfiles are, this article is helpful.
Dotfiles are configuration files in Unix-like systems (such as macOS and Linux) whose names start with
.. They are usually used to store user-level application settings.They are called dotfiles because each filename starts with a dot.
Important
Before you start, I need to mention that my shell setup is based on zsh.
If you use another shell (such as bash, fish, or others), I cannot guarantee this setup will work.
This repository may help you.
If you want to change your default shell (set zsh as default), searching on Google should help.
The principle: Do one thing and do it well
I like this principle (we all do, right?). So in my dotfiles, different tools do different jobs, even if a file only has one line, for example:
tmuxhandles terminal multiplexingzshhandles the shellneovimhandles text editinggithandles version control
...
Before you begin, please read zsh/bash loading order.
Moral: For bash, put stuff in ~/.bashrc, and make ~/.bash_profile source it. For zsh, put stuff in ~/.zshrc, which is always executed.
Briefly talk about my understanding:
| File | Load Order | When It Is Loaded | Shell Type | Runs Every Shell Start? | Typical Use |
|---|---|---|---|---|---|
.zshenv |
1 | Loaded for every Zsh invocation | login / interactive / non-interactive / scripts | ✅ Yes | Basic environment variables (PATH, LANG, EDITOR) |
.zprofile |
2 | Loaded when a login shell starts | login shell | ❌ No (login only) | Login initialization, brew shellenv, PATH setup |
.zshrc |
3 | Loaded for interactive shells | interactive shell | ❌ No (interactive only) | aliases, prompt, plugins, completion |
.zlogin |
4 | Loaded after .zshrc in a login shell |
login shell | ❌ No (login only) | Post-login tasks, startup messages |
I do not use the Oh My Zsh runtime framework anymore.
Zsh plugins are loaded directly from Homebrew paths in zsh/zshrc.d/plugins.zsh (source-based, framework-free).
The ohmyzsh/ directory in this repo is kept only as a historical plugin-list archive.
In large plugin setups, repeated source ~/.zshrc can become unexpectedly slow when compinit keeps rebuilding completion metadata (compdump).
- Re-sourcing
~/.zshrcin the same shell can cause completion metadata drift if path arrays are not deduplicated. - Once metadata differs,
compinitmay regenerate completion cache, which can make reload time jump from milliseconds to hundreds of milliseconds.
- Enable
fpath/pathuniqueness (typeset -gU fpath path) to prevent duplication during repeated sourcing. - Pin cache locations with
ZSH_CACHE_DIRandZSH_COMPDUMPunder~/.cachefor deterministic cache behavior. - Use
compinit -C -d "$ZSH_COMPDUMP"incompletion.zshto prefer cache reuse. - Keep completion policy explicit:
Tabuses menu selection, whilefzf-tabis available via keybinding.
I've used two themes: powerlevel10k and starship.
Caution
I don't know whether you prefer p10k or starship, so I include both.
However, I currently use starship, so you will see a p10k folder in this repo.
If you don't need p10k, you can delete it.
Likewise, if you need p10k, you can delete the starship config, then move and replace the files from ./p10k into ./zsh.
A Zsh prompt configuration based on Powerlevel10k, using a Rainbow + Powerline style, and requiring Nerd Font.
- Left side shows: current directory and Git status
- Right side shows: command exit code, execution time, language versions (Node/Python/Ruby, etc.), K8s/cloud context, and current time
- Enables instant prompt (near-zero startup delay) and transient prompt (simplified previous prompt lines)
- Uses modular config in
zshrc.d/for easier maintenance
If you don't like my style, run p10k configure in your terminal to reconfigure it. If fonts are missing, the configuration wizard may display incorrectly.
If you are a Windows user, this article explains it in detail.
A Zsh prompt configuration based on Starship, with integration for multiple languages and tools. If the current directory is a Git repository, the prompt shows branch and status. If the current directory contains a Node.js project, it shows the Node.js version. If it contains a Python project, it shows the Python version. Note that for Python version display, you need to activate a Python environment.
This file needs to be placed in ~/.config.
ln -s ~/dotfiles/starship/starship.toml ~/.config/starship.tomlThis is the Starship configuration file. You can modify it based on your needs. The format is TOML. You can find more details here.
-
gitconfigcontains global Git settings, such as username and email. -
If you want to know what each option means and how it works, see this article.
-
The content here should not be used directly; you need to customize it.
One important note: if your email is written directly in config, it may expose your address.
But GitHub can hide your email address. See this article.
You can enable Keep my email addresses private in GitHub to get a noreply email address.
CLI Git will not use it automatically, but you can put that address in gitconfig to avoid exposing your real email.
If you prefer to use your real email locally, you can split your config and create a file such as .gitconfig.local to store personal info.
gitignore_global contains global Git ignore rules (such as node_modules).
You can modify it as needed.
Its path must match the setting in gitconfig; otherwise Git won't load these rules.
If you don't like this approach, you can remove it and add a .gitignore file in each project instead, which gives more flexible per-project control.
My tmux configuration is based on oh-my-tmux Automatically install this configuration as follows:
curl -fsSL "https://github.com/gpakosz/.tmux/raw/refs/heads/master/install.sh#$(date +%s)" | bashAfter syncing this repo, tmux mainly reads customizations from tmux/tmux.conf.local.
tmux-plugins/tmux-copycat: quick regex-based search in scrollback/copy-mode.tmux-plugins/tmux-resurrect: save and restore tmux sessions/windows/panes.27medkamal/tmux-session-wizard: project/session switcher popup (fzf + zoxide).tmux-plugins/tmux-sensible: safer defaults and compatibility tweaks.tmux-plugins/tmux-yank: copy selected text into system clipboard.tmux-plugins/tmux-open: open highlighted path/URL with system handler.
Optional but currently disabled:
tmux-plugins/tmux-cputmux-plugins/tmux-continuum
TPM lifecycle keys:
Prefix + I: install pluginsPrefix + u: update pluginsPrefix + Alt + u: uninstall removed plugins
- Based on Oh My Tmux theme model and status segments.
- Mouse mode enabled by default (
set -g mouse on). - Larger scrollback history (
set -g history-limit 10000). - Copy to OS clipboard enabled (
tmux_conf_copy_to_os_clipboard=true). - Added split shortcut:
Prefix + =for left/right split (split-window -h). - Kept split shortcut:
Prefix + -for top/bottom split. - Added
dddelete flow in session tree (Prefix + s):- first
denters delete key table - second
dkills selected session/window/pane Escexits delete key table
- first
Note:
Prefix + sis tmux built-in choose-tree, whiletmux-session-wizarddefault key isPrefix + Tunless customized.
Assume default prefix is Ctrl+b.
Prefix + s: open session tree (choose-tree)j/k: move down/up in listdd: delete selected item (custom behavior in this repo)Prefix + T: open session wizard popup (plugin default)
Prefix + c: create new windowPrefix + w: open window tree/listPrefix + -: split top/bottomPrefix + =: split left/right (custom)Prefix + x: kill current panePrefix + z: zoom/unzoom panePrefix + q: show pane numbers
Prefix + h/j/k/l: move between panesPrefix + H/J/K/L: resize panePrefix + r: reload tmux configPrefix + m: toggle mouse mode (custom toggle)
Prefix + [: enter copy mode- In copy-mode-vi:
vstart selection,ycopy and exit - Copied content is piped to system clipboard on macOS/Linux when backend tool is available
Based on nvchad nvim configuration, If you don't have nvim installed, you can use the following command to install it (macOS):
brew install nvimOr download it from the official website.
It contains Homebrew packages installed via brew. Please inspect this file with a text editor first and adjust it to your needs. It uses Brewfile format. You can find more details here.
Then install with:
brew bundle --file=./Brewfileappdir is an option in Homebrew Brewfile. It specifies where cask apps are installed.
By default, Homebrew installs apps into /Applications.
If you want another directory, you can set this parameter, for example:
brew install --cask devtoys --appdir="~/Applications"On macOS, the first user account is always an administrator account.
Administrator accounts belong to the admin group and have sudo privileges.
This means they can effectively control the system, including privileged operations, which increases risk.
Tools like sudo can have weaknesses that may be exploited by concurrently running programs.
Apple recommends this best practice: use a separate standard account for daily work, and use an administrator account only for installation and system configuration.
You don't have to log in through the macOS login screen as the admin account all the time. When terminal commands require admin privileges, the system prompts for authentication, then the terminal continues with those privileges. For this, Apple provides guidance on hiding the admin account and its home directory here. It's an elegant approach to avoid having a visible “ghost” account.
Quoted from https://github.com/drduh/macOS-Security-and-Privacy-Guide
If you don't want to pass this parameter every time you install a cask app, you can search online for alternatives.
The bin folder contains custom commands/scripts. You can modify them as needed.
This folder should be added to your PATH environment variable so you can run commands directly in terminal.
The macos folder contains macOS configuration scripts (for example, system preference settings).
You can modify them as needed.
Scripts in this folder should be made executable with chmod +x, then run directly in terminal.
The macos scripts can use the defaults command to modify system preferences.
You can read more about defaults here.
This one-shot script does the following:
- macOS: installs Homebrew (with confirmation), then installs apps/packages from Brewfile
- Linux: skips Homebrew/Brewfile and uses your detected package manager for required packages
- Installs oh-my-zsh
- Installs p10k or starship (starship by default)
- Installs zsh plugins
- Prints Meslo Nerd Font guidance at the end
For Meslo Nerd Font:
- Windows: download from https://github.com/romkatv/powerlevel10k#meslo-nerd-font-patched-for-powerlevel10k
- macOS:
brew tap homebrew/cask-fonts && brew install --cask font-meslo-lg-nerd-font - Linux: use your package manager to install Meslo/Nerd Fonts (script prints detected manager hints)


