-
Notifications
You must be signed in to change notification settings - Fork 1
feat: capture macOS system defaults (home/.macos) #319
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,82 @@ | ||
| #!/usr/bin/env bash | ||
| # macOS system defaults — a faithful snapshot of this user's intentional settings. | ||
| # Captured via `defaults read` on 2026-06; reproduces the same choices on a new Mac. | ||
| # | ||
| # Run directly (`~/.macos` once symlinked, or `bash home/.macos`). Idempotent. | ||
| # bootstrap.sh runs this during a full `-p` install (NOT on a plain `-f` sync, so | ||
| # routine dotfile syncs don't restart Dock/Finder). | ||
| # | ||
| # NOT captured (can't be, via `defaults`): iCloud/Apple-ID settings, Login Items, | ||
| # TCC permissions, network/Wi-Fi, Touch ID, and sandboxed apps (Safari, Control | ||
| # Center) which need Full Disk Access and are fragile — configure those manually. | ||
|
|
||
| set -euo pipefail | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [Suggestion] With set -euo pipefail, the first defaults write that returns non-zero aborts the whole script, skipping every later setting AND the final killall Dock/Finder/SystemUIServer loop. The result is a partially-written, un-applied state (bootstrap.sh only prints a generic warning). For a script billed as idempotent and re-runnable, consider relaxing errexit for the defaults section (or running the killall via a trap on EXIT) so a single failed domain write does not prevent the UI restart that applies everything that did succeed. defaults write rarely fails for valid domains, so this is robustness hardening, not a live bug. |
||
|
|
||
| # macOS only. | ||
| [[ "$(uname)" == "Darwin" ]] || { echo "Skipping .macos (not macOS)"; exit 0; } | ||
|
|
||
| echo "Applying macOS defaults…" | ||
|
|
||
| # Close System Settings so it can't overwrite changes we're about to make. | ||
| osascript -e 'tell application "System Settings" to quit' 2>/dev/null || true | ||
|
|
||
| # ── Keyboard / text input (NSGlobalDomain) ────────────────────────────────── | ||
| defaults write NSGlobalDomain AppleShowAllExtensions -bool true # show all file extensions | ||
| defaults write NSGlobalDomain NSAutomaticCapitalizationEnabled -bool false | ||
| defaults write NSGlobalDomain NSAutomaticSpellingCorrectionEnabled -bool false | ||
| defaults write NSGlobalDomain NSAutomaticPeriodSubstitutionEnabled -bool false | ||
| defaults write NSGlobalDomain com.apple.swipescrolldirection -bool false # natural scrolling OFF | ||
| defaults write NSGlobalDomain AppleLocale -string "en_GB" | ||
|
|
||
| # ── Dock ──────────────────────────────────────────────────────────────────── | ||
| defaults write com.apple.dock autohide -bool true | ||
| defaults write com.apple.dock tilesize -int 64 | ||
| defaults write com.apple.dock largesize -int 16 | ||
| defaults write com.apple.dock magnification -bool false | ||
| defaults write com.apple.dock show-recents -bool false | ||
| defaults write com.apple.dock mru-spaces -bool false # don't auto-rearrange Spaces | ||
|
|
||
| # Hot corners (action codes: 2=Mission Control, 4=Desktop, 11=Launchpad, | ||
| # 12=Notification Center). Modifier 0 = no modifier key. | ||
| defaults write com.apple.dock wvous-tl-corner -int 2; defaults write com.apple.dock wvous-tl-modifier -int 0 | ||
| defaults write com.apple.dock wvous-tr-corner -int 12; defaults write com.apple.dock wvous-tr-modifier -int 0 | ||
| defaults write com.apple.dock wvous-bl-corner -int 11; defaults write com.apple.dock wvous-bl-modifier -int 0 | ||
| defaults write com.apple.dock wvous-br-corner -int 4; defaults write com.apple.dock wvous-br-modifier -int 0 | ||
|
|
||
| # ── Finder ────────────────────────────────────────────────────────────────── | ||
| defaults write com.apple.finder AppleShowAllFiles -bool true # show hidden files | ||
| defaults write com.apple.finder ShowPathbar -bool true | ||
| defaults write com.apple.finder ShowStatusBar -bool false | ||
| defaults write com.apple.finder FXPreferredViewStyle -string "Nlsv" # list view | ||
| defaults write com.apple.finder ShowHardDrivesOnDesktop -bool false | ||
| defaults write com.apple.finder ShowExternalHardDrivesOnDesktop -bool true | ||
| defaults write com.apple.finder NewWindowTarget -string "PfHm" # new windows → Home | ||
|
|
||
| # ── Trackpad (write to both built-in and Magic Trackpad domains) ──────────── | ||
| for d in com.apple.AppleMultitouchTrackpad com.apple.driver.AppleBluetoothMultitouch.trackpad; do | ||
| defaults write "$d" Clicking -bool true # tap to click | ||
| defaults write "$d" TrackpadThreeFingerDrag -bool true | ||
| defaults write "$d" TrackpadRightClick -bool true | ||
| defaults write "$d" TrackpadThreeFingerTapGesture -int 2 # 3-finger tap → look up | ||
| defaults write "$d" FirstClickThreshold -int 1 # light click | ||
| defaults write "$d" SecondClickThreshold -int 1 | ||
| done | ||
| # Companion key so tap-to-click also applies at the login window / globally. | ||
| defaults write NSGlobalDomain com.apple.mouse.tapBehavior -int 1 | ||
|
|
||
| # ── Window manager / Stage Manager ────────────────────────────────────────── | ||
| defaults write com.apple.WindowManager GloballyEnabled -bool false # Stage Manager off | ||
| defaults write com.apple.WindowManager HideDesktop -bool true | ||
|
|
||
| # ── Menu-bar clock ────────────────────────────────────────────────────────── | ||
| defaults write com.apple.menuextra.clock ShowDayOfWeek -bool false | ||
| defaults write com.apple.menuextra.clock ShowDate -int 0 | ||
|
|
||
| # ── Misc ──────────────────────────────────────────────────────────────────── | ||
| defaults write com.apple.desktopservices DSDontWriteNetworkStores -bool true # no .DS_Store on network shares | ||
| defaults write com.apple.ActivityMonitor ShowCategory -int 102 | ||
|
|
||
| # Apply: restart affected UI processes. | ||
| for app in Dock Finder SystemUIServer; do killall "$app" 2>/dev/null || true; done | ||
|
|
||
| echo "macOS defaults applied. Some changes need a logout/restart to fully take effect." | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[Suggestion] The guard tests for the executable bit, but the script is invoked via bash on the file path, which does not need the exec bit. If that bit is ever lost (e.g. core.fileMode=false, a non-exec filesystem, or an archive extraction), the defaults would silently not apply during bootstrap with no warning. A file-exists test matches how the file is actually run and is more resilient.