- Enable programs.aerospace to ensure config generation - Disable normalizations for pure i3-style tree management - Update layout keybindings to match i3+sway: - cmd-w: accordion-horizontal (tabbed) - cmd-s: accordion-vertical (stacking) - cmd-e: tiles layout with orientation toggle - Replace direct resize bindings with cmd-r resize mode - Add resize mode with hjkl directional controls
220 lines
7.4 KiB
Nix
220 lines
7.4 KiB
Nix
{ config, lib, pkgs, ... }:
|
|
|
|
with lib;
|
|
|
|
let
|
|
cfg = config.home.roles.aerospace;
|
|
in
|
|
{
|
|
options.home.roles.aerospace = {
|
|
enable = mkEnableOption "AeroSpace tiling window manager for macOS";
|
|
|
|
leader = mkOption {
|
|
type = types.str;
|
|
default = "cmd";
|
|
description = "Leader key for aerospace shortcuts (e.g., 'cmd', 'ctrl', 'alt')";
|
|
example = "ctrl";
|
|
};
|
|
|
|
launchd.enable = mkOption {
|
|
type = types.bool;
|
|
default = true;
|
|
description = "Whether to enable launchd agent for auto-starting aerospace";
|
|
};
|
|
|
|
userSettings = mkOption {
|
|
type = types.attrs;
|
|
default = {};
|
|
description = ''
|
|
Additional aerospace configuration settings to merge with defaults.
|
|
Use this to override or extend the default configuration on a per-machine basis.
|
|
'';
|
|
example = literalExpression ''
|
|
{
|
|
mode.main.binding."''${leader}-custom" = "custom-command";
|
|
}
|
|
'';
|
|
};
|
|
|
|
autoraise = {
|
|
enable = mkOption {
|
|
type = types.bool;
|
|
default = true;
|
|
description = "Whether to enable autoraise (auto-focus window on hover)";
|
|
};
|
|
|
|
pollMillis = mkOption {
|
|
type = types.int;
|
|
default = 50;
|
|
description = "Polling interval in milliseconds";
|
|
};
|
|
|
|
delay = mkOption {
|
|
type = types.int;
|
|
default = 2;
|
|
description = "Delay before raising window";
|
|
};
|
|
|
|
focusDelay = mkOption {
|
|
type = types.int;
|
|
default = 2;
|
|
description = "Delay before focusing window";
|
|
};
|
|
};
|
|
};
|
|
|
|
config = mkIf cfg.enable {
|
|
# Only apply on Darwin systems
|
|
assertions = [
|
|
{
|
|
assertion = pkgs.stdenv.isDarwin;
|
|
message = "Aerospace role is only supported on macOS (Darwin) systems";
|
|
}
|
|
];
|
|
|
|
# Install aerospace package and autoraise if enabled
|
|
home.packages = [ pkgs.aerospace ]
|
|
++ optionals cfg.autoraise.enable [ pkgs.autoraise ];
|
|
|
|
# Enable and configure aerospace
|
|
programs.aerospace.enable = true;
|
|
programs.aerospace.userSettings = mkMerge [
|
|
# Default configuration with leader key substitution
|
|
{
|
|
# Disable normalizations for i3-like behavior
|
|
enable-normalization-flatten-containers = false;
|
|
enable-normalization-opposite-orientation-for-nested-containers = false;
|
|
|
|
mode.main.binding = {
|
|
"${cfg.leader}-w" = "layout accordion horizontal"; # tabbed
|
|
"${cfg.leader}-s" = "layout accordion vertical"; # stacking
|
|
"${cfg.leader}-e" = "layout tiles horizontal vertical"; # tiles, toggles orientation
|
|
"${cfg.leader}-shift-q" = "close";
|
|
"${cfg.leader}-shift-f" = "fullscreen";
|
|
"${cfg.leader}-h" = "focus left";
|
|
"${cfg.leader}-j" = "focus down";
|
|
"${cfg.leader}-k" = "focus up";
|
|
"${cfg.leader}-l" = "focus right";
|
|
"${cfg.leader}-shift-h" = "move left";
|
|
"${cfg.leader}-shift-j" = "move down";
|
|
"${cfg.leader}-shift-k" = "move up";
|
|
"${cfg.leader}-shift-l" = "move right";
|
|
"${cfg.leader}-r" = "mode resize";
|
|
"${cfg.leader}-1" = "workspace 1";
|
|
"${cfg.leader}-2" = "workspace 2";
|
|
"${cfg.leader}-3" = "workspace 3";
|
|
"${cfg.leader}-4" = "workspace 4";
|
|
"${cfg.leader}-5" = "workspace 5";
|
|
"${cfg.leader}-6" = "workspace 6";
|
|
"${cfg.leader}-7" = "workspace 7";
|
|
"${cfg.leader}-8" = "workspace 8";
|
|
"${cfg.leader}-9" = "workspace 9";
|
|
"${cfg.leader}-0" = "workspace 10";
|
|
"${cfg.leader}-shift-1" = "move-node-to-workspace 1";
|
|
"${cfg.leader}-shift-2" = "move-node-to-workspace 2";
|
|
"${cfg.leader}-shift-3" = "move-node-to-workspace 3";
|
|
"${cfg.leader}-shift-4" = "move-node-to-workspace 4";
|
|
"${cfg.leader}-shift-5" = "move-node-to-workspace 5";
|
|
"${cfg.leader}-shift-6" = "move-node-to-workspace 6";
|
|
"${cfg.leader}-shift-7" = "move-node-to-workspace 7";
|
|
"${cfg.leader}-shift-8" = "move-node-to-workspace 8";
|
|
"${cfg.leader}-shift-9" = "move-node-to-workspace 9";
|
|
"${cfg.leader}-shift-0" = "move-node-to-workspace 10";
|
|
"${cfg.leader}-tab" = "workspace-back-and-forth";
|
|
"${cfg.leader}-shift-tab" = "move-workspace-to-monitor --wrap-around next";
|
|
|
|
"${cfg.leader}-enter" = ''
|
|
exec-and-forget osascript <<'APPLESCRIPT'
|
|
tell application "Ghostty"
|
|
activate
|
|
tell application "System Events"
|
|
keystroke "n" using {command down}
|
|
end tell
|
|
end tell
|
|
APPLESCRIPT
|
|
'';
|
|
|
|
"${cfg.leader}-shift-enter" = ''
|
|
exec-and-forget osascript <<'APPLESCRIPT'
|
|
tell application "Google Chrome"
|
|
set newWindow to make new window
|
|
activate
|
|
tell newWindow to set index to 1
|
|
end tell
|
|
APPLESCRIPT
|
|
'';
|
|
|
|
"${cfg.leader}-shift-e" = "exec-and-forget zsh --login -c \"emacsclient -c -n\"";
|
|
|
|
# Service mode: Deliberate aerospace window management
|
|
"${cfg.leader}-i" = "mode service";
|
|
|
|
# Passthrough mode: Temporarily disable aerospace to use macOS shortcuts
|
|
"${cfg.leader}-p" = "mode passthrough";
|
|
};
|
|
|
|
# Resize mode: For window resizing operations
|
|
mode.resize.binding = {
|
|
h = "resize width -50";
|
|
j = "resize height +50";
|
|
k = "resize height -50";
|
|
l = "resize width +50";
|
|
|
|
minus = "resize smart -50";
|
|
equal = "resize smart +50";
|
|
|
|
esc = "mode main";
|
|
enter = "mode main";
|
|
};
|
|
|
|
# Service mode: For deliberate aerospace window management operations
|
|
mode.service.binding = {
|
|
esc = ["reload-config" "mode main"];
|
|
r = ["flatten-workspace-tree" "mode main"]; # reset layout
|
|
f = ["layout floating tiling" "mode main"]; # Toggle between floating and tiling layout
|
|
backspace = ["close-all-windows-but-current" "mode main"];
|
|
|
|
"${cfg.leader}-shift-h" = ["join-with left" "mode main"];
|
|
"${cfg.leader}-shift-j" = ["join-with down" "mode main"];
|
|
"${cfg.leader}-shift-k" = ["join-with up" "mode main"];
|
|
"${cfg.leader}-shift-l" = ["join-with right" "mode main"];
|
|
};
|
|
|
|
# Passthrough mode: All shortcuts pass through to macOS
|
|
mode.passthrough.binding = {
|
|
esc = "mode main";
|
|
"${cfg.leader}-p" = "mode main";
|
|
};
|
|
}
|
|
cfg.userSettings
|
|
];
|
|
|
|
# Launchd agent for auto-starting aerospace
|
|
launchd.agents.aerospace = mkIf cfg.launchd.enable {
|
|
enable = true;
|
|
config = {
|
|
Program = "${pkgs.aerospace}/Applications/AeroSpace.app/Contents/MacOS/AeroSpace";
|
|
RunAtLoad = true;
|
|
KeepAlive = true;
|
|
StandardOutPath = "/tmp/aerospace.log";
|
|
StandardErrorPath = "/tmp/aerospace.err.log";
|
|
};
|
|
};
|
|
|
|
# Launchd agent for autoraise
|
|
launchd.agents.autoraise = mkIf cfg.autoraise.enable {
|
|
enable = true;
|
|
config = {
|
|
ProgramArguments = [
|
|
"${pkgs.autoraise}/bin/AutoRaise"
|
|
"-pollMillis" (toString cfg.autoraise.pollMillis)
|
|
"-delay" (toString cfg.autoraise.delay)
|
|
"-focusDelay" (toString cfg.autoraise.focusDelay)
|
|
];
|
|
RunAtLoad = true;
|
|
KeepAlive = true;
|
|
};
|
|
};
|
|
};
|
|
}
|