Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

aerospace: add module #6279

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions modules/lib/maintainers.nix
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,12 @@
github = "considerate";
githubId = 217918;
};
damidoug = {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be a separate commit.

Copy link
Author

@damidoug damidoug Jan 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@khaneliman the diference its for home-manager, in my case I dont use nix-darwin just the nix + home-manager. i want to keep all my apps on home-manager, so i can use the same flake file on linux, darwin etc... just installing nix+home-manager.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I saw some news modules merged with the manitainers in the same commit, for this reason i kept in the same.

Copy link
Contributor

@khaneliman khaneliman Jan 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@khaneliman the diference its for home-manager, in my case I dont use nix-darwin just the nix + home-manager. i want to keep all my apps on home-manager, so i can use the same flake file on linux, darwin etc... just installing nix+home-manager.

Again, all we are doing is explaining the reason for a comment above. No need to justify it again.

I saw some news modules merged with the manitainers in the same commit, for this reason i kept in the same.

Still is a best practice for logical commits.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is missing to approve this PR?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

split into two commits??

Copy link
Author

@damidoug damidoug Jan 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm new using git, what's the correct way to split it?

email = "[email protected]";
github = "damidoug";
githubId = 75175586;
name = "Douglas Damiano";
};
danjujan = {
name = "Jan Schmitz";
email = "[email protected]";
Expand Down
12 changes: 12 additions & 0 deletions modules/misc/news.nix
Original file line number Diff line number Diff line change
Expand Up @@ -1946,6 +1946,7 @@ in {
speed, features, or native UIs. Ghostty provides all three.
'';
}

{
time = "2025-01-04T15:00:00+00:00";
condition = hostPlatform.isLinux;
Expand All @@ -1960,6 +1961,17 @@ in {
as well as wf-shell.
'';
}

{
time = "2025-01-06T19:11:20+00:00";
condition = hostPlatform.isDarwin;
message = ''
A new module is available: 'programs.aerospace'.

AeroSpace is an i3-like tiling window manager for macOS.
See https://github.com/nikitabobko/AeroSpace for more.
'';
}
];
};
}
1 change: 1 addition & 0 deletions modules/modules.nix
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ let
./misc/xfconf.nix
./programs/abook.nix
./programs/aerc.nix
./programs/aerospace.nix
./programs/afew.nix
./programs/alacritty.nix
./programs/alot.nix
Expand Down
231 changes: 231 additions & 0 deletions modules/programs/aerospace.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,231 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.programs.aerospace;

tomlFormat = pkgs.formats.toml { };

filterAttrsRecursive = pred: set:
lib.listToAttrs (lib.concatMap (name:
let v = set.${name};
in if pred v then
[
(lib.nameValuePair name (if lib.isAttrs v then
filterAttrsRecursive pred v
else if lib.isList v then
(map (i: if lib.isAttrs i then filterAttrsRecursive pred i else i)
(lib.filter pred v))
else
v))
]
else
[ ]) (lib.attrNames set));
filterNulls = filterAttrsRecursive (v: v != null);
in {
meta.maintainers = with hm.maintainers; [ damidoug ];

options.programs.aerospace = with types; {
enable = mkEnableOption "Whether to enable AeroSpace window manager.";

package = mkPackageOption pkgs "aerospace" { };

userSettings = mkOption {
type = submodule {
freeformType = tomlFormat.type;
options = {
start-at-login = lib.mkOption {
type = bool;
default = false;
description = "Start AeroSpace at login.";
};
after-login-command = mkOption {
type = listOf str;
default = [ ];
description = ''
You can use it to add commands that run after login to macOS user session.
'start-at-login' needs to be 'true' for 'after-login-command' to work.
'';
};
after-startup-command = mkOption {
type = listOf str;
default = [ ];
description = ''
You can use it to add commands that run after AeroSpace startup.
'after-startup-command' is run after 'after-login-command'
'';
example = [ "layout tiles" ];
};
enable-normalization-flatten-containers = mkOption {
type = bool;
default = true;
description =
''Containers that have only one child are "flattened".'';
};
enable-normalization-opposite-orientation-for-nested-containers =
mkOption {
type = bool;
default = true;
description =
"Containers that nest into each other must have opposite orientations.";
};
accordion-padding = mkOption {
type = int;
default = 30;
description = "Padding between windows in an accordion container.";
};
default-root-container-layout = mkOption {
type = enum [ "tiles" "accordion" ];
default = "tiles";
description = "Default layout for the root container.";
};
default-root-container-orientation = mkOption {
type = enum [ "horizontal" "vertical" "auto" ];
default = "auto";
description = "Default orientation for the root container.";
};
on-window-detected = mkOption {
type = listOf (submodule {
options = {
"if" = mkOption {
type = submodule {
options = {
app-id = mkOption {
type = nullOr str;
default = null;
description = "The application ID to match (optional).";
};
workspace = mkOption {
type = nullOr str;
default = null;
description = "The workspace name to match (optional).";
};
window-title-regex-substring = mkOption {
type = nullOr str;
default = null;
description =
"Substring to match in the window title (optional).";
};
app-name-regex-substring = mkOption {
type = nullOr str;
default = null;
description =
"Regex substring to match the app name (optional).";
};
during-aerospace-startup = mkOption {
type = nullOr bool;
default = null;
description =
"Whether to match during aerospace startup (optional).";
};
};
};
default = { };
description = "Conditions for detecting a window.";
};
check-further-callbacks = mkOption {
type = nullOr bool;
default = null;
description =
"Whether to check further callbacks after this rule (optional).";
};
run = mkOption {
type = oneOf [ str (listOf str) ];
example = [ "move-node-to-workspace m" "resize-node" ];
description =
"Commands to execute when the conditions match (required).";
};
};
});
default = [ ];
example = [{
"if" = {
app-id = "Another.Cool.App";
workspace = "cool-workspace";
window-title-regex-substring = "Title";
app-name-regex-substring = "CoolApp";
during-aerospace-startup = false;
};
check-further-callbacks = false;
run = [ "move-node-to-workspace m" "resize-node" ];
}];
description =
"Commands to run every time a new window is detected with optional conditions.";
};
workspace-to-monitor-force-assignment = mkOption {
type = attrsOf (oneOf [ int str (listOf str) ]);
default = { };
description = ''
Map workspaces to specific monitors.
Left-hand side is the workspace name, and right-hand side is the monitor pattern.
'';
example = {
"1" = 1; # First monitor from left to right.
"2" = "main"; # Main monitor.
"3" = "secondary"; # Secondary monitor (non-main).
"4" = "built-in"; # Built-in display.
"5" =
"^built-in retina display$"; # Regex for the built-in retina display.
"6" = [ "secondary" "dell" ]; # Match first pattern in the list.
};
};
on-focus-changed = mkOption {
type = listOf str;
default = [ ];
example = [ "move-mouse monitor-lazy-center" ];
description =
"Commands to run every time focused window or workspace changes.";
};
on-focused-monitor-changed = mkOption {
type = listOf str;
default = [ "move-mouse monitor-lazy-center" ];
description = "Commands to run every time focused monitor changes.";
};
exec-on-workspace-change = mkOption {
type = listOf str;
default = [ ];
example = [
"/bin/bash"
"-c"
"sketchybar --trigger aerospace_workspace_change FOCUSED=$AEROSPACE_FOCUSED_WORKSPACE"
];
description = "Commands to run every time workspace changes.";
};
key-mapping.preset = mkOption {
type = enum [ "qwerty" "dvorak" ];
default = "qwerty";
description = "Keymapping preset.";
};
};
};
default = { };
example = literalExpression ''
{
gaps = {
outer.left = 8;
outer.bottom = 8;
outer.top = 8;
outer.right = 8;
};
mode.main.binding = {
alt-h = "focus left";
alt-j = "focus down";
alt-k = "focus up";
alt-l = "focus right";
};
}
'';
description = ''
AeroSpace configuration, see
<link xlink:href="https://nikitabobko.github.io/AeroSpace/guide#configuring-aerospace"/>
for supported values.
'';
};
};

config.home = mkIf cfg.enable {
packages = [ cfg.package ];
file.".config/aerospace/aerospace.toml".source =
tomlFormat.generate "aerospace" (filterNulls cfg.userSettings);
};

}
1 change: 1 addition & 0 deletions tests/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ in import nmtSrc {
./modules/xresources
] ++ lib.optionals isDarwin [
./modules/launchd
./modules/programs/aerospace
./modules/services/emacs-darwin
./modules/services/espanso-darwin
./modules/services/git-sync-darwin
Expand Down
27 changes: 27 additions & 0 deletions tests/modules/programs/aerospace/aerospace.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
programs.aerospace = {
enable = true;
userSettings = {
gaps = {
outer.left = 8;
outer.bottom = 8;
outer.top = 8;
outer.right = 8;
};
mode.main.binding = {
alt-h = "focus left";
alt-j = "focus down";
alt-k = "focus up";
alt-l = "focus right";
};
};
};

test.stubs.aerospace = { };

nmt.script = ''
assertFileContent home-files/.config/aerospace/aerospace.toml ${
./settings-expected.toml
}
'';
}
1 change: 1 addition & 0 deletions tests/modules/programs/aerospace/default.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{ aerospace = ./aerospace.nix; }
29 changes: 29 additions & 0 deletions tests/modules/programs/aerospace/settings-expected.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
accordion-padding = 30
after-login-command = []
after-startup-command = []
default-root-container-layout = "tiles"
default-root-container-orientation = "auto"
enable-normalization-flatten-containers = true
enable-normalization-opposite-orientation-for-nested-containers = true
exec-on-workspace-change = []
on-focus-changed = []
on-focused-monitor-changed = ["move-mouse monitor-lazy-center"]
on-window-detected = []
start-at-login = false

[gaps.outer]
bottom = 8
left = 8
right = 8
top = 8

[key-mapping]
preset = "qwerty"

[mode.main.binding]
alt-h = "focus left"
alt-j = "focus down"
alt-k = "focus up"
alt-l = "focus right"

[workspace-to-monitor-force-assignment]
Loading