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/ghostty.nix
Martijn Boers 34fe48801d ghostty: Add systemd integration
The systemd unit already exists on the system, this gives the
option to enable it.
2025-11-04 16:56:11 -06:00

259 lines
8.2 KiB
Nix

{
config,
lib,
pkgs,
...
}:
let
cfg = config.programs.ghostty;
keyValueSettings = {
listsAsDuplicateKeys = true;
mkKeyValue = lib.generators.mkKeyValueDefault { } " = ";
};
keyValue = pkgs.formats.keyValue keyValueSettings;
in
{
meta.maintainers = with lib.maintainers; [
HeitorAugustoLN
khaneliman
];
options.programs.ghostty =
let
mkShellIntegrationOption =
option:
option
// {
description = ''
${option.description}
This ensures that shell integration works in more scenarios, such as
switching shells within Ghostty. But it is not needed to have shell
integration.
See
<https://ghostty.org/docs/features/shell-integration#manual-shell-integration-setup>
for more information.
'';
};
in
{
enable = lib.mkEnableOption "Ghostty";
package = lib.mkPackageOption pkgs "ghostty" {
nullable = true;
extraDescription = "Set programs.ghostty.package to null on platforms where ghostty is not available or marked broken";
};
settings = lib.mkOption {
inherit (keyValue) type;
default = { };
example = lib.literalExpression ''
{
theme = "catppuccin-mocha";
font-size = 10;
keybind = [
"ctrl+h=goto_split:left"
"ctrl+l=goto_split:right"
];
}
'';
description = ''
Configuration written to {file}`$XDG_CONFIG_HOME/ghostty/config`.
See <https://ghostty.org/docs/config/reference> for more information.
'';
};
themes = lib.mkOption {
type = lib.types.attrsOf keyValue.type;
default = { };
example = {
catppuccin-mocha = {
palette = [
"0=#45475a"
"1=#f38ba8"
"2=#a6e3a1"
"3=#f9e2af"
"4=#89b4fa"
"5=#f5c2e7"
"6=#94e2d5"
"7=#bac2de"
"8=#585b70"
"9=#f38ba8"
"10=#a6e3a1"
"11=#f9e2af"
"12=#89b4fa"
"13=#f5c2e7"
"14=#94e2d5"
"15=#a6adc8"
];
background = "1e1e2e";
foreground = "cdd6f4";
cursor-color = "f5e0dc";
selection-background = "353749";
selection-foreground = "cdd6f4";
};
};
description = ''
Custom themes written to {file}`$XDG_CONFIG_HOME/ghostty/themes`.
See <https://ghostty.org/docs/features/theme#authoring-a-custom-theme> for more information.
'';
};
clearDefaultKeybinds = lib.mkEnableOption "" // {
description = "Whether to clear default keybinds.";
};
installVimSyntax = lib.mkEnableOption "installation of Ghostty configuration syntax for Vim";
installBatSyntax = lib.mkEnableOption "installation of Ghostty configuration syntax for bat" // {
default = cfg.package != null;
defaultText = lib.literalMD "`true` if programs.ghostty.package is not null";
};
systemd = lib.mkOption {
type = lib.types.submodule {
options = {
enable = lib.mkEnableOption "the Ghostty systemd user service" // {
default = pkgs.stdenv.hostPlatform.isLinux;
defaultText = lib.literalMD "`true` on Linux, `false` otherwise";
};
};
};
default = { };
description = ''
Configuration for Ghostty's systemd integration.
This enables additional speed and features.
See <https://ghostty.org/docs/linux/systemd> for more information.
'';
};
enableBashIntegration = mkShellIntegrationOption (
lib.hm.shell.mkBashIntegrationOption { inherit config; }
);
enableFishIntegration = mkShellIntegrationOption (
lib.hm.shell.mkFishIntegrationOption { inherit config; }
);
enableZshIntegration = mkShellIntegrationOption (
lib.hm.shell.mkZshIntegrationOption { inherit config; }
);
};
config = lib.mkIf cfg.enable (
lib.mkMerge [
{
home.packages = lib.optionals (cfg.package != null) [ cfg.package ];
programs.ghostty.settings = lib.mkIf cfg.clearDefaultKeybinds {
keybind = lib.mkBefore [ "clear" ];
};
# MacOS also supports XDG configuration directory, so we use it for both
# Linux and macOS to reduce complexity
xdg.configFile =
let
validate =
file:
lib.mkIf (cfg.package != null)
"${lib.getExe cfg.package} +validate-config --config-file=${config.xdg.configHome}/ghostty/${file}";
in
lib.mkMerge [
{
"ghostty/config" = lib.mkIf (cfg.settings != { }) {
source = keyValue.generate "ghostty-config" cfg.settings;
onChange = validate "config";
};
}
(lib.mkIf (cfg.themes != { }) (
lib.mapAttrs' (name: value: {
name = "ghostty/themes/${name}";
value = {
source = keyValue.generate "ghostty-${name}-theme" value;
onChange = validate "themes/${name}";
};
}) cfg.themes
))
];
}
(lib.mkIf cfg.installVimSyntax {
assertions = [
{
assertion = cfg.installVimSyntax -> cfg.package != null;
message = "programs.ghostty.installVimSyntax cannot be enabled when programs.ghostty.package is null";
}
];
programs.vim.plugins = lib.optionals (cfg.package != null) [ cfg.package.vim ];
})
(lib.mkIf cfg.installBatSyntax {
assertions = [
{
assertion = cfg.installBatSyntax -> cfg.package != null;
message = "programs.ghostty.installBatSyntax cannot be enabled when programs.ghostty.package is null";
}
];
programs.bat = lib.mkIf (cfg.package != null) {
syntaxes.ghostty = {
src = cfg.package;
file =
if pkgs.stdenv.hostPlatform.isDarwin then
"Applications/Ghostty.app/Contents/Resources/bat/syntaxes/ghostty.sublime-syntax"
else
"share/bat/syntaxes/ghostty.sublime-syntax";
};
config.map-syntax = [ "${config.xdg.configHome}/ghostty/config:Ghostty Config" ];
};
})
(lib.mkIf cfg.systemd.enable {
assertions = [
{
assertion = cfg.systemd.enable -> cfg.package != null;
message = "programs.ghostty.systemd.enable cannot be true when programs.ghostty.package is null";
}
{
assertion = cfg.systemd.enable -> pkgs.stdenv.hostPlatform.isLinux;
message = "Ghostty systemd integration cannot be enabled for non-linux platforms";
}
];
xdg.configFile."systemd/user/app-com.mitchellh.ghostty.service".source =
"${cfg.package}/share/systemd/user/app-com.mitchellh.ghostty.service";
dbus.packages = [ cfg.package ];
})
(lib.mkIf cfg.enableBashIntegration {
# Make order 101 to be placed exactly after bash completions, as Ghostty
# documentation suggests sourcing the script as soon as possible
programs.bash.initExtra = lib.mkOrder 101 ''
if [[ -n "''${GHOSTTY_RESOURCES_DIR}" ]]; then
builtin source "''${GHOSTTY_RESOURCES_DIR}/shell-integration/bash/ghostty.bash"
fi
'';
})
(lib.mkIf cfg.enableFishIntegration {
programs.fish.interactiveShellInit = ''
if set -q GHOSTTY_RESOURCES_DIR
source "$GHOSTTY_RESOURCES_DIR/shell-integration/fish/vendor_conf.d/ghostty-shell-integration.fish"
end
'';
})
(lib.mkIf cfg.enableZshIntegration {
programs.zsh.initContent = ''
if [[ -n $GHOSTTY_RESOURCES_DIR ]]; then
source "$GHOSTTY_RESOURCES_DIR"/shell-integration/zsh/ghostty-integration
fi
'';
})
]
);
}