Last active
July 3, 2025 08:52
-
-
Save antifuchs/10138c4d838a63c0a05e725ccd7bccdd to your computer and use it in GitHub Desktop.
A nix module that arranges the macOS dock the way you want it. Note: It won't allow you to manually re-arrange the items on it; the dock gets reset everytime you log in.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ config, pkgs, lib, ... }: | |
with lib; | |
let | |
cfg = config.local.dock; | |
stdenv = pkgs.stdenv; | |
in | |
{ | |
options = { | |
local.dock.enable = mkOption { | |
description = "Enable dock"; | |
default = stdenv.isDarwin; | |
example = false; | |
}; | |
local.dock.entries = mkOption | |
{ | |
description = "Entries on the Dock"; | |
type = with types; listOf (submodule { | |
options = { | |
path = lib.mkOption { type = str; }; | |
section = lib.mkOption { | |
type = str; | |
default = "apps"; | |
}; | |
options = lib.mkOption { | |
type = str; | |
default = ""; | |
}; | |
}; | |
}); | |
readOnly = true; | |
}; | |
}; | |
config = | |
mkIf (cfg.enable) | |
( | |
let | |
dockutil = (import ./dockutil.nix); | |
du = "env PYTHONIOENCODING=utf-8 ${dockutil}/bin/dockutil"; | |
normalize = path: if hasSuffix ".app" path then path + "/" else path; | |
entryURI = path: "file://" + (builtins.replaceStrings | |
# TODO: This is entirely too naive and works only with the bundles that I have seen on my system so far: | |
[" " "!" "\"" "#" "$" "%" "&" "'" "(" ")"] | |
["%20" "%21" "%22" "%23" "%24" "%25" "%26" "%27" "%28" "%29"] | |
(normalize path) | |
); | |
wantURIs = concatMapStrings | |
(entry: "${entryURI entry.path}\n") | |
cfg.entries; | |
createEntries = concatMapStrings | |
(entry: "${du} --no-restart --add '${entry.path}' --section ${entry.section} ${entry.options}\n") | |
cfg.entries; | |
in | |
{ | |
system.activationScripts.postUserActivation.text = '' | |
echo >&2 "Setting up persistent dock items..." | |
haveURIs="$(${du} --list | ${pkgs.coreutils}/bin/cut -f2)" | |
if ! diff -wu <(echo -n "$haveURIs") <(echo -n '${wantURIs}') >&2 ; then | |
echo >&2 "Resetting Dock." | |
${du} --no-restart --remove all | |
${createEntries} | |
killall Dock | |
else | |
echo >&2 "Dock is how we want it." | |
fi | |
''; | |
} | |
); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
with (import <nixpkgs> { }); | |
derivation { | |
name = "dockutil-2.0.5"; | |
builder = "${bash}/bin/bash"; | |
args = [ | |
"-xeuc" | |
'' | |
${unzip}/bin/unzip $src | |
${coreutils}/bin/mkdir -p $out/bin | |
${coreutils}/bin/mv dockutil-2.0.5/scripts/dockutil $out/bin/dockutil | |
'' | |
]; | |
src = fetchurl { | |
url = "https://github.com/kcrawford/dockutil/archive/2.0.5.zip"; | |
sha256 = "0b18awdaimf3gc4dhxx6lpivvx4li7j8kci648ssz39fwmbknlam"; | |
}; | |
system = builtins.currentSystem; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ config, pkgs, ... }: | |
{ | |
local.dock.entries = [ | |
{ path = "${pkgs.emacs}/Applications/Emacs.app/"; } | |
{ path = "/Applications/Mailplane.app"; } | |
{ path = "/Applications/IRCCloud.app/"; } | |
{ path = "/Applications/Google Chrome.app/"; } | |
{ path = "/Applications/iPulse.app/"; } | |
{ path = "/Applications/Dash.app/"; } | |
{ path = "/System/Applications/Messages.app/"; } | |
{ path = "/Applications/iTerm.app/"; } | |
{ path = "/System/Applications/Music.app/"; } | |
{ path = "/System/Applications/Home.app/"; } | |
# Folders: | |
{ | |
path = "/Users/asf/Downloads/"; | |
section = "others"; | |
options = "--sort dateadded --view grid --display folder"; | |
} | |
{ | |
path = "/Users/asf/Mess/Mess/"; | |
section = "others"; | |
options = "--sort name --view grid --display folder"; | |
} | |
]; | |
} |
local.dock.username = mkOption { description = "Username to apply the dock settings to"; type = types.str; }; };
That's a good catch - you can use
default = config.system.primaryUser;
there, so you don't have to set that manually.
Good point! Updated my Gist 👍
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
That's a good catch - you can use
default = config.system.primaryUser;
there, so you don't have to set that manually.