Windows 11 dotfiles managed with Chezmoi. Includes editor configs, shell profiles, app settings, and automation scripts for a reproducible setup.
| Category | Tools |
|---|---|
| Editors | Vim, Neovim, Emacs (Chemacs2 + Doom), IntelliJ IdeaVim, Sublime Text, VS Code |
| Shell | PowerShell 7+, Windows PowerShell 5.1, custom modules (git aliases, rclone, shortcuts, tools) |
| Terminal | Windows Terminal (Sauce Code Pro NF) |
| Desktop | Rainmeter (RSS feed), AutoHotkey (brightness keys), Auto Dark Mode (wallpaper switching) |
| Apps | VLC, TeXstudio, RStudio, PowerToys |
| Git | Global .gitignore_global (OS/IDE/build junk), LF line endings, autocrlf = input |
| Automation | Chocolatey install scripts, bloatware removal, registry tweaks, WSL setup |
- Installation
- Git Configuration
- Chezmoi Usage
- Commands
- Chocolatey
- PowerShell
- Task Scheduler
- Recover Windows Boot EFI
- PARA Drive Sync
- Application Data Restore
- Development
- License
Tip: Run these commands from the Windows PowerShell app (run as Administrator), not from Windows Terminal.
Download and run the setup script:
iwr -useb https://raw.githubusercontent.com/cuberhaus/WinDotfiles/master/setup-dotfiles.ps1 -OutFile setup-dotfiles.ps1
.\setup-dotfiles.ps1The script auto-elevates to admin, installs Chocolatey + Git + chezmoi, applies the dotfiles, and then prompts for an install profile:
| Profile | Orchestrator | Software set |
|---|---|---|
personal |
windows.ps1 |
Full personal toolchain (Emacs, LaTeX, R, games-adjacent tools, …) |
work |
windows_work.ps1 |
Subset focused on dev work; entertainment/personal apps commented out |
To skip the prompt, pass flags:
.\setup-dotfiles.ps1 -Profile work -WorkMode full # work + extended packages
.\setup-dotfiles.ps1 -Profile work -WorkMode minimal # work, essentials only
.\setup-dotfiles.ps1 -Profile personalAfter setup, configure your personal information:
cd $HOME\.local\share\chezmoi
.\fix-chezmoi-config.ps1This prompts you for email/name/GitHub username and updates your git configuration. (Re-running setup-dotfiles.ps1 will not clobber the resulting chezmoi.toml.)
Authenticate with GitHub CLI (required for cloning private repos):
gh auth loginThis enables passwordless git operations using GitHub CLI as the credential helper.
The orchestrators refresh the session's environment variables in-process via Invoke-RefreshEnv, so Vim, Emacs, pipenv, and the other post-install steps run inline. A reboot is only needed for:
- WSL (after the feature is enabled the first time)
- The Caps Lock ↔ Escape keyboard remap (takes effect on next sign-in)
Chezmoi applies a global .gitconfig with these QoL settings:
| Setting | Value | Purpose |
|---|---|---|
core.excludesfile |
~/.gitignore_global |
Ignores OS junk (Thumbs.db, .DS_Store), IDE dirs (.idea/, .vscode/), build artifacts, and more across all repos |
core.autocrlf |
input |
Converts CRLF → LF on commit; avoids phantom diffs on Windows |
The global gitignore covers:
- OS files —
.DS_Store,Thumbs.db,Desktop.ini,$RECYCLE.BIN/ - Editors/IDEs —
.vscode/,.idea/,*.swp,*.swo,*~,.sublime-*,.project,.settings/ - Python —
__pycache__/,*.py[cod],.venv/,venv/,.env - Node —
node_modules/ - Build artifacts —
*.o,*.obj,*.exe,*.dll,*.so,*.dylib - Logs —
*.log,npm-debug.log*
Note: All repos should also have their own
.gitattributeswith* text=auto eol=lfto enforce LF endings at the repo level.
A Makefile is included for common operations. Run make help for the full list, or use chezmoi directly:
| Command | Description |
|---|---|
chezmoi apply -v |
Apply dotfiles to home directory |
chezmoi diff |
Preview pending changes |
chezmoi re-add |
Update source state from modified home files |
chezmoi edit --apply <file> |
Edit a managed file and apply immediately |
chezmoi git add . && chezmoi git commit -m "msg" && chezmoi git push |
Commit and push changes |
chezmoi upgrade |
Upgrade chezmoi to latest version |
You can customize the dotfiles by editing the files in ~/.local/share/chezmoi. Learn more about source state attributes in the Chezmoi reference.
The Makefile works on Windows and Linux (cross-platform shell + pwsh). Targets that require Windows-specific tools error with a clear message on Linux.
| Group | Target | Description |
|---|---|---|
| Chezmoi | make apply |
Apply dotfiles to home directory |
| Chezmoi | make dry-run |
Simulate apply and show what would change |
| Chezmoi | make diff / status / update / re-add / cd |
Common chezmoi operations |
| Quality | make lint |
Parse-check every .ps1/.psm1 |
| Quality | make analyze |
Run PSScriptAnalyzer (errors fail; warnings reported) |
| Quality | make test |
Run Pester tests under tests/ |
| Quality | make check |
Run lint + analyze + test |
| Setup | make doctor |
Report missing tools (chezmoi, git, pwsh, choco/winget on Windows) |
| Setup | make hooks |
Install git pre-commit hook (gitleaks secret scan on staged files) |
| Windows | make install |
Run the full Windows installation (prompts for personal vs work, then minimal vs full on work) |
| Windows | make install-personal |
Personal install, skips the profile prompt |
| Windows | make install-work |
Work install, still prompts for minimal vs full |
| Windows | make install-work-full |
Work install, full subset, no profile prompts |
| Windows | make install-unattended |
Fully non-interactive (work + minimal, all per-step prompts default to OFF) |
| Windows | make upgrade |
Upgrade chezmoi via Chocolatey |
make doctor is a good first check on a new machine. Run it before make install to catch missing prerequisites early.
All install* targets route through setup-dotfiles.ps1 (auto-elevates, installs Chocolatey + Git + chezmoi, syncs workspace files, then runs the chosen orchestrator). The per-step prompts (Caps/Esc, Emacs + Doom, clone personal repos) still apply unless you pass -Unattended or override individually \u2014 see Interactive prompts during install below.
Run aliases in PowerShell to open all profile and module files for editing. Key shell functions:
| Command | Description |
|---|---|
update |
Upgrade Chocolatey packages and Windows |
updateall |
Upgrade everything including Vim plugins |
cleanup |
Run choco-cleaner and Vim plugin cleanup |
sudo / su |
Launch an elevated PowerShell window |
g, ga, gc, gs, gp |
Git shortcuts (git, add, commit, status, push) |
pull, fetch, yolo |
Recursive git operations across all repos |
cr |
cd to ~/repos |
ce <file> |
chezmoi edit --apply shortcut |
vim |
Launches Neovim |
choco upgrade allchoco listAll profiles source a single shared config at ~/.local/scripts/profile_common.ps1. This works for both PowerShell 7+ and Windows PowerShell 5.1, and across Documents and OneDrive folder locations.
To check which profile is being loaded:
$PROFILE | Format-List -ForceTo add a task at login, use the schtasks command. Example:
schtasks /create /tn "TaskName" /tr "command" /sc onlogonNote: If user and computer name differ, you may need to adjust the task's user account via the Task Scheduler GUI.
Emergency procedure to restore a missing Windows boot entry. Video guide.
c:\windows is your healthy Windows installation. v: is the EFI partition:
bcdboot c:\windows /s v: /f UEFI
Helpers for keeping a local PARA folder tree in sync with a Google Drive Stream mount, with safe handling of .gdoc/.gsheet pointers and emoji/accented paths. See docs/DRIVE_SYNC.md.
Both orchestrators run a small set of Invoke-Step calls after the package installs to restore user data from a Google Drive backup via rclone. Each step delegates to the matching rclonepull_* helper in home/dot_local/scripts/modules/my_rclone.psm1 so paths and rclone flags live in one place.
| App | Profile | Drive source | Local destination |
|---|---|---|---|
| Thunderbird | personal + work | drive:4 Archive/rcloneBackups/Thunderbird/ |
%APPDATA%\Thunderbird\Profiles |
| Anki | personal only | drive:4 Archive/rcloneBackups/Anki/ |
%APPDATA%\Anki2\ |
| Calibre | personal only | drive:4 Archive/rcloneBackups/Calibre/Calibre Library |
%USERPROFILE%\Calibre Library |
The work bootstrap only wires Thunderbird because work_full_install doesn't install Anki / Calibre; the Thunderbird step itself self-skips on a work box that doesn't have it either, so it's a safe no-op.
Each step is defensive and skips cleanly when any precondition is missing: no rclone on PATH, no drive: rclone remote configured, the app isn't installed, or the app is currently running. The bootstrap cannot create the Drive remote because Google requires an interactive OAuth flow — the first time you hit a missing remote you get a one-time yellow banner with the exact recipe:
rclone config # add a Google Drive backend named exactly 'drive'Then re-run setup-dotfiles.ps1, or call rclonepull_thunderbird / rclonepull_anki / rclonepull_calibre directly from any shell. Push direction (rclonepush_*, rclone_sync_push_*) stays manual to avoid clobbering the remote.
A handful of steps ask before running so you can decline heavy / personal-only work without editing the script. Each one also takes an explicit flag for unattended runs:
| Step | Personal | Work | Function param | Orchestrator flag |
|---|---|---|---|---|
| Caps Lock ↔ Escape | yes | yes | registry -SwapCapsEscape $true/$false |
-SwapCaps $true/$false |
| Emacs + Chemacs2 + Doom | yes | n/a | emacs_install -Install $true/$false |
-InstallEmacs $true/$false |
| Clone personal repos | yes | yes | clone -Clone $true/$false |
-CloneRepos $true/$false |
Pass -Unattended to skip every prompt and default all three to off (matches the existing $SwapCaps = $false behaviour). Pass any of the explicit flags individually to override one without touching the others.
The VS Code multi-root workspace at $env:USERPROFILE\cuberhaus (where all ~50 sibling git repos are cloned) is not itself a git repo, so any files placed at its root would be untracked. The cuberhaus-workspace/ folder is the git-tracked source of truth for those files (workspace-level AGENTS.md, the /init-repo skill that scaffolds per-repo AGENTS.md).
make sync-workspace # copy sources -> ~\cuberhaus (idempotent)
make sync-workspace-dry-run # preview without writingThe sync also removes the legacy 15-byte .github\copilot-instructions.md stub that pointed at a non-existent ../.cursorrules. See cuberhaus-workspace/README.md for the file list and how to add new ones.
CI runs PSScriptAnalyzer and Pester on every push. Both can be run locally:
Invoke-ScriptAnalyzer -Path . -Recurse -Settings .\PSScriptAnalyzerSettings.psd1
Invoke-Pester ./tests -Output DetailedThe VS Code PowerShell extension auto-discovers PSScriptAnalyzerSettings.psd1 at the workspace root, so editor warnings match CI.
MIT.
