summaryrefslogtreecommitdiff
path: root/hosts
diff options
context:
space:
mode:
authorRyan Schanzenbacher <ryan@rschanz.org>2026-08-03 01:22:44 -0400
committerRyan Schanzenbacher <ryan@rschanz.org>2026-08-03 01:22:44 -0400
commit0c8fa3a2a270747f3dbb54fe8792f3f0aec997e3 (patch)
tree6f94ff3aeea2af859c7c166e01a8e73002017893 /hosts
Initial commit: combined darwin + guix-linux home-manager flake
Supersedes nix-dotfiles (darwin) and guix-dotfiles' ad-hoc nix-home-manager flake (linux). See README.md/MIGRATION.md.
Diffstat (limited to 'hosts')
-rw-r--r--hosts/RyanMac/configuration.nix438
1 files changed, 438 insertions, 0 deletions
diff --git a/hosts/RyanMac/configuration.nix b/hosts/RyanMac/configuration.nix
new file mode 100644
index 0000000..e19490d
--- /dev/null
+++ b/hosts/RyanMac/configuration.nix
@@ -0,0 +1,438 @@
1{ config, pkgs, inputs, lib, ... }:
2let
3 username = "ryan";
4
5 defaultBrowser = "zen";
6
7 thirdPartyTaps = {
8 "netbirdio/homebrew-tap" = inputs.homebrew-netbird;
9 "FelixKratz/homebrew-formulae" = inputs.homebrew-felixkratz;
10 };
11
12 pinnedNixpkgs = pkgs.writeText "flake-registry.json" (builtins.toJSON {
13 version = 2;
14 flakes = [
15 {
16 from = { type = "indirect"; id = "nixpkgs"; };
17 to = {
18 type = "path";
19 path = inputs.nixpkgs.outPath;
20 lastModified = inputs.nixpkgs.lastModified;
21 narHash = inputs.nixpkgs.narHash;
22 };
23 }
24 ];
25 });
26
27 mkSpace = i: {
28 name = toString (117+i);
29 value = {
30 enabled = true;
31 value = {
32 type = "standard";
33 parameters = [ (48 + i) (builtins.elemAt [ 18 19 20 21 22 23 25 26 28 ] (i - 1)) 524288 ]; # opt + num
34 #parameters = [ (48 + i) (builtins.elemAt [ 18 19 20 21 22 23 25 26 28 ] (i - 1)) 1048576 ]; # cmd + num
35 };
36 };
37 };
38
39 spaceHotkeys = builtins.listToAttrs (map mkSpace (lib.range 1 9));
40
41 manualHotkeys = {
42 "64" = {
43 enabled = true;
44 };
45 };
46
47in {
48 # Modules
49 imports = [
50 inputs.nix-homebrew.darwinModules.nix-homebrew
51 ../../modules/darwin/random-wallpaper
52 ];
53
54 # Define the system's user and home dir location
55 users.users."${username}" = {
56 name = "${username}";
57 home = "/Users/${username}";
58 };
59
60 system.primaryUser = "${username}";
61
62 # Set the hostname for this machine
63 networking.hostName = "RyanMac";
64
65 # Install the wallpaper engine
66 local.randomWallpaper = {
67 enable = true;
68 directory = "${../../files/Wallpapers}";
69 };
70
71 # Configure yabai
72 services.yabai = {
73 enable = true;
74 enableScriptingAddition = false;
75 config = {
76 mouse_follows_focus = "on";
77 layout = "bsp";
78 window_placement = "second_child";
79 top_padding = "10";
80 bottom_padding = "10";
81 left_padding = "10";
82 right_padding = "10";
83 window_gap = "10";
84 mouse_modifier = "alt";
85 mouse_drop_action = "swap";
86 mouse_action1 = "move";
87 mouse_action2 = "resize";
88 focus_follows_mouse = "autofocus";
89 };
90 extraConfig = ''
91 yabai -m rule --add app='System Settings' manage=off
92 yabai -m rule --add app="^Zen$" title="^Picture-in-Picture$" manage=off
93 ''
94 # Add simple-bar signals if enabled
95 + lib.optionalString config.home-manager.users.${username}.ryan.simple-bar.enable ''
96 yabai -m signal --add event=window_focused action="curl http://localhost:7776/yabai/spaces/refresh && curl http://localhost:7776/yabai/windows/refresh" label="Refresh simple-bar spaces & windows when focused application changes"
97 yabai -m signal --add event=window_resized action="curl http://localhost:7776/yabai/spaces/refresh && curl http://localhost:7776/yabai/windows/refresh" label="Refresh simple-bar spaces & windows when a window is resized"
98 yabai -m signal --add event=window_destroyed action="curl http://localhost:7776/yabai/spaces/refresh && curl http://localhost:7776/yabai/windows/refresh" label="Refresh simple-ba spaces & windows when an application window is closed"
99 yabai -m signal --add event=space_changed action="curl http://localhost:7776/yabai/spaces/refresh && curl http://localhost:7776/yabai/windows/refresh" label="Refresh simple-bar spaces & windows on space change"
100 yabai -m signal --add event=display_changed action="curl http://localhost:7776/yabai/spaces/refresh && curl http://localhost:7776/yabai/windows/refresh" label="Refresh simple-bar spaces & windows on display focus change"
101 yabai -m signal --add event=window_title_changed action="curl http://localhost:7776/yabai/spaces/refresh && curl http://localhost:7776/yabai/windows/refresh" label="Refresh simple-bar spaces & windows when current window title changes"
102 yabai -m signal --add event=space_destroyed action="curl http://localhost:7776/yabai/spaces/refresh && curl http://localhost:7776/yabai/windows/refresh" label="Refresh simple-bar spaces & windows on space removal"
103 yabai -m signal --add event=space_created action="curl http://localhost:7776/yabai/spaces/refresh && curl http://localhost:7776/yabai/windows/refresh" label="Refresh simple-bar spaces & windows on space creation"
104 yabai -m signal --add event=application_activated action="curl http://localhost:7776/yabai/spaces/refresh && curl http://localhost:7776/yabai/windows/refresh" label="Refresh simple-bar spaces & windows when application is activated"
105 yabai -m signal --add event=display_added action="curl http://localhost:7776/yabai/displays/refresh" label="Refresh simple-bar displays when a new dispay is added"
106 yabai -m signal --add event=display_removed action="curl http://localhost:7776/yabai/displays/refresh" label="Refresh simple-bar displays when a dispay is removed"
107 yabai -m signal --add event=display_moved action="curl http://localhost:7776/yabai/displays/refresh" label="Refresh simple-bar displays when a dispay is moved"
108 '';
109 };
110
111 # Configure JankyBorders
112 services.jankyborders = {
113 enable = true;
114 style = "round";
115 width = 6.0;
116 hidpi = true;
117 ax_focus = true;
118 active_color = "gradient(top_left=0xee33ccff,bottom_right=0xee00ff99)";
119 inactive_color = "0xaa595959";
120 };
121
122 # Install the /etc/nix/flake-registry.json file we made above
123 environment.etc."nix/flake-registry.json".source = pinnedNixpkgs;
124
125 # Install RyanCA Root
126 security.pki.certificateFiles = [
127 ../../files/CACerts/RyanCA.crt
128 ];
129
130 # Virby linux builder
131 services.virby = {
132 enable = true;
133 cores = 4;
134 diskSize = "50GiB";
135 onDemand = {
136 enable = true;
137 ttl = 30;
138 };
139 rosetta = true;
140 };
141
142 nix = {
143 enable = true;
144 settings = {
145 flake-registry = "/etc/nix/flake-registry.json";
146 extra-substituters = [
147 "https://virby-nix-darwin.cachix.org"
148 ];
149 extra-trusted-public-keys = [
150 "virby-nix-darwin.cachix.org-1:z9GiEZeBU5bEeoDQjyfHPMGPBaIQJOOvYOOjGMKIlLo="
151 ];
152 "extra-experimental-features" = [ "nix-command" "flakes" ];
153 };
154 };
155
156 # Determines the nix-darwin release compatibility
157 system.stateVersion = 6;
158
159 # System profile programs
160 programs = {
161 zsh.enable = true;
162 };
163
164 # Install homebrew itself
165 nix-homebrew = {
166 enable = true;
167 enableRosetta = true;
168 user = "${username}";
169 mutableTaps = false;
170 taps = {
171 "homebrew/homebrew-core" = inputs.homebrew-core;
172 "homebrew/homebrew-cask" = inputs.homebrew-cask;
173 } // thirdPartyTaps;
174 trust.taps = builtins.attrNames thirdPartyTaps;
175 };
176
177 # Install homebrew casks/apps
178 homebrew = {
179 enable = true;
180
181 onActivation = {
182 cleanup = "zap";
183 };
184
185 global.brewfile = true;
186
187 taps = builtins.attrNames config.nix-homebrew.taps;
188
189 brews = [ ];
190
191 casks = [
192 "utm"
193 "ghostty"
194 "zen"
195 "ungoogled-chromium"
196 "tailscale-app"
197 "netbird-ui"
198 "ubersicht"
199 "hammerspoon"
200 ];
201 };
202
203 # Keyboard shortcuts using skhd
204 services.skhd = {
205 enable = true;
206 skhdConfig = ''
207 alt - d : osascript -e 'tell application "System Events" to key code 49 using {command down}'
208 alt - return : osascript -e 'tell application "Ghostty"' -e 'new window' -e 'activate' -e 'end tell'
209
210 shift + alt - q : ${pkgs.yabai}/bin/yabai -m window --close
211
212 alt - up : ${pkgs.yabai}/bin/yabai -m window --focus north || ${pkgs.yabai}/bin/yabai -m display --focus north
213 shift + alt - up : ${pkgs.yabai}/bin/yabai -m window --swap north || ${pkgs.yabai}/bin/yabai -m window --display north
214 alt - down : ${pkgs.yabai}/bin/yabai -m window --focus south || ${pkgs.yabai}/bin/yabai -m display --focus south
215 shift + alt - down : ${pkgs.yabai}/bin/yabai -m window --swap south || ${pkgs.yabai}/bin/yabai -m window --display south
216 alt - right : ${pkgs.yabai}/bin/yabai -m window --focus east || ${pkgs.yabai}/bin/yabai -m display --focus east
217 shift + alt - right : ${pkgs.yabai}/bin/yabai -m window --swap east || ${pkgs.yabai}/bin/yabai -m window --display east
218 alt - left : ${pkgs.yabai}/bin/yabai -m window --focus west || ${pkgs.yabai}/bin/yabai -m display --focus west
219 shift + alt - left: ${pkgs.yabai}/bin/yabai -m window --swap west || ${pkgs.yabai}/bin/yabai -m window --display west
220
221 shift + alt - space: ${pkgs.yabai}/bin/yabai -m window --toggle float
222
223 shift + alt - return: ${pkgs.yabai}/bin/yabai -m window --toggle sticky
224
225 alt - f : ${pkgs.yabai}/bin/yabai -m window --toggle zoom-fullscreen
226
227 shift + alt - f: ${pkgs.yabai}/bin/yabai -m window --toggle native-fullscreen
228
229 shift + alt - 1 : ${pkgs.yabai}/bin/yabai -m window --space 1
230 shift + alt - 2 : ${pkgs.yabai}/bin/yabai -m window --space 2
231 shift + alt - 3 : ${pkgs.yabai}/bin/yabai -m window --space 3
232 shift + alt - 4 : ${pkgs.yabai}/bin/yabai -m window --space 4
233 shift + alt - 5 : ${pkgs.yabai}/bin/yabai -m window --space 5
234 shift + alt - 6 : ${pkgs.yabai}/bin/yabai -m window --space 6
235 shift + alt - 7 : ${pkgs.yabai}/bin/yabai -m window --space 7
236 shift + alt - 8 : ${pkgs.yabai}/bin/yabai -m window --space 8
237 shift + alt - 9 : ${pkgs.yabai}/bin/yabai -m window --space 9
238 '';
239 };
240
241 # System configuration
242 time.timeZone = "America/New_York";
243
244 power.sleep = {
245 display = 10;
246 computer = 30;
247 };
248
249 system.defaults = {
250 WindowManager = {
251 EnableTilingOptionAccelerator = false;
252 };
253 NSGlobalDomain = {
254 # 24 hour time
255 AppleICUForce24HourTime = true;
256
257 # Dark Mode
258 AppleInterfaceStyle = "Dark";
259
260 # Key repeat rate
261 KeyRepeat = 2;
262 InitialKeyRepeat = 35;
263
264 # Swap F1-12 to be default
265 "com.apple.keyboard.fnState" = true;
266
267 # Disable Keyboard bullcrap
268 NSAutomaticCapitalizationEnabled = false;
269 NSAutomaticDashSubstitutionEnabled = false;
270 NSAutomaticPeriodSubstitutionEnabled = false;
271 NSAutomaticQuoteSubstitutionEnabled = false;
272 NSAutomaticSpellingCorrectionEnabled = false;
273 ApplePressAndHoldEnabled = false;
274 };
275
276 # screensaver/power settings
277 screensaver = {
278 askForPassword = true;
279 askForPasswordDelay = 0;
280 };
281
282 # Control center stuff
283 controlcenter = {
284 BatteryShowPercentage = true;
285 Bluetooth = true;
286 };
287
288 # Clock settings
289 menuExtraClock = {
290 Show24Hour = true;
291 ShowDate = 1; # Always
292 ShowDayOfWeek = true;
293 ShowSeconds = true;
294 };
295
296 # Screen capture settings
297 screencapture = {
298 target = "clipboard";
299 type = "png";
300 };
301
302 # finder good settings
303 finder = {
304 AppleShowAllExtensions = true;
305 AppleShowAllFiles = true;
306 ShowPathbar = true;
307 FXEnableExtensionChangeWarning = false;
308 _FXShowPosixPathInTitle = true;
309 NewWindowTarget = "Home";
310 ShowExternalHardDrivesOnDesktop = false;
311 ShowHardDrivesOnDesktop = false;
312 ShowMountedServersOnDesktop = false;
313 ShowRemovableMediaOnDesktop = false;
314 ShowStatusBar = true;
315 };
316
317 spaces = {
318 "spans-displays" = false; # independent spaces per display
319 };
320
321 # Login Window Settings
322 loginwindow = {
323 GuestEnabled = false;
324 DisableConsoleAccess = true;
325 };
326
327 # dock settings
328 dock = {
329 magnification = true;
330 largesize = 96;
331 tilesize = 32;
332 minimize-to-application = false;
333 orientation = "bottom";
334 autohide = true;
335 mru-spaces = false; # Disable auto-rearrange spaces
336 persistent-apps = [
337 { app = "/Applications/Zen.app"; }
338 #{ app = "/System/Applications/Launchpad.app"; }
339 { app = "/System/Applications/Messages.app"; }
340 { app = "/System/Applications/Facetime.app"; }
341 { app = "/System/Applications/Calendar.app"; }
342 { app = "/System/Applications/App Store.app"; }
343 { app = "/System/Applications/System Settings.app"; }
344 { app = "/Applications/Ghostty.app"; }
345 { app = "/Applications/UTM.app"; }
346 ];
347 persistent-others = [
348 { folder = { path = "/Users/${username}/Downloads"; showas = "grid"; arrangement = "date-created"; }; }
349 { folder = { path = "/Users/${username}/Applications"; showas = "grid"; arrangement = "name"; }; }
350 ];
351 show-recents = false;
352 };
353
354 # Custom preferences
355 CustomUserPreferences = {
356 NSGlobalDomain = {
357 # Always show menu bar
358 AppleMenuBarVisibleInFullscreen = true;
359
360 # Hide the menubar by default
361 "_HIHideMenuBar" = true;
362
363 # Option + L lock
364 NSUserKeyEquivalents = {
365 "Lock Screen" = "~l";
366 };
367 };
368
369 "com.apple.desktopservices" = {
370 DSDontWriteNetworkStores = true;
371 DSDontWriteUSBStores = true;
372 };
373
374 "com.apple.WindowManager" = {
375 EnableStandardClickToShowDesktop = false;
376 StandardHideDesktopIcons = false;
377 };
378
379 "com.apple.screensaver" = {
380 askForPassword = true;
381 askForPasswordDelay = 2;
382 };
383
384 "com.apple.AdLib" = {
385 allowApplePersonalizedAdvertising = false;
386 };
387
388 "com.apple.Accessibility" = {
389 ReduceMotionEnabled = 1;
390 };
391
392 "com.apple.symbolichotkeys" = {
393 AppleSymbolicHotKeys = manualHotkeys // spaceHotkeys;
394 };
395 };
396 universalaccess.reduceMotion = true;
397 };
398
399 # Post-Activation scripts
400 system.activationScripts.postActivation.text = ''
401 echo "Configuring NTP servers..."
402 systemsetup -setnetworktimeserver pool.ntp.org > /dev/null 2>&1 || true
403 systemsetup -setusingnetworktime on > /dev/null 2>&1 || true
404
405 ryancasum="$(${pkgs.openssl}/bin/openssl x509 -in "${../../files/CACerts/RyanCA.crt}" -noout -fingerprint -sha1 | sed 's/.*=//; s/://g')"
406 if ! /usr/bin/security find-certificate -a -Z "/Library/Keychains/System.keychain" | tr -d ':' | grep -iq "$ryancasum"; then
407 echo "Installing RyanCA Certificate..."
408 /usr/bin/security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain ${../../files/CACerts/RyanCA.crt}
409 fi
410
411 echo "Reloading Preferences DB..."
412 sudo -iu ${username} /System/Library/PrivateFrameworks/SystemAdministration.framework/Resources/activateSettings -u
413
414 echo "Setting default browser"
415 ${pkgs.defaultbrowser}/bin/defaultbrowser ${defaultBrowser}
416
417 echo "Adding Keyboard brightness controls to Control Center..."
418 sudo -iu ${username} defaults -currentHost write com.apple.controlcenter KeyboardBrightness -int 25
419
420 # this is fragile so it goes at the bottom
421 echo "Reloading skhd..."
422 sudo -iu ${username} ${pkgs.skhd}/bin/skhd -r
423
424 # Notes if we are running for the first time and writes a message for actions that may need to be done on macOS or linux
425 MARK="/opt/.nix-complete"
426 if [ ! -f "$MARK" ]; then
427 echo "o0o0o0o0o0o MacOS Initial Deploy Notes o0o0o0o0o0o"
428 echo "--------------------------------------------------"
429 echo "The following actions must be taken since they are not configurable by Nix. This must be done only ONCE."
430 echo ""
431 echo "1. Create 9 spaces."
432 echo "2. Set keyboard autofill settings"
433 echo "--------------------------------------------------"
434 fi
435 touch "$MARK"
436 '';
437
438}