1
Fork 0
mirror of https://github.com/RGBCube/NCC synced 2025-05-14 03:54:59 +00:00

feat: huge darwin overhaul

This commit is contained in:
RGBCube 2025-04-13 17:58:16 +03:00
parent 7935aa65f5
commit c4888c276b
No known key found for this signature in database
16 changed files with 367 additions and 230 deletions

34
.gitignore vendored
View file

@ -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

13
lib/colors.nix Normal file
View file

@ -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;
}

View file

@ -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

View file

@ -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);

21
modules/darwin/dock.nix Normal file
View file

@ -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"; }
];
};
}

35
modules/darwin/finder.nix Normal file
View file

@ -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;
};
}

View file

@ -0,0 +1,5 @@
{
home-manager.sharedModules = [{
home.file.".hammerspoon/init.lua".text = "";
}];
}

View file

@ -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;
}];
}

View file

@ -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

View file

@ -0,0 +1,6 @@
{ config, ... }: {
system.defaults.smb = {
NetBIOSName = config.networking.hostName;
ServerDescription = config.networking.hostName;
};
}

View file

@ -0,0 +1,9 @@
{
system.defaults.NSGlobalDomain = {
AppleICUForce24HourTime = true;
AppleMeasurementUnits = "Centimeters";
AppleMetricUnits = 1;
AppleTemperatureUnit = "Celsius";
};
}

6
modules/darwin/login.nix Normal file
View file

@ -0,0 +1,6 @@
{
system.defaults.loginwindow = {
DisableConsoleAccess = true;
GuestEnabled = false;
};
}

9
modules/darwin/menu.nix Normal file
View file

@ -0,0 +1,9 @@
{
system.defaults = {
menuExtraClock.Show24Hour = true;
menuExtraClock.ShowSeconds = true;
controlcenter.BatteryShowPercentage = true;
controlcenter.Bluetooth = true;
};
}

238
modules/darwin/paperwm.nix Normal file
View file

@ -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
'';
}];
}

View file

@ -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;
};
}

View file

@ -0,0 +1,3 @@
{
system.defaults.SoftwareUpdate.AutomaticallyInstallMacOSUpdates = true;
}