diff --git a/modules/system/defaults/dock.nix b/modules/system/defaults/dock.nix
index d88b6af..31d2f52 100644
--- a/modules/system/defaults/dock.nix
+++ b/modules/system/defaults/dock.nix
@@ -197,16 +197,93 @@ in {
};
system.defaults.dock.persistent-others = mkOption {
- type = types.nullOr (types.listOf (types.either types.path types.str));
+ type = let
+ folderType = types.submodule {
+ options.path = mkOption {
+ description = "Path to a folder to be added to the dock.";
+ type = types.str;
+ };
+ options.arrangement = mkOption {
+ description = "Sort order for files in folder when clicked.";
+ type = types.enum ["name" "date-added" "date-modified" "date-created" "kind"];
+ default = "name";
+ };
+ options.displayas = mkOption {
+ description = "How to display the folder before clicked. stack: Stack of file previews. folder: A folder icon";
+ type = types.enum ["stack" "folder"];
+ default = "stack";
+ };
+ options.showas = mkOption {
+ description = "Effect to show files when clicked. fan: fan-out effect, grid: box, list: list";
+ type = types.enum ["automatic" "fan" "grid" "list"];
+ default = "automatic";
+ };
+ };
+ taggedType = types.attrTag {
+ file = mkOption {
+ description = "A file to be added to the dock.";
+ type = types.str;
+ };
+ folder = mkOption {
+ description = "A folder to be added to the dock.";
+ type = types.coercedTo types.str (str: { path = str; }) folderType;
+ };
+ };
+ simpleType = types.either types.str types.path;
+ # Below to NOT break exisiting config
+ toTagged = _path: let path = builtins.toString _path; in if strings.hasInfix "." (last (splitString "/" path)) then { file = path; } else { folder = path; };
+ # toTagged = path: { folder = path; }; # or this to be consistent with persistent-apps
+ in
+ types.nullOr (types.listOf (types.coercedTo simpleType toTagged taggedType));
default = null;
- example = [ "~/Documents" "~/Downloads" ];
+ example = lib.literalExpression ''
+ [
+ ./flake.nix
+ "/Volumes"
+ { folder = "/Users/@username@/Downloads"; }
+ { folder = { path = "/Users/@username@/.emacs.d"; showas = "grid"; }; }
+ { file = "/Users/@username@/Desktop/this_is_a_file"; }
+ ]'';
description = ''
- Persistent folders in the dock.
+ Persistent files, and folders in the dock.
'';
- apply = value:
- if !(isList value)
- then value
- else map (folder: { tile-data = { file-data = { _CFURLString = "file://" + folder; _CFURLStringType = 15; }; }; tile-type = if strings.hasInfix "." (last (splitString "/" folder)) then "file-tile" else "directory-tile"; }) value;
+ apply = let
+ arrangementMap = {
+ name = 1;
+ date-added = 2;
+ date-modified = 3;
+ date-created = 4;
+ kind = 5;
+ };
+ displayasMap = {
+ stack = 0;
+ folder = 1;
+ };
+ showasMap = {
+ automatic = 0;
+ fan = 1;
+ grid = 2;
+ list = 3;
+ };
+ parseFolder = (folder:
+ builtins.mapAttrs (name: val:
+ if name == "arrangement" then arrangementMap.${val}
+ else if name == "displayas" then displayasMap.${val}
+ else if name == "showas" then showasMap.${val}
+ else val
+ ) folder
+ );
+ toTile = item: {
+ tile-data = {
+ file-data = {
+ _CFURLString = "file://" + (if item ? folder then item.folder.path else item.file);
+ _CFURLStringType = 15;
+ };
+ } // (if item ? folder then {inherit (parseFolder item.folder) arrangement displayas showas;} else {});
+ tile-type = if item ? folder then "directory-tile" else "file-tile";
+ };
+ in
+ value: if value == null then null else map toTile value;
};
system.defaults.dock.scroll-to-open = mkOption {
diff --git a/tests/fixtures/system-defaults-write/user.txt b/tests/fixtures/system-defaults-write/user.txt
index b29e19f..15153e0 100644
--- a/tests/fixtures/system-defaults-write/user.txt
+++ b/tests/fixtures/system-defaults-write/user.txt
@@ -331,13 +331,19 @@ launchctl asuser "$(id -u -- test-defaults-user)" sudo --user=test-defaults-user
tile-data
+ arrangement
+ 1
+ displayas
+ 0
file-data
_CFURLString
- file://~/Documents
+ file:///file
_CFURLStringType
15
+ showas
+ 0
tile-type
directory-tile
@@ -348,7 +354,7 @@ launchctl asuser "$(id -u -- test-defaults-user)" sudo --user=test-defaults-user
file-data
_CFURLString
- file://~/Downloads/file.txt
+ file:///file
_CFURLStringType
15
@@ -356,6 +362,60 @@ launchctl asuser "$(id -u -- test-defaults-user)" sudo --user=test-defaults-user
tile-type
file-tile
+
+ tile-data
+
+ file-data
+
+ _CFURLString
+ file:///folder.d
+ _CFURLStringType
+ 15
+
+
+ tile-type
+ file-tile
+
+
+ tile-data
+
+ arrangement
+ 5
+ displayas
+ 1
+ file-data
+
+ _CFURLString
+ file:///folder.d
+ _CFURLStringType
+ 15
+
+ showas
+ 2
+
+ tile-type
+ directory-tile
+
+
+ tile-data
+
+ arrangement
+ 1
+ displayas
+ 0
+ file-data
+
+ _CFURLString
+ file:///folder
+ _CFURLStringType
+ 15
+
+ showas
+ 0
+
+ tile-type
+ directory-tile
+
'
launchctl asuser "$(id -u -- test-defaults-user)" sudo --user=test-defaults-user -- defaults write com.apple.dock scroll-to-open '
diff --git a/tests/system-defaults-write.nix b/tests/system-defaults-write.nix
index 8773014..d704b17 100644
--- a/tests/system-defaults-write.nix
+++ b/tests/system-defaults-write.nix
@@ -80,7 +80,14 @@
{ folder = "/Applications/Utilities"; }
{ file = "/Users/example/Downloads/test.csv"; }
];
- system.defaults.dock.persistent-others = ["~/Documents" "~/Downloads/file.txt"];
+ system.defaults.dock.persistent-others = [
+ # ./. # TODO: how to test for paths while NOT being brittle?
+ "/file"
+ { file = "/file"; }
+ "/folder.d"
+ { folder = { path = "/folder.d"; arrangement="kind"; displayas="folder"; showas = "grid"; }; }
+ { folder = "/folder"; }
+ ];
system.defaults.dock.scroll-to-open = false;
system.defaults.finder.AppleShowAllFiles = true;
system.defaults.finder.ShowStatusBar = true;