Last active
February 22, 2025 09:39
-
-
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 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 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 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"; | |
} | |
]; | |
} |
I have modified dock.nix to add spacers and folders
{ config, pkgs, lib, ... }:
# Original source: https://gist.github.com/antifuchs/10138c4d838a63c0a05e725ccd7bccdd
with lib;
let
cfg = config.local.dock;
inherit (pkgs) stdenv dockutil;
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 = {
type = lib.mkOption {
type = str;
default = "app";
};
path = lib.mkOption {
type = str;
default = "";
};
view = lib.mkOption {
type = str;
default = "auto";
};
display = lib.mkOption {
type = str;
default = "folder";
};
section = lib.mkOption {
type = str;
default = "apps";
};
options = lib.mkOption {
type = str;
default = "";
};
};
});
readOnly = true;
};
};
config =
mkIf cfg.enable
(
let
normalize = path: if hasSuffix ".app" path then path + "/" else path;
entryURI = path: "file://" + (builtins.replaceStrings
[" " "!" "\"" "#" "$" "%" "&" "'" "(" ")"]
["%20" "%21" "%22" "%23" "%24" "%25" "%26" "%27" "%28" "%29"]
(normalize path)
);
wantURIs = concatMapStrings
(entry: "${entryURI entry.path}\n")
cfg.entries;
createEntries = concatMapStrings
(entry:
if hasSuffix "spacer" entry.type then
"${dockutil}/bin/dockutil --no-restart --add '' --type ${entry.type} --section ${entry.section}\n"
else if entry.type == "folder" then
"${dockutil}/bin/dockutil --no-restart --add '${entry.path}' --view ${entry.view} --display ${entry.display}\n"
else
"${dockutil}/bin/dockutil --no-restart --add '${entry.path}' --section ${entry.section} ${entry.options}\n"
) cfg.entries;
in
{
system.activationScripts.postUserActivation.text = ''
echo >&2 "Setting up the Dock..."
haveURIs="$(${dockutil}/bin/dockutil --list | ${pkgs.coreutils}/bin/cut -f2)"
if ! diff -wu <(echo -n "$haveURIs") <(echo -n '${wantURIs}') >&2 ; then
echo >&2 "Resetting Dock."
${dockutil}/bin/dockutil --no-restart --remove all
${createEntries}
killall Dock
else
echo >&2 "Dock setup complete."
fi
'';
}
);
}
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thought someone might find this useful. The package on nix channel, takes quite a long time to build, so instead I use the one from homebrew.