diff --git a/.gitignore b/.gitignore index 2b20459..2e42723 100644 --- a/.gitignore +++ b/.gitignore @@ -5,45 +5,17 @@ !docs/ !hosts/ - -!hosts/best/ -!hosts/best/cache/ -!hosts/best/garage/ -!hosts/best/grafana/ -!hosts/best/hercules/ -!hosts/best/matrix/ -!hosts/best/nextcloud/ -!hosts/best/nextcloud/*.gif - -!hosts/disk/ - -!hosts/nine/ -!hosts/nine/github2forgejo/ - -!hosts/pala/ +!hosts/**/ !lib/ !modules/ - -!modules/common/ -!modules/common/nushell/ -!modules/common/ssh/ - -!modules/darwin/ -!modules/darwin/hammerspoon/ - -!modules/linux/ -!modules/linux/hyprland/ -!modules/linux/restic/ - -!modules/acme/ -!modules/mail/ +!modules/**/ !flake.lock !*.age -!*.lua +!*.gif !*.md !*.nix !*.nu diff --git a/lib/colors.nix b/lib/colors.nix new file mode 100644 index 0000000..69c4ec5 --- /dev/null +++ b/lib/colors.nix @@ -0,0 +1,13 @@ +_: self: _: { + luminance = hex: let + r = self.substring 0 2 hex |> self.fromHexString; + g = self.substring 2 4 hex |> self.fromHexString; + b = self.substring 4 6 hex |> self.fromHexString; + in assert !self.hasPrefix "#" hex; + 0.2126 * r + + 0.7152 * g + + 0.0722 * b ; + + isDark = { base00, base07, ... }: self.luminance base00 < self.luminance base07; + isLight = theme: !self.isDark theme; +} diff --git a/lib/default.nix b/lib/default.nix index 6babaf2..452554d 100644 --- a/lib/default.nix +++ b/lib/default.nix @@ -1,6 +1,7 @@ inputs: self: super: let + colors = import ./colors.nix inputs self super; filesystem = import ./filesystem.nix inputs self super; option = import ./option.nix inputs self super; system = import ./system.nix inputs self super; values = import ./values.nix inputs self super; -in filesystem // option // system // values +in colors // filesystem // option // system // values diff --git a/modules/common/nix.nix b/modules/common/nix.nix index 874357d..bc60bb7 100644 --- a/modules/common/nix.nix +++ b/modules/common/nix.nix @@ -43,7 +43,7 @@ in { nix.settings = (import <| self + /flake.nix).nixConfig |> flip removeAttrs (optionals config.isDarwin [ "use-cgroups" ]) - |> (if config.services.nix-serve.enable then + |> (if config.isLinux && config.services.nix-serve.enable then (cfg: cfg // { extra-substituters = cfg.extra-substituters |> filter (x: match ".*cache.rgbcu.be.*" x != null); diff --git a/modules/darwin/dock.nix b/modules/darwin/dock.nix new file mode 100644 index 0000000..35bc60b --- /dev/null +++ b/modules/darwin/dock.nix @@ -0,0 +1,21 @@ +{ + system.defaults.dock = { + autohide = true; + + mouse-over-hilite-stack = true; + + show-recents = false; + mru-spaces = 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"; } + ]; + }; +} diff --git a/modules/darwin/finder.nix b/modules/darwin/finder.nix new file mode 100644 index 0000000..15f69c3 --- /dev/null +++ b/modules/darwin/finder.nix @@ -0,0 +1,35 @@ +{ + system.defaults.NSGlobalDomain = { + AppleShowAllFiles = true; + AppleShowAllExtensions = true; + + "com.apple.springing.enabled" = true; + "com.apple.springing.delay" = 0.0; + }; + + system.defaults.CustomSystemPreferences."com.apple.desktopservices" = { + DSDontWriteNetworkStores = true; + DSDontWriteUSBStores = true; + }; + + system.defaults.finder = { + AppleShowAllExtensions = true; + AppleShowAllFiles = true; + + FXEnableExtensionChangeWarning = true; + FXPreferredViewStyle = "Nlsv"; # List style. + FXRemoveOldTrashItems = true; + + _FXShowPosixPathInTitle = true; + _FXSortFoldersFirst = true; + _FXSortFoldersFirstOnDesktop = false; + + NewWindowTarget = "Home"; + + ShowExternalHardDrivesOnDesktop = true; + ShowMountedServersOnDesktop = true; + ShowPathbar = true; + ShowRemovableMediaOnDesktop = true; + ShowStatusBar = true; + }; +} diff --git a/modules/darwin/hammerspoon.nix b/modules/darwin/hammerspoon.nix new file mode 100644 index 0000000..158c0bf --- /dev/null +++ b/modules/darwin/hammerspoon.nix @@ -0,0 +1,5 @@ +{ + home-manager.sharedModules = [{ + home.file.".hammerspoon/init.lua".text = ""; + }]; +} diff --git a/modules/darwin/hammerspoon/default.nix b/modules/darwin/hammerspoon/default.nix deleted file mode 100644 index e6174c0..0000000 --- a/modules/darwin/hammerspoon/default.nix +++ /dev/null @@ -1,26 +0,0 @@ -{ pkgs, ... }: { - home-manager.sharedModules = [{ - home.file.".hammerspoon/Spoons/PaperWM.spoon" = { - recursive = true; - - source = pkgs.fetchFromGitHub { - owner = "mogenson"; - repo = "PaperWM.spoon"; - rev = "41389206e739e6f48ea59ddcfc07254226f4c93f"; - hash = "sha256-O1Pis5udvh3PUYJmO+R2Aw11/udxk3v5hf2U9SzbeqI="; - }; - }; - home.file.".hammerspoon/Spoons/Swipe.spoon" = { - recursive = true; - - source = pkgs.fetchFromGitHub { - owner = "mogenson"; - repo = "Swipe.spoon"; - rev = "c56520507d98e663ae0e1228e41cac690557d4aa"; - hash = "sha256-G0kuCrG6lz4R+LdAqNWiMXneF09pLI+xKCiagryBb5k="; - }; - }; - - home.file.".hammerspoon/init.lua".source = ./init.lua; - }]; -} diff --git a/modules/darwin/hammerspoon/init.lua b/modules/darwin/hammerspoon/init.lua deleted file mode 100644 index 61d9bfb..0000000 --- a/modules/darwin/hammerspoon/init.lua +++ /dev/null @@ -1,171 +0,0 @@ ----@type table -_G.hs = _G.hs - -PaperWM = hs.loadSpoon("PaperWM") -Swipe = hs.loadSpoon("Swipe") - -local windowResize = function(offsetWidth, offsetHeight) - local window = hs.window.focusedWindow() - if not window then return end - - local window_frame = window:frame() - local screen_frame = window:screen():frame() - - -- Adjust width - window_frame.w = window_frame.w + offsetWidth - window_frame.w = math.max(100, math.min(window_frame.w, screen_frame.w - window_frame.x)) - - -- Adjust height - window_frame.h = window_frame.h + offsetHeight - window_frame.h = math.max(100, math.min(window_frame.h, screen_frame.h - window_frame.y)) - - window:setFrame(window_frame) -end - -local windowClose = function() - local window = hs.window.focusedWindow() - - if not window then return end - - window:close() -end - -local spaceChange = function(offset) - local current_space = hs.spaces.activeSpaceOnScreen() - local spaces = hs.spaces.allSpaces()[hs.screen.mainScreen():getUUID()] - - local current_index = nil - for space_index, space in ipairs(spaces) do - if space == current_space then - current_index = space_index - break - end - end - - local next_index = current_index + offset - if next_index > #spaces then - next_index = 1 - elseif next_index <= 0 then - next_index = #spaces - end - - local next_space = spaces[next_index] - - hs.spaces.gotoSpace(next_space) -end - -do -- HOTKEYS - local super = { "cmd", "alt" } - local super_ctrl = { "cmd", "alt", "ctrl" } - local super_shift = { "cmd", "alt", "shift" } - - hs.hotkey.bind(super, "left", PaperWM.actions.focus_left) - hs.hotkey.bind(super, "down", PaperWM.actions.focus_down) - hs.hotkey.bind(super, "up", PaperWM.actions.focus_up) - hs.hotkey.bind(super, "right", PaperWM.actions.focus_right) - - hs.hotkey.bind(super, "h", PaperWM.actions.focus_left) - hs.hotkey.bind(super, "j", PaperWM.actions.focus_down) - hs.hotkey.bind(super, "k", PaperWM.actions.focus_up) - hs.hotkey.bind(super, "l", PaperWM.actions.focus_right) - - hs.hotkey.bind(super_ctrl, "left", function() windowResize(-100, 0) end) - hs.hotkey.bind(super_ctrl, "down", function() windowResize(0, 100) end) - hs.hotkey.bind(super_ctrl, "up", function() windowResize(0, -100) end) - hs.hotkey.bind(super_ctrl, "right", function() windowResize(100, 0) end) - - hs.hotkey.bind(super_ctrl, "h", function() windowResize(-100, 0) end) - hs.hotkey.bind(super_ctrl, "j", function() windowResize(0, 100) end) - hs.hotkey.bind(super_ctrl, "k", function() windowResize(0, -100) end) - hs.hotkey.bind(super_ctrl, "l", function() windowResize(100, 0) 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 - hs.hotkey.bind(super, tostring(index), PaperWM.actions["switch_space_" .. index]) - hs.hotkey.bind(super_shift, tostring(index), PaperWM.actions["move_window_" .. index]) - end - - hs.hotkey.bind(super_shift, "left", PaperWM.actions.swap_left) - hs.hotkey.bind(super_shift, "down", PaperWM.actions.swap_down) - hs.hotkey.bind(super_shift, "up", PaperWM.actions.swap_up) - hs.hotkey.bind(super_shift, "right", PaperWM.actions.swap_right) - - hs.hotkey.bind(super_shift, "h", PaperWM.actions.swap_left) - hs.hotkey.bind(super_shift, "j", PaperWM.actions.swap_down) - hs.hotkey.bind(super_shift, "k", PaperWM.actions.swap_up) - hs.hotkey.bind(super_shift, "l", PaperWM.actions.swap_right) - - hs.hotkey.bind(super, "q", windowClose) - hs.hotkey.bind(super, "c", PaperWM.actions.center_window) - hs.hotkey.bind(super_ctrl, "f", PaperWM.actions.full_width) - hs.hotkey.bind(super, "f", PaperWM.actions.toggle_floating) - - hs.hotkey.bind(super, "w", function() hs.application.launchOrFocus("Zen") end) - hs.hotkey.bind(super, "return", function() hs.application.launchOrFocus("Ghostty") end) - hs.hotkey.bind(super, "t", function() hs.application.launchOrFocus("Finder") end) - - PaperWM.swipe_fingers = 3 - PaperWM.swipe_gain = 1.7 - - PaperWM:start() -end - -do -- 3 FINGER VERTICAL SWIPE TO CHANGE SPACES - local current_id, threshold - - Swipe:start(3, function(direction, distance, id) - if id ~= current_id then - current_id = id - threshold = 0.2 -- 20% of trackpad - return - end - - if distance > threshold then - threshold = math.huge -- only trigger once per swipe - - if direction == "up" then - spaceChange(1) - elseif direction == "down" then - spaceChange(-1) - end - end - end) -end - -do -- SPACE BUTTONS - local space_buttons = {} - - local updateSpaceButtons = function() - for _, button in pairs(space_buttons) do - button:delete() - end - space_buttons = {} - - local current_space = hs.spaces.activeSpaceOnScreen() - local spaces = hs.spaces.allSpaces()[hs.screen.mainScreen():getUUID()] - - for index = #spaces, 1, -1 do - local space = spaces[index] - - local title = tostring(index) - - local attributes = space == current_space and { - color = { red = 1 } - } or {} - - local button = hs.menubar.new() - button:setTitle(hs.styledtext.new(title, attributes)) - button:setClickCallback(function() - hs.spaces.gotoSpace(space) - end) - - table.insert(space_buttons, button) - end - end - - hs.spaces.watcher.new(updateSpaceButtons):start() - - updateSpaceButtons() -end diff --git a/modules/darwin/hostname.nix b/modules/darwin/hostname.nix new file mode 100644 index 0000000..7541a08 --- /dev/null +++ b/modules/darwin/hostname.nix @@ -0,0 +1,6 @@ +{ config, ... }: { + system.defaults.smb = { + NetBIOSName = config.networking.hostName; + ServerDescription = config.networking.hostName; + }; +} diff --git a/modules/darwin/localisation.nix b/modules/darwin/localisation.nix new file mode 100644 index 0000000..b14cfb8 --- /dev/null +++ b/modules/darwin/localisation.nix @@ -0,0 +1,9 @@ +{ + system.defaults.NSGlobalDomain = { + AppleICUForce24HourTime = true; + + AppleMeasurementUnits = "Centimeters"; + AppleMetricUnits = 1; + AppleTemperatureUnit = "Celsius"; + }; +} diff --git a/modules/darwin/login.nix b/modules/darwin/login.nix new file mode 100644 index 0000000..31f6358 --- /dev/null +++ b/modules/darwin/login.nix @@ -0,0 +1,6 @@ +{ + system.defaults.loginwindow = { + DisableConsoleAccess = true; + GuestEnabled = false; + }; +} diff --git a/modules/darwin/menu.nix b/modules/darwin/menu.nix new file mode 100644 index 0000000..962a3a8 --- /dev/null +++ b/modules/darwin/menu.nix @@ -0,0 +1,9 @@ +{ + system.defaults = { + menuExtraClock.Show24Hour = true; + menuExtraClock.ShowSeconds = true; + + controlcenter.BatteryShowPercentage = true; + controlcenter.Bluetooth = true; + }; +} diff --git a/modules/darwin/paperwm.nix b/modules/darwin/paperwm.nix new file mode 100644 index 0000000..a05722b --- /dev/null +++ b/modules/darwin/paperwm.nix @@ -0,0 +1,238 @@ +{ config, lib, pkgs, ... }: let + inherit (lib) mkAfter mkIf; +in { + system.defaults.NSGlobalDomain = { + AppleInterfaceStyle = mkIf (lib.isDark config.theme) "Dark"; + + AppleScrollerPagingBehavior = true; # Jump to the spot that was pressed in the scrollbar. + AppleShowScrollBars = "WhenScrolling"; + + AppleWindowTabbingMode = "always"; # Always prefer tabs for new windows. + + NSWindowShouldDragOnGesture = true; # CMD+CTRL click to drag window. + AppleEnableMouseSwipeNavigateWithScrolls = false; + AppleEnableSwipeNavigateWithScrolls = false; + + AppleKeyboardUIMode = 3; # Full keyboard access. + ApplePressAndHoldEnabled = false; + + NSScrollAnimationEnabled = true; + NSWindowResizeTime = 0.001; + + "com.apple.keyboard.fnState" = true; # Invert Fn. + + InitialKeyRepeat = 15; + KeyRepeat = 1; + + NSAutomaticCapitalizationEnabled = false; + NSAutomaticDashSubstitutionEnabled = false; + NSAutomaticInlinePredictionEnabled = false; + NSAutomaticPeriodSubstitutionEnabled = false; + NSAutomaticQuoteSubstitutionEnabled = false; + }; + + system.defaults.CustomSystemPreferences."com.apple.Accessibility".ReduceMotionEnabled = 1; + system.defaults.universalaccess.reduceMotion = true; + + system.defaults.WindowManager = { + AppWindowGroupingBehavior = false; # Show them one at a a time. + }; + + home-manager.sharedModules = [{ + home.file.".hammerspoon/Spoons/PaperWM.spoon" = { + recursive = true; + + source = pkgs.fetchFromGitHub { + owner = "mogenson"; + repo = "PaperWM.spoon"; + rev = "41389206e739e6f48ea59ddcfc07254226f4c93f"; + hash = "sha256-O1Pis5udvh3PUYJmO+R2Aw11/udxk3v5hf2U9SzbeqI="; + }; + }; + + home.file.".hammerspoon/Spoons/Swipe.spoon" = { + recursive = true; + + source = pkgs.fetchFromGitHub { + owner = "mogenson"; + repo = "Swipe.spoon"; + rev = "c56520507d98e663ae0e1228e41cac690557d4aa"; + hash = "sha256-G0kuCrG6lz4R+LdAqNWiMXneF09pLI+xKCiagryBb5k="; + }; + }; + + home.file.".hammerspoon/init.lua".text = mkAfter /* lua */ '' + ---@type table + _G.hs = _G.hs + + PaperWM = hs.loadSpoon("PaperWM") + Swipe = hs.loadSpoon("Swipe") + + local windowResize = function(offsetWidth, offsetHeight) + local window = hs.window.focusedWindow() + if not window then return end + + local window_frame = window:frame() + local screen_frame = window:screen():frame() + + -- Adjust width + window_frame.w = window_frame.w + offsetWidth + window_frame.w = math.max(100, math.min(window_frame.w, screen_frame.w - window_frame.x)) + + -- Adjust height + window_frame.h = window_frame.h + offsetHeight + window_frame.h = math.max(100, math.min(window_frame.h, screen_frame.h - window_frame.y)) + + window:setFrame(window_frame) + end + + local windowClose = function() + local window = hs.window.focusedWindow() + + if not window then return end + + window:close() + end + + local spaceChange = function(offset) + local current_space = hs.spaces.activeSpaceOnScreen() + local spaces = hs.spaces.allSpaces()[hs.screen.mainScreen():getUUID()] + + local current_index = nil + for space_index, space in ipairs(spaces) do + if space == current_space then + current_index = space_index + break + end + end + + local next_index = current_index + offset + if next_index > #spaces then + next_index = 1 + elseif next_index <= 0 then + next_index = #spaces + end + + local next_space = spaces[next_index] + + hs.spaces.gotoSpace(next_space) + end + + do -- HOTKEYS + local super = { "cmd", "ctrl" } + local super_alt = { "cmd", "ctrl", "alt" } + local super_shift = { "cmd", "ctrl", "shift" } + + hs.hotkey.bind(super, "left", PaperWM.actions.focus_left) + hs.hotkey.bind(super, "down", PaperWM.actions.focus_down) + hs.hotkey.bind(super, "up", PaperWM.actions.focus_up) + hs.hotkey.bind(super, "right", PaperWM.actions.focus_right) + + hs.hotkey.bind(super, "h", PaperWM.actions.focus_left) + hs.hotkey.bind(super, "j", PaperWM.actions.focus_down) + hs.hotkey.bind(super, "k", PaperWM.actions.focus_up) + hs.hotkey.bind(super, "l", PaperWM.actions.focus_right) + + hs.hotkey.bind(super_alt, "left", function() windowResize(-100, 0) end) + hs.hotkey.bind(super_alt, "down", function() windowResize(0, 100) end) + hs.hotkey.bind(super_alt, "up", function() windowResize(0, -100) end) + hs.hotkey.bind(super_alt, "right", function() windowResize(100, 0) end) + + hs.hotkey.bind(super_alt, "h", function() windowResize(-100, 0) end) + hs.hotkey.bind(super_alt, "j", function() windowResize(0, 100) end) + hs.hotkey.bind(super_alt, "k", function() windowResize(0, -100) end) + hs.hotkey.bind(super_alt, "l", function() windowResize(100, 0) 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 + hs.hotkey.bind(super, tostring(index), PaperWM.actions["switch_space_" .. index]) + hs.hotkey.bind(super_shift, tostring(index), PaperWM.actions["move_window_" .. index]) + end + + hs.hotkey.bind(super_shift, "left", PaperWM.actions.swap_left) + hs.hotkey.bind(super_shift, "down", PaperWM.actions.swap_down) + hs.hotkey.bind(super_shift, "up", PaperWM.actions.swap_up) + hs.hotkey.bind(super_shift, "right", PaperWM.actions.swap_right) + + hs.hotkey.bind(super_shift, "h", PaperWM.actions.swap_left) + hs.hotkey.bind(super_shift, "j", PaperWM.actions.swap_down) + hs.hotkey.bind(super_shift, "k", PaperWM.actions.swap_up) + hs.hotkey.bind(super_shift, "l", PaperWM.actions.swap_right) + + hs.hotkey.bind(super, "q", windowClose) + hs.hotkey.bind(super, "c", PaperWM.actions.center_window) + hs.hotkey.bind(super_alt, "f", PaperWM.actions.full_width) + hs.hotkey.bind(super, "f", PaperWM.actions.toggle_floating) + + hs.hotkey.bind(super, "w", function() hs.application.launchOrFocus("Zen") end) + hs.hotkey.bind(super, "return", function() hs.application.launchOrFocus("Ghostty") end) + hs.hotkey.bind(super, "t", function() hs.application.launchOrFocus("Finder") end) + + PaperWM.swipe_fingers = 3 + PaperWM.swipe_gain = 1.7 + + PaperWM:start() + end + + do -- 3 FINGER VERTICAL SWIPE TO CHANGE SPACES + local current_id, threshold + + Swipe:start(3, function(direction, distance, id) + if id ~= current_id then + current_id = id + threshold = 0.2 -- 20% of trackpad + return + end + + if distance > threshold then + threshold = math.huge -- only trigger once per swipe + + if direction == "up" then + spaceChange(1) + elseif direction == "down" then + spaceChange(-1) + end + end + end) + end + + do -- SPACE BUTTONS + local space_buttons = {} + + local updateSpaceButtons = function() + for _, button in pairs(space_buttons) do + button:delete() + end + space_buttons = {} + + local current_space = hs.spaces.activeSpaceOnScreen() + local spaces = hs.spaces.allSpaces()[hs.screen.mainScreen():getUUID()] + + for index = #spaces, 1, -1 do + local space = spaces[index] + + local title = tostring(index) + + local attributes = space == current_space and { + color = { red = 1 } + } or {} + + local button = hs.menubar.new() + button:setTitle(hs.styledtext.new(title, attributes)) + button:setClickCallback(function() + hs.spaces.gotoSpace(space) + end) + + table.insert(space_buttons, button) + end + end + + hs.spaces.watcher.new(updateSpaceButtons):start() + + updateSpaceButtons() + end + ''; + }]; +} diff --git a/modules/darwin/unshittify.nix b/modules/darwin/unshittify.nix new file mode 100644 index 0000000..385477c --- /dev/null +++ b/modules/darwin/unshittify.nix @@ -0,0 +1,16 @@ +{ + system.defaults.NSGlobalDomain = { + NSDocumentSaveNewDocumentsToCloud = false; + }; + + system.defaults.LaunchServices = { + LSQuarantine = false; + }; + + system.defaults.CustomSystemPreferences."com.apple.AdLib" = { + allowApplePersonalizedAdvertising = false; + allowIdentifierForAdvertising = false; + forceLimitAdTracking = true; + personalizedAdsMigrated = false; + }; +} diff --git a/modules/darwin/update.nix b/modules/darwin/update.nix new file mode 100644 index 0000000..10e1737 --- /dev/null +++ b/modules/darwin/update.nix @@ -0,0 +1,3 @@ +{ + system.defaults.SoftwareUpdate.AutomaticallyInstallMacOSUpdates = true; +}