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

targets/darwin: add more options for configuring macOS #1753

Merged
merged 5 commits into from
Feb 3, 2021
Merged
Show file tree
Hide file tree
Changes from 4 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
23 changes: 23 additions & 0 deletions modules/misc/news.nix
Original file line number Diff line number Diff line change
Expand Up @@ -1822,6 +1822,29 @@ in
A new module is available: 'services.playerctld'.
'';
}

{
time = "2021-01-28T15:07:34+00:00";
condition = hostPlatform.isDarwin;
message = ''
New options are available for 'targets.darwin':

- targets.darwin.defaults

This adds options for configuring macOS through the defaults(1)
system.

- targets.darwin.keybindings

This adds options for configuring the default keybindings for macOS
text fields.

- targets.darwin.search

This adds options for configuring the default search engine for
macOS.
'';
}
];
};
}
2 changes: 1 addition & 1 deletion modules/modules.nix
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ let
(loadModule ./services/xscreensaver.nix { })
(loadModule ./services/xsuspender.nix { condition = hostPlatform.isLinux; })
(loadModule ./systemd.nix { })
(loadModule ./targets/darwin.nix { condition = hostPlatform.isDarwin; })
(loadModule ./targets/darwin { condition = hostPlatform.isDarwin; })
berbiche marked this conversation as resolved.
Show resolved Hide resolved
(loadModule ./targets/generic-linux.nix { condition = hostPlatform.isLinux; })
(loadModule ./xcursor.nix { })
(loadModule ./xresources.nix { })
Expand Down
51 changes: 51 additions & 0 deletions modules/targets/darwin/default.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
{ config, lib, pkgs, ... }:

with lib;

let
inherit (pkgs.stdenv.hostPlatform) isDarwin;
berbiche marked this conversation as resolved.
Show resolved Hide resolved
inherit (lib.strings) escapeShellArg;
berbiche marked this conversation as resolved.
Show resolved Hide resolved

cfg = config.targets.darwin;

toDefaultsFile = domain: attrs:
pkgs.writeText "${domain}.plist"
(lib.generators.toPlist { } (filterAttrs (n: v: v != null) attrs));

toActivationCmd = domain: attrs:
"$DRY_RUN_CMD defaults import ${escapeShellArg domain} ${
toDefaultsFile domain attrs
}";

activationCmds = mapAttrsToList toActivationCmd cfg.defaults;
in {
imports = [ ./keybindings.nix ./linkapps.nix ./search.nix ];

options.targets.darwin.defaults = mkOption {
type = types.submodule ./options.nix;
default = { };
example = {
"com.apple.desktopservices" = {
DSDontWriteNetworkStores = true;
DSDontWriteUSBStores = true;
};
};
description = ''
Set macOS user defaults. Values set to <literal>null</literal> are
ignored.

<warning>
<para>
Some settings might require a re-login to take effect.
</para>
</warning>
'';
};

config = mkIf (cfg.defaults != { }) {
home.activation.setDarwinDefaults = hm.dag.entryAfter [ "writeBoundary" ] ''
$VERBOSE_ECHO "Configuring macOS user defaults"
${concatStringsSep "\n" activationCmds}
'';
};
}
43 changes: 43 additions & 0 deletions modules/targets/darwin/keybindings.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
{ config, lib, pkgs, ... }:

with lib;

let
inherit (pkgs.stdenv.hostPlatform) isDarwin;
berbiche marked this conversation as resolved.
Show resolved Hide resolved
cfg = config.targets.darwin;
homeDir = config.home.homeDirectory;
confFile = pkgs.writeText "DefaultKeybinding.dict"
(lib.generators.toPlist { } cfg.keybindings);
in {
options.targets.darwin.keybindings = mkOption {
type = with types; attrsOf anything;
default = { };
example = {
"^u" = "deleteToBeginningOfLine:";
"^w" = "deleteWordBackward:";
};
description = ''
This will configure the default keybindings for text fields in macOS
applications. See
<link xlink:href="https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/EventOverview/TextDefaultsBindings/TextDefaultsBindings.html">Apple's documentation</link>
for more details.

<warning>
<para>
Existing keybinding configuration will be wiped when using this
option.
</para>
</warning>
'';
};

config = mkIf (cfg.keybindings != { }) {
# NOTE: just copy the files because symlinks won't be recognized by macOS
home.activation.setCocoaKeybindings =
hm.dag.entryAfter [ "writeBoundary" ] ''
$VERBOSE_ECHO "Configuring keybindings for the Cocoa Text System"
$DRY_RUN_CMD install -Dm644 $VERBOSE_ARG \
"${confFile}" "${homeDir}/Library/KeyBindings/DefaultKeyBinding.dict"
'';
};
}
File renamed without changes.
182 changes: 182 additions & 0 deletions modules/targets/darwin/options.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
{ config, lib, ... }:

with lib;

let
mkOption = args:
berbiche marked this conversation as resolved.
Show resolved Hide resolved
lib.mkOption (args // {
type = types.nullOr args.type;
default = null;
});

mkEnableOption = name:
berbiche marked this conversation as resolved.
Show resolved Hide resolved
lib.mkOption {
type = with types; nullOr bool;
default = null;
example = true;
description = "Whether to enable ${name}.";
};

safari = config."com.apple.Safari";
in {
freeformType = with types; attrsOf (attrsOf anything);

options = {
NSGlobalDomain = {
AppleLanguages = mkOption {
type = with types; listOf str;
example = [ "en" ];
description = "Sets the language to use in the preferred order.";
};

AppleLocale = mkOption {
type = types.str;
example = "en_US";
description = "Configures the user locale.";
};

AppleMeasurementUnits = mkOption {
type = types.enum [ "Centimeters" "Inches" ];
example = "Centimeters";
description = "Sets the measurement unit.";
};

AppleTemperatureUnit = mkOption {
type = types.enum [ "Celsius" "Fahrenheit" ];
example = "Celsius";
description = "Sets the temperature unit.";
};

AppleMetricUnits = mkEnableOption "the metric system";

NSAutomaticCapitalizationEnabled =
mkEnableOption "automatic captilization";

NSAutomaticDashSubstitutionEnabled = mkEnableOption "smart dashes";

NSAutomaticPeriodSubstitutionEnabled =
mkEnableOption "period with double space";

NSAutomaticQuoteSubstitutionEnabled = mkEnableOption "smart quotes";

NSAutomaticSpellingCorrectionEnabled =
mkEnableOption "spelling correction";
};

"com.apple.desktopservices" = {
DSDontWriteNetworkStores = mkOption {
type = types.bool;
example = false;
description = ''
Disable use of <filename>.DS_Store</filename> files on network shares.
See <link xlink:href="https://support.apple.com/en-us/HT208209">the
official article</link> for more info.
'';
};
DSDontWriteUSBStores = mkOption {
type = types.bool;
example = false;
description = ''
Disable use of <filename>.DS_Store</filename> files on thumb drives.
'';
};
};

"com.apple.dock" = {
tilesize = mkOption {
type = types.int;
example = 64;
description = "Sets the size of the dock.";
};
size-immutable = mkEnableOption "locking of the dock size";
expose-group-apps =
mkEnableOption "grouping of windows by application in Mission Control";
};

"com.apple.menuextra.battery".ShowPercent = mkOption {
type = types.enum [ "YES" "NO" ];
example = "NO";
description = "Whether to show battery percentage in the menu bar.";
};

"com.apple.Safari" = {
AutoOpenSafeDownloads = mkEnableOption "opening of downloaded files";
AutoFillPasswords = mkEnableOption "autofill of usernames and passwords";
AutoFillCreditCardData = mkEnableOption "autofill of credit card numbers";
IncludeDevelopMenu = mkEnableOption ''"Develop" menu in the menu bar'';
ShowOverlayStatusBar = mkEnableOption "status bar";

WebKitDeveloperExtrasEnabledPreferenceKey = mkOption {
type = types.bool;
description = ''
Configures the web inspector.

<warning>
<para>
Instead of setting this option directly, set
<option>IncludeDevelopMenu</option> instead.
</para>
</warning>
'';
};
"com.apple.Safari.ContentPageGroupIdentifier.WebKit2DeveloperExtrasEnabled" =
mkOption {
type = types.bool;
description = ''
Configures the web inspector.

<warning>
<para>
Instead of setting this option directly, set
<option>IncludeDevelopMenu</option> instead.
</para>
</warning>
'';
};
};

"com.googlecode.iterm2" = {
AddNewTabAtEndOfTabs =
mkEnableOption "placement of new tabs at the end of the tab bar";

AlternateMouseScroll =
mkEnableOption "arrow keys when scrolling in alternate screen mode";

CopySelection = mkEnableOption "copy to clipboard upon selecting text";

OpenTmuxWindowsIn = mkOption {
type = types.int;
example = 2;
description = ''
Configures how to restore tmux windows when attaching to a session.

<variablelist><title>Possible Values</title>
<varlistentry>
<term><literal>0</literal></term>
<listitem><para>Native windows</para></listitem>
</varlistentry>
<varlistentry>
<term><literal>1</literal></term>
<listitem><para>Native tabs in a new window</para></listitem>
</varlistentry>
<varlistentry>
<term><literal>2</literal></term>
<listitem><para>Tabs in the attaching window</para></listitem>
</varlistentry>
</variablelist>
'';
};

ExperimentalKeyHandling =
mkEnableOption "experimental key handling for AquaSKK compatibility";
};
};

config = {
"com.apple.Safari" = mkIf (safari.IncludeDevelopMenu == true) {
berbiche marked this conversation as resolved.
Show resolved Hide resolved
WebKitDeveloperExtrasEnabledPreferenceKey = true;
"com.apple.Safari.ContentPageGroupIdentifier.WebKit2DeveloperExtrasEnabled" =
true;
};
};
}
34 changes: 34 additions & 0 deletions modules/targets/darwin/search.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{ config, lib, pkgs, ... }:

with lib;

let
inherit (pkgs.stdenv.hostPlatform) isDarwin;
berbiche marked this conversation as resolved.
Show resolved Hide resolved
cfg = config.targets.darwin;
searchEngines = {
Bing = "com.bing.www";
DuckDuckGo = "com.duckduckgo";
Ecosia = "org.ecosia.www";
Google = "com.google.www";
Yahoo = "com.yahoo.www";
};
berbiche marked this conversation as resolved.
Show resolved Hide resolved
searchId = getAttr cfg.search searchEngines;
in {
options.targets.darwin.search = mkOption {
type = with types; nullOr (enum (attrNames searchEngines));
default = null;
description = "Default search engine.";
};

config = mkIf (cfg.search != null) {
targets.darwin.defaults = {
NSGlobalDomain.NSPreferredWebServices = {
NSWebServicesProviderWebSearch = {
NSDefaultDisplayName = cfg.search;
NSProviderIdentifier = searchId;
};
};
"com.apple.Safari".SearchProviderIdentifier = searchId;
};
};
}