diff --git a/modules/common/home-manager.nix b/modules/common/home-manager.nix index 4824466..3eca196 100644 --- a/modules/common/home-manager.nix +++ b/modules/common/home-manager.nix @@ -1,12 +1,6 @@ -{ lib, ... }: let - inherit (lib) enabled; -in { +{ home-manager = { useGlobalPkgs = true; useUserPackages = true; - - sharedModules = [{ - xdg = enabled {}; - }]; }; } diff --git a/modules/common/shell/0_nushell.nix b/modules/common/shell/0_nushell.nix index 95b3822..0226b61 100644 --- a/modules/common/shell/0_nushell.nix +++ b/modules/common/shell/0_nushell.nix @@ -1,25 +1,66 @@ { config, lib, pkgs, ... }: let - inherit (lib) attrNames attrValues const enabled filterAttrs mapAttrs readFile replaceStrings; + inherit (lib) attrNames attrValues concatStringsSep const enabled filter filterAttrs flatten foldl' head last listToAttrs mapAttrs mapAttrsToList match nameValuePair readFile replaceStrings splitString; package = pkgs.nushell; in { + shells."0" = package; + home-manager.sharedModules = [(homeArgs: let config' = homeArgs.config; - environmentVariables = config.environment.variables - |> mapAttrs (const <| replaceStrings (attrNames config'.variablesMap) (attrValues config'.variablesMap)) + environmentVariables = let + variablesMap = { + HOME = config'.home.homeDirectory; + USER = config'.home.username; + + XDG_CACHE_HOME = config'.xdg.cacheHome; + XDG_CONFIG_HOME = config'.xdg.configHome; + XDG_DATA_HOME = config'.xdg.dataHome; + XDG_STATE_HOME = config'.xdg.stateHome; + } + |> mapAttrsToList (name: value: [ + { name = "\$${name}"; inherit value; } + { name = "\${${name}}"; inherit value; } + ]) + |> flatten + |> listToAttrs; + + environmentVariables = config.environment.variables; + + homeVariables = config'.home.sessionVariables; + + homeVariablesExtra = pkgs.runCommand "home-variables-extra.env" {} '' + bash -ic ' + ${variablesMap + |> mapAttrsToList (name: value: "export ${name}='${value}'") + |> concatStringsSep "\n"} + + alias export=echo + source ${config'.home.sessionVariablesPackage}/etc/profile.d/hm-session-vars.sh + ' > $out + '' + |> readFile + |> splitString "\n" + |> filter (s: s != "") + |> map (match "([^=]+)=(.*)") + |> map (keyAndValue: nameValuePair (head keyAndValue) (last keyAndValue)) + |> foldl' (x: y: x // y) {}; + + homeSearchVariables = config'.home.sessionSearchVariables + |> mapAttrs (const <| concatStringsSep ":"); + in environmentVariables + // homeVariables + // homeVariablesExtra + // homeSearchVariables + |> mapAttrs (const <| replaceStrings (attrNames variablesMap) (attrValues variablesMap)) |> filterAttrs (name: const <| name != "TERM"); in { - shells."0" = package; - programs.nushell = enabled { inherit package; + inherit (config.environment) shellAliases; inherit environmentVariables; - shellAliases = config.environment.shellAliases - |> filterAttrs (_: value: value != null); - configFile.text = readFile ./0_nushell.nu; }; })]; diff --git a/modules/common/shell/default.nix b/modules/common/shell/default.nix index 9f68be9..a22401e 100644 --- a/modules/common/shell/default.nix +++ b/modules/common/shell/default.nix @@ -1,78 +1,16 @@ -{ config, lib, pkgs, ... }: let - inherit (lib) attrsToList catAttrs concatStringsSep const filter flatten foldl' getAttr getExe head last listToAttrs mapAttrs mapAttrsToList match mkConst mkIf mkValue nameValuePair readFile sortOn splitString toInt unique; +{ config, lib, ... }: let + inherit (lib) attrsToList catAttrs mkConst mkIf mkValue sortOn toInt; in { - environment.shells = config.home-manager.users - |> mapAttrsToList (const <| getAttr "shellsByPriority") - |> flatten - |> unique; + options.shells = mkValue {}; - home-manager.sharedModules = [ + options.shellsByPriority = mkConst (config.shells + |> attrsToList + |> sortOn ({ name, ... }: toInt name) + |> catAttrs "value"); - (homeArgs: let - config' = homeArgs.config; - in { - options.shells = mkValue {}; - - options.shellsByPriority = mkConst (config'.shells - |> attrsToList - |> sortOn ({ name, ... }: toInt name) - |> catAttrs "value"); - - options.variablesMap = mkConst ({ - HOME = config'.home.homeDirectory; - USER = config'.home.username; - - XDG_CACHE_HOME = config'.xdg.cacheHome; - XDG_CONFIG_HOME = config'.xdg.configHome; - XDG_DATA_HOME = config'.xdg.dataHome; - XDG_STATE_HOME = config'.xdg.stateHome; - } - |> mapAttrsToList (name: value: [ - { name = "\$${name}"; inherit value; } - { name = "\${${name}}"; inherit value; } - ]) - |> flatten - |> listToAttrs); - }) - - (mkIf config.isDarwin (homeArgs: let - config' = homeArgs.config; - - homeSessionVariables = let - homeSessionVariables = config'.home.sessionVariables; - - homeSessionVariablesExtra = pkgs.runCommand "home-variables-extra.env" {} '' - bash -ic ' - ${config'.variablesMap - |> mapAttrsToList (name: value: "export ${name}='${value}'") - |> concatStringsSep "\n"} - - alias export=echo - source ${config'.home.sessionVariablesPackage}/etc/profile.d/hm-session-vars.sh - ' > $out - '' - |> readFile - |> splitString "\n" - |> filter (s: s != "") - |> map (match "([^=]+)=(.*)") - |> map (keyAndValue: nameValuePair (head keyAndValue) (last keyAndValue)) - |> foldl' (x: y: x // y) {}; - - homeSessionSearchVariables = config'.home.sessionSearchVariables - |> mapAttrs (const <| concatStringsSep ":"); - in homeSessionVariables - // homeSessionVariablesExtra - // homeSessionSearchVariables; - in { - home.file.".zshrc".text = mkIf config.isDarwin /* zsh */ '' - ${homeSessionVariables - |> mapAttrsToList (name: value: "export ${name}='${value}'") - |> concatStringsSep "\n"} - SHELL='${getExe <| head config'.shellsByPriority}' exec "$SHELL" - ''; - })) - - ]; + config = mkIf config.isDarwin { + environment.shells = config.shellsByPriority; + }; # More at modules/linux/shell/default.nix. # diff --git a/modules/common/shell/shadow-xcode.nix b/modules/common/shell/shadow-xcode.nix deleted file mode 100644 index e66f932..0000000 --- a/modules/common/shell/shadow-xcode.nix +++ /dev/null @@ -1,78 +0,0 @@ -{ config, lib, pkgs, ... }: let - inherit (lib) getExe mkAfter mkIf; -in { - home-manager.sharedModules = mkIf config.isDarwin [(homeArgs: let - config' = homeArgs.config; - lib' = homeArgs.lib; - - inherit (lib'.hm.dag) entryAfter; - - # Replace with the command that has been triggering - # the "install developer tools" popup. - # - # Set by default to "SplitForks" because who even uses that? - originalTrigger = "/usr/bin/SplitForks"; - originalTriggerLiteral = ''"${originalTrigger}"''; - - # Where the symbolic links to `/usr/bin/false` will - # be created in to shadow all popup-triggering binaries. - # - # Place this in your $env.PATH right before /usr/bin - # to never get the "install developer tools" popup ever again: - # - # ```nu - # let usr_bin_index = $env.PATH - # | enumerate - # | where item == /usr/bin - # | get 0.index - # - # $env.PATH = $env.PATH | insert $usr_bin_index $shadow_path - # ``` - # - # Do NOT set this to a path that you use for other things, - # it will get deleted if it exists to only have the shadowers. - shadowPath = "${config'.home.homeDirectory}/.local/shadow"; # Did you read the comment? - shadowPathLiteral = ''"${shadowPath}"''; - in { - home.activation.shadow = entryAfter [ "installPackages" "linkGeneration" ] /* bash */ '' - ${getExe pkgs.nushell} ${pkgs.writeScript "shadow-xcode.nu" '' - use std null_device - - let original_size = ls ${originalTriggerLiteral} | get 0.size - - let shadoweds = ls /usr/bin - | flatten - | where { - # All xcode-select binaries are the same size, so we can narrow down and not run weird stuff. - $in.size == $original_size and (try { - open $null_device | ^$in.name out+err>| str contains "xcode-select: note: No developer tools were found, requesting install." - } catch { - # If it exited with a nonzero code, it's probably already set up. - false - }) - } - | get name - | each { path basename } - - rm -rf ${shadowPathLiteral} - mkdir ${shadowPathLiteral} - - for shadowed in $shadoweds { - ln --symbolic /usr/bin/false (${shadowPathLiteral} | path join $shadowed) - } - ''} - ''; - - programs.nushell.configFile.text = mkAfter /* nu */ '' - do --env { - let usr_bin_index = $env.PATH - | enumerate - | where item == /usr/bin - | get 0.index; - - $env.PATH = $env.PATH - | insert $usr_bin_index ${shadowPathLiteral}; - } - ''; - })]; -} diff --git a/modules/common/ssh/default.nix b/modules/common/ssh/default.nix index a83abe4..fca23d2 100644 --- a/modules/common/ssh/default.nix +++ b/modules/common/ssh/default.nix @@ -24,14 +24,12 @@ in { mode = "444"; }; - home-manager.sharedModules = [(homeArgs: let - lib' = homeArgs.lib; - - inherit (lib'.hm.dag) entryAfter; - in { - home.activation.createControlPath = entryAfter [ "writeBoundary" ] /* bash */ '' - mkdir --parents ${controlPath} - ''; + home-manager.sharedModules = [{ + home.activation.createControlPath = { + after = [ "writeBoundary" ]; + before = []; + data = "mkdir --parents ${controlPath}"; + }; programs.ssh = enabled { controlMaster = "auto"; @@ -51,7 +49,7 @@ in { }; }; }; - })]; + }]; environment.systemPackages = mkIf config.isDesktop [ pkgs.mosh diff --git a/modules/darwin/dock.nix b/modules/darwin/dock.nix index 4acdc08..35bc60b 100644 --- a/modules/darwin/dock.nix +++ b/modules/darwin/dock.nix @@ -1,38 +1,21 @@ { system.defaults.dock = { - autohide = true; - showhidden = true; # Translucent. + autohide = true; mouse-over-hilite-stack = true; show-recents = false; mru-spaces = false; - tilesize = 48; - magnification = false; + tilesize = 48; enable-spring-load-actions-on-all-items = true; + expose-animation-duration = 0.1; + persistent-apps = [ { app = "/Applications/Zen.app"; } { app = "/Applications/Ghostty.app"; } ]; }; - - system.defaults.CustomSystemPreferences."com.apple.dock" = { - autohide-time-modifier = 0.0; - autohide-delay = 0.0; - expose-animation-duration = 0.0; - springboard-show-duration = 0.0; - springboard-hide-duration = 0.0; - springboard-page-duration = 0.0; - - # Disable hot corners. - wvous-tl-corner = 0; - wvous-tr-corner = 0; - wvous-bl-corner = 0; - wvous-br-corner = 0; - - launchanim = 0; - }; } diff --git a/modules/darwin/finder.nix b/modules/darwin/finder.nix index b97baf9..15f69c3 100644 --- a/modules/darwin/finder.nix +++ b/modules/darwin/finder.nix @@ -26,32 +26,10 @@ NewWindowTarget = "Home"; - QuitMenuItem = true; # Allow quitting of Finder application - ShowExternalHardDrivesOnDesktop = true; ShowMountedServersOnDesktop = true; ShowPathbar = true; ShowRemovableMediaOnDesktop = true; ShowStatusBar = true; }; - - system.defaults.CustomSystemPreferences."com.apple.finder" = { - DisableAllAnimations = true; - - FXArrangeGroupViewBy = "Name"; - FxDefaultSearchScope = "SCcf"; # Search in current folder by default. - - WarnOnEmptyTrash = false; - }; - - home-manager.sharedModules = [(homeArgs: let - lib' = homeArgs.lib; - - inherit (lib'.hm.dag) entryAfter; - in { - home.activation.showLibrary = entryAfter [ "writeBoundary" ] /* bash */ '' - # Unhide ~/Library. - /usr/bin/chflags nohidden ~/Library - ''; - })]; } diff --git a/modules/darwin/paperwm.nix b/modules/darwin/paperwm.nix index 13c0272..f5d0e55 100644 --- a/modules/darwin/paperwm.nix +++ b/modules/darwin/paperwm.nix @@ -1,10 +1,8 @@ { config, lib, pkgs, ... }: let - inherit (lib) mkAfter; + inherit (lib) mkAfter mkIf; in { system.defaults.NSGlobalDomain = { - _HIHideMenuBar = true; # Automatically hide/show the menu bar. - - AppleInterfaceStyle = if lib.isDark config.theme then "Dark" else null; + AppleInterfaceStyle = mkIf (lib.isDark config.theme) "Dark"; AppleScrollerPagingBehavior = true; # Jump to the spot that was pressed in the scrollbar. AppleShowScrollBars = "WhenScrolling"; @@ -14,16 +12,16 @@ in { AppleEnableSwipeNavigateWithScrolls = false; AppleWindowTabbingMode = "always"; # Always prefer tabs for new windows. - AppleKeyboardUIMode = 3; # Full keyboard access. - ApplePressAndHoldEnabled = false; # No ligatures when you press and hold a key, just repeat it. + AppleKeyboardUIMode = 3; # Full keyboard access. + ApplePressAndHoldEnabled = false; # No ligatures when you press and hold a key, just repeat it. NSScrollAnimationEnabled = true; - NSWindowResizeTime = 0.003; + NSWindowResizeTime = 0.001; "com.apple.keyboard.fnState" = false; # Don't invert Fn. - "com.apple.trackpad.scaling" = 1.5; # Faster mouse speed. + "com.apple.trackpad.scaling" = 1.5; # Faster mouse speed. - InitialKeyRepeat = 12; + InitialKeyRepeat = 15; KeyRepeat = 1; NSAutomaticCapitalizationEnabled = false; @@ -31,15 +29,8 @@ in { NSAutomaticInlinePredictionEnabled = false; NSAutomaticPeriodSubstitutionEnabled = false; NSAutomaticQuoteSubstitutionEnabled = false; - - NSNavPanelExpandedStateForSaveMode = true; # Expand save panel by default. - PMPrintingExpandedStateForPrint = true; # Expand print panel by default. - - AppleSpacesSwitchOnActivate = false; # Do not switch workspaces implicitly. }; - system.defaults.CustomSystemPreferences."com.apple.dock".workspaces-auto-swoosh = false; # Read `AppleSpacesSwitchOnActivate`. - system.defaults.CustomSystemPreferences."com.apple.AppleMultitouchTrackpad" = { TrackpadThreeFingerVertSwipeGesture = 0; # Four finger swipe up for mission control. @@ -115,7 +106,7 @@ in { window:close() end - local currentSpaceIndex = function() + local spaceChange = function(offset) local current_space = hs.spaces.activeSpaceOnScreen() local spaces = hs.spaces.allSpaces()[hs.screen.mainScreen():getUUID()] @@ -127,13 +118,6 @@ in { end end - return current_index - end - - local changeSpaceBy = function(offset) - local current_index = currentSpaceIndex() - local spaces = hs.spaces.allSpaces()[hs.screen.mainScreen():getUUID()] - local next_index = current_index + offset if next_index > #spaces then next_index = 1 @@ -141,22 +125,11 @@ in { next_index = #spaces end - if next_index == current_index then - return - end - local next_space = spaces[next_index] hs.spaces.gotoSpace(next_space) end - local gotoSpace = function(index) - local current_index = currentSpaceIndex() - local change_by = index - current_index - - changeSpaceBy(change_by) - end - do -- HOTKEYS local super = { "cmd", "ctrl" } local super_alt = { "cmd", "ctrl", "alt" } @@ -188,12 +161,12 @@ in { hs.hotkey.bind(super_alt, "f", PaperWM.actions.full_width) -- CYCLE SPACES -- SUPER[ + SHIFT FOR REVERSE] + TAB - hs.hotkey.bind(super, "tab", function() changeSpaceBy(1) end) - hs.hotkey.bind(super_shift, "tab", function() changeSpaceBy(-1) end) + hs.hotkey.bind(super, "tab", function() spaceChange(1) end) + hs.hotkey.bind(super_shift, "tab", function() spaceChange(-1) end) for index = 1, 9 do -- GO TO SPACE -- SUPER + NUMBER - hs.hotkey.bind(super, tostring(index), function() gotoSpace(index) end) + hs.hotkey.bind(super, tostring(index), PaperWM.actions["switch_space_" .. index]) -- MOVE WINDOW TO SPACE -- SUPER + SHIFT + NUMBER hs.hotkey.bind(super_shift, tostring(index), PaperWM.actions["move_window_" .. index]) @@ -244,9 +217,9 @@ in { threshold = math.huge -- only trigger once per swipe if direction == "up" then - changeSpaceBy(1) + spaceChange(1) elseif direction == "down" then - changeSpaceBy(-1) + spaceChange(-1) end end end) @@ -276,7 +249,7 @@ in { local button = hs.menubar.new() button:setTitle(hs.styledtext.new(title, attributes)) button:setClickCallback(function() - gotoSpace(space) + hs.spaces.gotoSpace(space) end) table.insert(space_buttons, button) diff --git a/modules/darwin/screencapture.nix b/modules/darwin/screencapture.nix deleted file mode 100644 index 5e169cd..0000000 --- a/modules/darwin/screencapture.nix +++ /dev/null @@ -1,3 +0,0 @@ -{ - system.defaults.screencapture.location = "~/Downloads"; -} diff --git a/modules/darwin/screensaver.nix b/modules/darwin/screensaver.nix deleted file mode 100644 index 73462b4..0000000 --- a/modules/darwin/screensaver.nix +++ /dev/null @@ -1,7 +0,0 @@ -{ - system.defaults.CustomSystemPreferences."com.apple.screensaver" = { - # Request password immediately. - askForPassword = 1; - askForPasswordDelay = 0; - }; -} diff --git a/modules/darwin/trackpad.nix b/modules/darwin/trackpad.nix deleted file mode 100644 index 6e73a8a..0000000 --- a/modules/darwin/trackpad.nix +++ /dev/null @@ -1,6 +0,0 @@ -{ - system.defaults.trackpad = { - Clicking = false; # No touch-to-click. - Dragging = false; # No tap-to-drag. - }; -} diff --git a/modules/linux/shell/default.nix b/modules/linux/shell/default.nix index 7c29478..dff21fa 100644 --- a/modules/linux/shell/default.nix +++ b/modules/linux/shell/default.nix @@ -1,20 +1,9 @@ { config, lib, pkgs, ... }: let - inherit (lib) concatStringsSep const flatten getAttr mapAttrsToList mkForce unique; + inherit (lib) concatStringsSep; in { users.defaultUserShell = pkgs.crash; - # TODO: This should be a per-user session variable. But we can't set - # a home-manager session variable because that's initialized by the - # shell itself! Lol. - environment.sessionVariables.SHELLS = config.home-manager.users - |> mapAttrsToList (const <| getAttr "shellsByPriority") - |> flatten - |> map (drv: "${drv}${drv.shellPath}") - |> unique - |> concatStringsSep ":"; - - environment.shellAliases = { - ls = mkForce null; - l = mkForce null; - }; + environment.sessionVariables.SHELLS = config.shellsByPriority + |> map (drv: "${drv}${drv.shellPath}") + |> concatStringsSep ":"; } diff --git a/rebuild.nu b/rebuild.nu index 3ac8e08..1578e88 100755 --- a/rebuild.nu +++ b/rebuild.nu @@ -17,7 +17,7 @@ def --wrapped sync [...arguments] { # Rebuild a NixOS / Darwin config. def main --wrapped [ host: string = "" # The host to build. - --remote # Whether if this is a remote host. The config will be built on this host if it is. + --remote (-r) # Whether if this is a remote host. The config will be built on this host if it is. ...arguments # The arguments to pass to `nh {os,darwin} switch` and `nix` (separated by --). ]: nothing -> nothing { let host = if ($host | is-not-empty) { @@ -34,10 +34,6 @@ def main --wrapped [ } if $remote { - ssh -tt ("root@" + $host) " - rm --recursive --force ncc - " - git ls-files | sync --files-from - ./ $"root@($host):ncc" @@ -61,7 +57,77 @@ def main --wrapped [ if (uname | get kernel-name) == "Darwin" { NH_BYPASS_ROOT_CHECK=true NH_NO_CHECKS=true nh darwin switch . ...$nh_flags -- ...$nix_flags + + if not (xcode-select --install e>| str contains "Command line tools are already installed") { + darwin-shadow-xcode-popup + } + + darwin-set-zshrc } else { NH_BYPASS_ROOT_CHECK=true NH_NO_CHECKS=true nh os switch . ...$nh_flags -- ...$nix_flags } } + +# Replace with the command that has been triggering +# the "install developer tools" popup. +# +# Set by default to "SplitForks" because who even uses that? +const original_trigger = "/usr/bin/SplitForks" + +# Where the symbolic links to `/usr/bin/false` will +# be created in to shadow all popup-triggering binaries. +# +# Place this in your $env.PATH right before /usr/bin +# to never get the "install developer tools" popup ever again: +# +# ```nu +# let usr_bin_index = $env.PATH +# | enumerate +# | where item == /usr/bin +# | get 0.index +# +# $env.PATH = $env.PATH | insert $usr_bin_index $shadow_path +# ``` +# +# Do NOT set this to a path that you use for other things, +# it will get deleted if it exists to only have the shadowers. +const shadow_path = "~/.local/shadow" | path expand # Did you read the comment? + +def darwin-shadow-xcode-popup [] { + print "shadowing xcode popup binaries..." + + let original_size = ls $original_trigger | get 0.size + + let shadoweds = ls /usr/bin + | flatten + | where { + # All xcode-select binaries are the same size, so we can narrow down and not run weird stuff. + $in.size == $original_size + } + | where { + ^$in.name e>| str contains "xcode-select: note: No developer tools were found, requesting install." + } + | get name + | each { path basename } + + rm -rf $shadow_path + mkdir $shadow_path + + for shadowed in $shadoweds { + let shadow_path = $shadow_path | path join $shadowed + + ln --symbolic /usr/bin/false $shadow_path + } +} + +def darwin-set-zshrc [] { + print "setting zshrc..." + + let nu_command = $"let usr_bin_index = $env.PATH | enumerate | where item == /usr/bin | get 0.index; +$env.PATH = $env.PATH | insert $usr_bin_index ($shadow_path | path expand); +$env.SHELL = which nu | get 0.path" | str replace --all "\n" "" + + let zshrc = $"exec nu --execute '($nu_command)'" + + $zshrc | save --force ~/.zshrc +}