1
0
Fork 0
mirror of https://github.com/nix-community/home-manager.git synced 2025-11-08 11:36:05 +01:00
home-manager/modules/programs/zed-editor.nix
Pierre-Yves Landuré 1f34c2c855 zed-editor: options to generate debug.json
Add `mutableUserDebug` and `userDebug` options to generate `debug.json` file.
The options are heavily inspired by `mutableUserTasks` and `userTasks` options implementation.

Closes #8091
2025-11-03 20:24:19 -06:00

318 lines
9.8 KiB
Nix

{
config,
lib,
pkgs,
...
}:
let
inherit (lib)
literalExpression
mkIf
mkMerge
mkOption
types
;
cfg = config.programs.zed-editor;
jsonFormat = pkgs.formats.json { };
json5 = pkgs.python3Packages.toPythonApplication pkgs.python3Packages.json5;
impureConfigMerger = empty: jqOperation: path: staticSettings: ''
mkdir -p $(dirname ${lib.escapeShellArg path})
if [ ! -e ${lib.escapeShellArg path} ]; then
# No file? Create it
echo ${lib.escapeShellArg empty} > ${lib.escapeShellArg path}
fi
dynamic="$(${lib.getExe json5} --as-json ${lib.escapeShellArg path} 2>/dev/null || echo ${lib.escapeShellArg empty})"
static="$(cat ${lib.escapeShellArg staticSettings})"
config="$(${lib.getExe pkgs.jq} -n ${lib.escapeShellArg jqOperation} --argjson dynamic "$dynamic" --argjson static "$static")"
printf '%s\n' "$config" > ${lib.escapeShellArg path}
unset config
'';
mergedSettings =
cfg.userSettings
// (lib.optionalAttrs (builtins.length cfg.extensions > 0) {
# this part by @cmacrae
auto_install_extensions = lib.genAttrs cfg.extensions (_: true);
});
in
{
meta.maintainers = [ lib.hm.maintainers.libewa ];
options = {
# TODO: add vscode option parity (installing extensions, configuring
# keybinds with nix etc.)
programs.zed-editor = {
enable = lib.mkEnableOption "Zed, the high performance, multiplayer code editor from the creators of Atom and Tree-sitter";
package = lib.mkPackageOption pkgs "zed-editor" { nullable = true; };
extraPackages = mkOption {
type = with types; listOf package;
default = [ ];
example = literalExpression "[ pkgs.nixd ]";
description = "Extra packages available to Zed.";
};
mutableUserSettings = mkOption {
type = types.bool;
default = true;
example = false;
description = ''
Whether user settings (settings.json) can be updated by zed.
'';
};
mutableUserKeymaps = mkOption {
type = types.bool;
default = true;
example = false;
description = ''
Whether user keymaps (keymap.json) can be updated by zed.
'';
};
mutableUserTasks = mkOption {
type = types.bool;
default = true;
example = false;
description = ''
Whether user tasks (tasks.json) can be updated by zed.
'';
};
mutableUserDebug = mkOption {
type = types.bool;
default = true;
example = false;
description = ''
Whether user debug configurations (debug.json) can be updated by zed.
'';
};
userSettings = mkOption {
type = jsonFormat.type;
default = { };
example = literalExpression ''
{
features = {
copilot = false;
};
telemetry = {
metrics = false;
};
vim_mode = false;
ui_font_size = 16;
buffer_font_size = 16;
}
'';
description = ''
Configuration written to Zed's {file}`settings.json`.
'';
};
userKeymaps = mkOption {
type = jsonFormat.type;
default = [ ];
example = literalExpression ''
[
{
context = "Workspace";
bindings = {
ctrl-shift-t = "workspace::NewTerminal";
};
};
]
'';
description = ''
Configuration written to Zed's {file}`keymap.json`.
'';
};
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.
'';
};
userDebug = mkOption {
type = jsonFormat.type;
default = [ ];
example = literalExpression ''
[
{
label = "Go (Delve)";
adapter = "Delve";
program = "$ZED_FILE";
request = "launch";
mode = "debug";
}
]
'';
description = ''
Configuration written to Zed's {file}`debug.json`.
Global debug configurations for Zed's [Debugger](https://zed.dev/docs/debugger).
'';
};
extensions = mkOption {
type = types.listOf types.str;
default = [ ];
example = literalExpression ''
[ "swift" "nix" "xy-zed" ]
'';
description = ''
A list of the extensions Zed should install on startup.
Use the name of a repository in the [extension list](https://github.com/zed-industries/extensions/tree/main/extensions).
'';
};
installRemoteServer = mkOption {
type = types.bool;
default = false;
example = true;
description = ''
Whether to symlink the Zed's remote server binary to the expected
location. This allows remotely connecting to this system from a
distant Zed client.
For more information, consult the
["Remote Server" section](https://wiki.nixos.org/wiki/Zed#Remote_Server)
in the wiki.
'';
};
themes = mkOption {
description = ''
Each theme is written to
{file}`$XDG_CONFIG_HOME/zed/themes/theme-name.json`
where the name of each attribute is the theme-name
See <https://zed.dev/docs/extensions/themes> for the structure of a
Zed theme
'';
type = types.attrsOf (
types.oneOf [
jsonFormat.type
types.path
types.lines
]
);
default = { };
};
};
};
config = mkIf cfg.enable {
home.packages = mkIf (cfg.package != null) (
if cfg.extraPackages != [ ] then
[
(pkgs.symlinkJoin {
name = "${lib.getName cfg.package}-wrapped-${lib.getVersion cfg.package}";
paths = [ cfg.package ];
preferLocalBuild = true;
nativeBuildInputs = [ pkgs.makeWrapper ];
postBuild = ''
wrapProgram $out/bin/zeditor \
--suffix PATH : ${lib.makeBinPath cfg.extraPackages}
'';
})
]
else
[ cfg.package ]
);
home.file = mkIf (cfg.installRemoteServer && (cfg.package ? remote_server)) (
let
inherit (cfg.package) version remote_server;
binaryName = "zed-remote-server-stable-${version}";
in
{
".zed_server/${binaryName}".source = lib.getExe' remote_server binaryName;
}
);
home.activation = mkMerge [
(mkIf (cfg.mutableUserSettings && mergedSettings != { }) {
zedSettingsActivation = lib.hm.dag.entryAfter [ "linkGeneration" ] (
impureConfigMerger "{}" "$dynamic * $static" "${config.xdg.configHome}/zed/settings.json" (
jsonFormat.generate "zed-user-settings" mergedSettings
)
);
})
(mkIf (cfg.mutableUserKeymaps && cfg.userKeymaps != [ ]) {
zedKeymapActivation = lib.hm.dag.entryAfter [ "linkGeneration" ] (
impureConfigMerger "[]"
"$dynamic + $static | group_by(.context) | map(reduce .[] as $item ({}; . * $item))"
"${config.xdg.configHome}/zed/keymap.json"
(jsonFormat.generate "zed-user-keymaps" cfg.userKeymaps)
);
})
(mkIf (cfg.mutableUserTasks && 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)
);
})
(mkIf (cfg.mutableUserDebug && cfg.userDebug != [ ]) {
zedDebugActivation = lib.hm.dag.entryAfter [ "linkGeneration" ] (
impureConfigMerger "[]"
"$dynamic + $static | group_by(.label) | map(reduce .[] as $item ({}; . * $item))"
"${config.xdg.configHome}/zed/debug.json"
(jsonFormat.generate "zed-user-debug" cfg.userDebug)
);
})
];
xdg.configFile = mkMerge [
(lib.mapAttrs' (
n: v:
lib.nameValuePair "zed/themes/${n}.json" {
source =
if lib.isString v then
pkgs.writeText "zed-theme-${n}" v
else if builtins.isPath v || lib.isStorePath v then
v
else
jsonFormat.generate "zed-theme-${n}" v;
}
) cfg.themes)
(mkIf (!cfg.mutableUserSettings && mergedSettings != { }) {
"zed/settings.json".source = jsonFormat.generate "zed-user-settings" mergedSettings;
})
(mkIf (!cfg.mutableUserKeymaps && cfg.userKeymaps != { }) {
"zed/keymap.json".source = jsonFormat.generate "zed-user-keymaps" cfg.userKeymaps;
})
(mkIf (!cfg.mutableUserTasks && cfg.userTasks != [ ]) {
"zed/tasks.json".source = jsonFormat.generate "zed-user-tasks" cfg.userTasks;
})
(mkIf (!cfg.mutableUserDebug && cfg.userDebug != [ ]) {
"zed/debug.json".source = jsonFormat.generate "zed-user-debug" cfg.userDebug;
})
];
assertions = [
{
assertion = cfg.extraPackages != [ ] -> cfg.package != null;
message = "{option}programs.zed-editor.extraPackages requires non null {option}programs.zed-editor.package";
}
];
};
}