Skip to content

Instantly share code, notes, and snippets.

@antifuchs
Last active September 14, 2025 13:23
Show Gist options
  • Save antifuchs/10138c4d838a63c0a05e725ccd7bccdd to your computer and use it in GitHub Desktop.
Save antifuchs/10138c4d838a63c0a05e725ccd7bccdd to your computer and use it in GitHub Desktop.

Revisions

  1. antifuchs revised this gist Sep 5, 2020. 2 changed files with 19 additions and 18 deletions.
    10 changes: 8 additions & 2 deletions dock.nix
    Original file line number Diff line number Diff line change
    @@ -17,7 +17,6 @@ in
    description = "Entries on the Dock";
    type = with types; listOf (submodule {
    options = {
    url = lib.mkOption { type = str; };
    path = lib.mkOption { type = str; };
    section = lib.mkOption {
    type = str;
    @@ -39,8 +38,15 @@ in
    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: "${entry.url}\n")
    (entry: "${entryURI entry.path}\n")
    cfg.entries;
    createEntries = concatMapStrings
    (entry: "${du} --no-restart --add '${entry.path}' --section ${entry.section} ${entry.options}\n")
    27 changes: 11 additions & 16 deletions usage_example.nix
    Original file line number Diff line number Diff line change
    @@ -1,29 +1,24 @@
    { config, pkgs, ... }:
    {
    local.dock.entries = [
    {
    url = "file://${pkgs.emacs}/Applications/Emacs.app/";
    path = "${pkgs.emacs}/Applications/Emacs.app/";
    }
    { url = "file:///Applications/Mailplane.app/"; path = "/Applications/Mailplane.app"; }
    { url = "file:///Applications/IRCCloud.app/"; path = "/Applications/IRCCloud.app/"; }
    { url = "file:///Applications/Google%20Chrome.app/"; path = "/Applications/Google Chrome.app/"; }
    { url = "file:///Applications/iPulse.app/"; path = "/Applications/iPulse.app/"; }
    { url = "file:///Applications/Dash.app/"; path = "/Applications/Dash.app/"; }
    { url = "file:///System/Applications/Messages.app/"; path = "/System/Applications/Messages.app/"; }
    { url = "file:///Applications/iTerm.app/"; path = "/Applications/iTerm.app/"; }
    { url = "file:///System/Applications/Music.app/"; path = "/System/Applications/Music.app/"; }
    { url = "file:///System/Applications/Home.app/"; path = "/System/Applications/Home.app/"; }
    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:
    {
    url = "file:///Users/asf/Downloads/";
    path = "/Users/asf/Downloads/";
    section = "others";
    options = "--sort dateadded --view grid --display folder";
    }
    {
    url = "file:///Users/asf/Mess/Mess/";
    path = "/Users/asf/Mess/Mess/";
    section = "others";
    options = "--sort name --view grid --display folder";
  2. antifuchs revised this gist Sep 5, 2020. 1 changed file with 0 additions and 1 deletion.
    1 change: 0 additions & 1 deletion dock.nix
    Original file line number Diff line number Diff line change
    @@ -15,7 +15,6 @@ in
    local.dock.entries = mkOption
    {
    description = "Entries on the Dock";
    default = [ ];
    type = with types; listOf (submodule {
    options = {
    url = lib.mkOption { type = str; };
  3. antifuchs created this gist Sep 5, 2020.
    65 changes: 65 additions & 0 deletions dock.nix
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,65 @@
    { 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";
    default = [ ];
    type = with types; listOf (submodule {
    options = {
    url = lib.mkOption { type = str; };
    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";
    wantURIs = concatMapStrings
    (entry: "${entry.url}\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
    '';
    }
    );
    }
    18 changes: 18 additions & 0 deletions dockutil.nix
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,18 @@
    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;
    }
    32 changes: 32 additions & 0 deletions usage_example.nix
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,32 @@
    { config, pkgs, ... }:
    {
    local.dock.entries = [
    {
    url = "file://${pkgs.emacs}/Applications/Emacs.app/";
    path = "${pkgs.emacs}/Applications/Emacs.app/";
    }
    { url = "file:///Applications/Mailplane.app/"; path = "/Applications/Mailplane.app"; }
    { url = "file:///Applications/IRCCloud.app/"; path = "/Applications/IRCCloud.app/"; }
    { url = "file:///Applications/Google%20Chrome.app/"; path = "/Applications/Google Chrome.app/"; }
    { url = "file:///Applications/iPulse.app/"; path = "/Applications/iPulse.app/"; }
    { url = "file:///Applications/Dash.app/"; path = "/Applications/Dash.app/"; }
    { url = "file:///System/Applications/Messages.app/"; path = "/System/Applications/Messages.app/"; }
    { url = "file:///Applications/iTerm.app/"; path = "/Applications/iTerm.app/"; }
    { url = "file:///System/Applications/Music.app/"; path = "/System/Applications/Music.app/"; }
    { url = "file:///System/Applications/Home.app/"; path = "/System/Applications/Home.app/"; }

    # Folders:
    {
    url = "file:///Users/asf/Downloads/";
    path = "/Users/asf/Downloads/";
    section = "others";
    options = "--sort dateadded --view grid --display folder";
    }
    {
    url = "file:///Users/asf/Mess/Mess/";
    path = "/Users/asf/Mess/Mess/";
    section = "others";
    options = "--sort name --view grid --display folder";
    }
    ];
    }