-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathinstall
More file actions
executable file
·258 lines (239 loc) · 9.48 KB
/
install
File metadata and controls
executable file
·258 lines (239 loc) · 9.48 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
#!/usr/bin/env zsh
set -eu
DOTFILES=${0:A:h}
# Colors
autoload -U colors && colors
info() { print -P "%F{blue}[INFO]%f $1" }
ok() { print -P "%F{green}[OK]%f $1" }
warn() { print -P "%F{yellow}[WARN]%f $1" }
err() { print -P "%F{red}[ERROR]%f $1" }
# Flags
AUTOYES=false
ALLOW_ADOPT=false
for arg in "$@"; do
case $arg in
--yes|-y) AUTOYES=true ;;
--adopt) ALLOW_ADOPT=true ;;
-h|--help)
print "Usage: ./install [--yes|-y] [--adopt]"
print " --yes Non-interactive (auto-yes to all prompts)"
print " --adopt Allow stow --adopt on conflict (DESTRUCTIVE: moves \$HOME files into the repo)"
exit 0
;;
*) err "Unknown flag: $arg"; exit 2 ;;
esac
done
ask() {
if $AUTOYES; then
info "$1 [auto-yes]"
return 0
fi
read -q "?$1 [y/N] " || { print; return 1 }
print
}
# --- Xcode Command Line Tools ---
if ! xcode-select -p &>/dev/null; then
if ask "Install Xcode Command Line Tools?"; then
info "Installing Xcode Command Line Tools..."
xcode-select --install
until xcode-select -p &>/dev/null; do
sleep 5
done
ok "Xcode Command Line Tools installed."
fi
fi
# --- Homebrew ---
if ! command -v brew &>/dev/null; then
if ask "Install Homebrew?"; then
info "Installing Homebrew..."
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
eval "$(/opt/homebrew/bin/brew shellenv zsh)"
ok "Homebrew installed."
fi
fi
# --- Brewfile ---
if command -v brew &>/dev/null; then
while IFS= read -r line <&3; do
[[ -z $line || $line == \#* ]] && continue
[[ $line =~ '^(brew|cask|tap)[[:space:]]+"([^"]+)"' ]] || continue
type=$match[1]
pkg=$match[2]
# Skip if already installed/tapped
case $type in
tap)
if brew tap | grep -qx "$pkg"; then
info "tap '${pkg}' already added, skipping."
continue
fi
;;
brew)
if brew list --formula "$pkg" &>/dev/null; then
info "'${pkg}' already installed, skipping."
continue
fi
;;
cask)
if brew list --cask "$pkg" &>/dev/null; then
info "'${pkg}' already installed, skipping."
continue
fi
;;
esac
if ask "Install ${type} '${pkg}'?"; then
case $type in
tap) brew tap "$pkg" || warn "Failed to tap ${pkg}, continuing..." ;;
brew) brew install "$pkg" || warn "Failed to install ${pkg}, continuing..." ;;
cask) brew install --cask "$pkg" || warn "Failed to install ${pkg}, continuing..." ;;
esac
fi
done 3< ${DOTFILES}/Brewfile
fi
# --- Oh My Zsh ---
if [[ ! -d ${HOME}/.oh-my-zsh ]]; then
if ask "Install Oh My Zsh?"; then
info "Installing Oh My Zsh..."
sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" "" --unattended --keep-zshrc
ok "Oh My Zsh installed."
fi
fi
# --- Oh My Zsh Custom Themes ---
ZSH_CUSTOM=${ZSH_CUSTOM:-${HOME}/.oh-my-zsh/custom}
typeset -A custom_themes=(
powerlevel10k https://github.com/romkatv/powerlevel10k.git
)
for theme url in ${(kv)custom_themes}; do
if [[ ! -d ${ZSH_CUSTOM}/themes/${theme} ]]; then
if ask "Install oh-my-zsh theme '${theme}'?"; then
git clone --depth=1 "$url" "${ZSH_CUSTOM}/themes/${theme}"
ok "${theme} installed."
fi
fi
done
# --- Oh My Zsh Custom Plugins ---
typeset -A custom_plugins=(
zsh-autosuggestions https://github.com/zsh-users/zsh-autosuggestions.git
zsh-syntax-highlighting https://github.com/zsh-users/zsh-syntax-highlighting.git
)
for plugin url in ${(kv)custom_plugins}; do
if [[ ! -d ${ZSH_CUSTOM}/plugins/${plugin} ]]; then
if ask "Install oh-my-zsh plugin '${plugin}'?"; then
git clone "$url" "${ZSH_CUSTOM}/plugins/${plugin}"
ok "${plugin} installed."
fi
fi
done
# --- macOS Defaults ---
if ask "Apply macOS Finder defaults?"; then
# Show all file extensions
defaults write NSGlobalDomain AppleShowAllExtensions -bool true
# Show hidden files
defaults write com.apple.finder AppleShowAllFiles -bool true
# Show path bar
defaults write com.apple.finder ShowPathbar -bool true
# Show status bar
defaults write com.apple.finder ShowStatusBar -bool true
# Default to list view
defaults write com.apple.finder FXPreferredViewStyle -string "Nlsv"
# Disable warning when changing file extension
defaults write com.apple.finder FXEnableExtensionChangeWarning -bool false
# Keep folders on top when sorting by name
defaults write com.apple.finder _FXSortFoldersFirst -bool true
# Search the current folder by default
defaults write com.apple.finder FXDefaultSearchScope -string "SCcf"
# Disable the "Are you sure you want to open this application?" dialog
defaults write com.apple.LaunchServices LSQuarantine -bool false
# Show ~/Library
chflags nohidden ~/Library
killall Finder
ok "Finder defaults applied."
fi
if ask "Apply macOS Dock defaults?"; then
# Minimize windows into their application icon
defaults write com.apple.dock minimize-to-application -bool true
# Don't show recent applications
defaults write com.apple.dock show-recents -bool false
# Don't rearrange Spaces based on most recent use
defaults write com.apple.dock mru-spaces -bool false
# Faster Mission Control animation
defaults write com.apple.dock expose-animation-duration -float 0.1
# Remove auto-hide delay
defaults write com.apple.dock autohide-delay -float 0
# Faster auto-hide animation
defaults write com.apple.dock autohide-time-modifier -float 0.3
# Set icon size
defaults write com.apple.dock tilesize -int 48
killall Dock
ok "Dock defaults applied."
fi
if ask "Apply macOS keyboard defaults?"; then
# Blazing fast key repeat (essential for Vim-style navigation)
defaults write NSGlobalDomain KeyRepeat -int 2
# Short delay until key repeat kicks in
defaults write NSGlobalDomain InitialKeyRepeat -int 15
# Disable auto-correct
defaults write NSGlobalDomain NSAutoCorrectionEnabled -bool false
# Disable smart quotes (they break code)
defaults write NSGlobalDomain NSAutomaticQuoteSubstitutionEnabled -bool false
# Disable smart dashes (they break code)
defaults write NSGlobalDomain NSAutomaticDashSubstitutionEnabled -bool false
# Enable full keyboard access (Tab through all UI controls)
defaults write NSGlobalDomain AppleKeyboardUIMode -int 3
# Disable auto-capitalization
defaults write NSGlobalDomain NSAutomaticCapitalizationEnabled -bool false
# Disable auto period substitution (double-space to period)
defaults write NSGlobalDomain NSAutomaticPeriodSubstitutionEnabled -bool false
# Disable spell correction
defaults write NSGlobalDomain NSAutomaticSpellingCorrectionEnabled -bool false
# Disable press-and-hold for accent characters (enables key repeat everywhere)
defaults write NSGlobalDomain ApplePressAndHoldEnabled -bool false
ok "Keyboard defaults applied."
fi
if ask "Apply macOS screenshot defaults?"; then
# Save screenshots to ~/Pictures/Screenshots instead of Desktop
defaults write com.apple.screencapture location -string "${HOME}/Pictures/Screenshots"
mkdir -p ${HOME}/Pictures/Screenshots
# Disable shadow in screenshots
defaults write com.apple.screencapture disable-shadow -bool true
# Save as PNG (lossless)
defaults write com.apple.screencapture type -string "png"
killall SystemUIServer
ok "Screenshot defaults applied."
fi
if ask "Apply macOS trackpad defaults?"; then
# Enable tap to click
#defaults write com.apple.AppleMultitouchTrackpad Clicking -bool true
# Three-finger drag
defaults write com.apple.AppleMultitouchTrackpad TrackpadThreeFingerDrag -bool true
ok "Trackpad defaults applied."
fi
if ask "Apply miscellaneous power-user defaults?"; then
# Expand save panels by default
defaults write NSGlobalDomain NSNavPanelExpandedStateForSaveMode -bool true
defaults write NSGlobalDomain NSNavPanelExpandedStateForSaveMode2 -bool true
# Expand print panels by default
defaults write NSGlobalDomain PMPrintingExpandedStateForPrint -bool true
defaults write NSGlobalDomain PMPrintingExpandedStateForPrint2 -bool true
ok "Miscellaneous defaults applied."
fi
# --- Stow ---
if command -v stow &>/dev/null; then
if ask "Stow dotfiles?"; then
for dir in ${DOTFILES}/*(/); do
if stow -d ${DOTFILES} -n -R ${dir:t} 2>/dev/null; then
stow -d ${DOTFILES} -R ${dir:t}
ok "${dir:t} stowed."
elif $ALLOW_ADOPT; then
warn "${dir:t} has conflicts; --adopt set, resolving..."
stow -d ${DOTFILES} --adopt -R ${dir:t}
warn "Adopted ${dir:t}: review 'git diff' for clobbered tracked files."
else
err "${dir:t} has conflicts with files in \$HOME."
err "Re-run with --adopt to resolve (DESTRUCTIVE: moves \$HOME files into the repo, overwriting tracked configs)."
exit 1
fi
done
fi
else
warn "stow not found, skipping dotfile linking."
fi
ok "All done!"