diff --git a/modules/programs/zed-editor.nix b/modules/programs/zed-editor.nix index e3e4e45b0..be7ea5c0c 100644 --- a/modules/programs/zed-editor.nix +++ b/modules/programs/zed-editor.nix @@ -93,6 +93,26 @@ in ''; }; + userTasks = mkOption { + type = jsonFormat.type; + default = [ ]; + example = literalExpression '' + [ + { + label = "Format Code"; + command = "nix"; + args = [ "fmt" "$ZED_WORKTREE_ROOT" ]; + } + ] + ''; + description = '' + Configuration written to Zed's {file}`tasks.json`. + + [List of tasks](https://zed.dev/docs/tasks) that can be run from the + command palette. + ''; + }; + extensions = mkOption { type = types.listOf types.str; default = [ ]; @@ -186,6 +206,14 @@ in (jsonFormat.generate "zed-user-keymaps" cfg.userKeymaps) ); }) + (mkIf (cfg.userTasks != [ ]) { + zedTasksActivation = lib.hm.dag.entryAfter [ "linkGeneration" ] ( + impureConfigMerger "[]" + "$dynamic + $static | group_by(.label) | map(reduce .[] as $item ({}; . * $item))" + "${config.xdg.configHome}/zed/tasks.json" + (jsonFormat.generate "zed-user-tasks" cfg.userTasks) + ); + }) ]; xdg.configFile = lib.mapAttrs' ( diff --git a/tests/modules/programs/zed-editor/default.nix b/tests/modules/programs/zed-editor/default.nix index 112a1811d..93869021f 100644 --- a/tests/modules/programs/zed-editor/default.nix +++ b/tests/modules/programs/zed-editor/default.nix @@ -5,5 +5,7 @@ zed-keymap-empty = ./keymap-empty.nix; zed-settings = ./settings.nix; zed-settings-empty = ./settings-empty.nix; + zed-tasks = ./tasks.nix; + zed-tasks-empty = ./tasks-empty.nix; zed-themes = ./themes; } diff --git a/tests/modules/programs/zed-editor/tasks-empty.nix b/tests/modules/programs/zed-editor/tasks-empty.nix new file mode 100644 index 000000000..2bd21532c --- /dev/null +++ b/tests/modules/programs/zed-editor/tasks-empty.nix @@ -0,0 +1,69 @@ +{ + config, + lib, + pkgs, + ... +}: + +{ + programs.zed-editor = { + enable = true; + package = config.lib.test.mkStubPackage { }; + userTasks = [ + { + label = "Format Code"; + command = "nix"; + args = [ + "fmt" + "$ZED_WORKTREE_ROOT" + ]; + allow_concurrent_runs = false; + } + ]; + }; + + home.homeDirectory = lib.mkForce "/@TMPDIR@/hm-user"; + + nmt.script = + let + preexistingTasks = builtins.toFile "preexisting.json" ""; + + expectedContent = builtins.toFile "expected.json" '' + [ + { + "allow_concurrent_runs": false, + "args": [ + "fmt", + "$ZED_WORKTREE_ROOT" + ], + "command": "nix", + "label": "Format Code" + } + ] + ''; + + taskPath = ".config/zed/tasks.json"; + activationScript = pkgs.writeScript "activation" config.home.activation.zedTasksActivation.data; + in + '' + export HOME=$TMPDIR/hm-user + + # Simulate preexisting tasks + mkdir -p $HOME/.config/zed + cat ${preexistingTasks} > $HOME/${taskPath} + + # Run the activation script + substitute ${activationScript} $TMPDIR/activate --subst-var TMPDIR + chmod +x $TMPDIR/activate + $TMPDIR/activate + + # Validate the merged tasks + assertFileExists "$HOME/${taskPath}" + assertFileContent "$HOME/${taskPath}" "${expectedContent}" + + # Test idempotency + $TMPDIR/activate + assertFileExists "$HOME/${taskPath}" + assertFileContent "$HOME/${taskPath}" "${expectedContent}" + ''; +} diff --git a/tests/modules/programs/zed-editor/tasks.nix b/tests/modules/programs/zed-editor/tasks.nix new file mode 100644 index 000000000..b39dee22c --- /dev/null +++ b/tests/modules/programs/zed-editor/tasks.nix @@ -0,0 +1,86 @@ +{ + config, + lib, + pkgs, + ... +}: + +{ + programs.zed-editor = { + enable = true; + package = config.lib.test.mkStubPackage { }; + userTasks = [ + { + label = "Format Code"; + command = "nix"; + args = [ + "fmt" + "$ZED_WORKTREE_ROOT" + ]; + allow_concurrent_runs = false; + } + ]; + }; + + home.homeDirectory = lib.mkForce "/@TMPDIR@/hm-user"; + + nmt.script = + let + preexistingTasks = builtins.toFile "preexisting.json" '' + [ + // Label is the same + { + "label": "Format Code", + "allow_concurrent_runs": true, + }, + // Different label, created by hand + { + "label": "Compile", + "command": "make", + }, + ] + ''; + + expectedContent = builtins.toFile "expected.json" '' + [ + { + "label": "Compile", + "command": "make" + }, + { + "label": "Format Code", + "allow_concurrent_runs": false, + "args": [ + "fmt", + "$ZED_WORKTREE_ROOT" + ], + "command": "nix" + } + ] + ''; + + taskPath = ".config/zed/tasks.json"; + activationScript = pkgs.writeScript "activation" config.home.activation.zedTasksActivation.data; + in + '' + export HOME=$TMPDIR/hm-user + + # Simulate preexisting tasks + mkdir -p $HOME/.config/zed + cat ${preexistingTasks} > $HOME/${taskPath} + + # Run the activation script + substitute ${activationScript} $TMPDIR/activate --subst-var TMPDIR + chmod +x $TMPDIR/activate + $TMPDIR/activate + + # Validate the merged tasks + assertFileExists "$HOME/${taskPath}" + assertFileContent "$HOME/${taskPath}" "${expectedContent}" + + # Test idempotency + $TMPDIR/activate + assertFileExists "$HOME/${taskPath}" + assertFileContent "$HOME/${taskPath}" "${expectedContent}" + ''; +}