Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Backport 24.11] ghostty: add module #6285

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions modules/misc/news.nix
Original file line number Diff line number Diff line change
Expand Up @@ -1866,6 +1866,18 @@ in {
NOTE: The minus symbol means to NOT use that particular TLS version.
'';
}

{
time = "2025-01-01T23:16:35+00:00";
message = ''
A new module is available: 'programs.ghostty'.

Ghostty is a terminal emulator that differentiates itself by being
fast, feature-rich, and native. While there are many excellent
terminal emulators available, they all force you to choose between
speed, features, or native UIs. Ghostty provides all three.
'';
}
];
};
}
1 change: 1 addition & 0 deletions modules/modules.nix
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ let
./programs/getmail.nix
./programs/gh.nix
./programs/gh-dash.nix
./programs/ghostty.nix
./programs/git-cliff.nix
./programs/git-credential-oauth.nix
./programs/git.nix
Expand Down
175 changes: 175 additions & 0 deletions modules/programs/ghostty.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
{ config, lib, pkgs, ... }:
let
cfg = config.programs.ghostty;

keyValueSettings = {
listsAsDuplicateKeys = true;
mkKeyValue = lib.generators.mkKeyValueDefault { } " = ";
};
keyValue = pkgs.formats.keyValue keyValueSettings;
in {
meta.maintainers = [ lib.maintainers.HeitorAugustoLN ];

options.programs.ghostty = {
enable = lib.mkEnableOption "Ghostty";

package = lib.mkPackageOption pkgs "ghostty" { };

settings = lib.mkOption {
inherit (keyValue) type;
default = { };
example = lib.literalExpression ''
{
theme = "catppuccin-mocha";
font-size = 10;
}
'';
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 = true;
};

enableBashIntegration = lib.mkEnableOption ''
bash shell integration.

This is 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
'';

enableFishIntegration = lib.mkEnableOption ''
fish shell integration.

This is 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
'';

enableZshIntegration = lib.mkEnableOption ''
zsh shell integration.

This is 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
'';
};

config = lib.mkIf cfg.enable (lib.mkMerge [
{
home.packages = [ 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 = lib.mkMerge [
{
"ghostty/config" = lib.mkIf (cfg.settings != { }) {
source = keyValue.generate "ghostty-config" cfg.settings;
onChange = "${lib.getExe cfg.package} +validate-config";
};
}

(lib.mkIf (cfg.themes != { }) (lib.mapAttrs' (name: value: {
name = "ghostty/themes/${name}";
value.source = keyValue.generate "ghostty-${name}-theme" value;
}) cfg.themes))
];
}

(lib.mkIf cfg.installVimSyntax {
programs.vim.plugins = [ cfg.package.vim ];
})

(lib.mkIf cfg.installBatSyntax {
programs.bat = {
syntaxes.ghostty = {
src = cfg.package;
file = "share/bat/syntaxes/ghostty.sublime-syntax";
};
config.map-syntax =
[ "${config.xdg.configHome}/ghostty/config:Ghostty Config" ];
};
})

(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.shellInit = ''
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.initExtra = ''
if [[ -n $GHOSTTY_RESOURCES_DIR ]]; then
source "$GHOSTTY_RESOURCES_DIR"/shell-integration/zsh/ghostty-integration
fi
'';
})
]);
}
1 change: 1 addition & 0 deletions tests/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ in import nmtSrc {
./modules/programs/gallery-dl
./modules/programs/gh
./modules/programs/gh-dash
./modules/programs/ghostty
./modules/programs/git
./modules/programs/git-cliff
./modules/programs/git-credential-oauth
Expand Down
5 changes: 5 additions & 0 deletions tests/modules/programs/ghostty/default.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
ghostty-example-settings = ./example-settings.nix;
ghostty-empty-settings = ./empty-settings.nix;
ghostty-example-theme = ./example-theme.nix;
}
7 changes: 7 additions & 0 deletions tests/modules/programs/ghostty/empty-settings.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
programs.ghostty.enable = true;
test.stubs.ghostty = { };
nmt.script = ''
assertPathNotExists home-files/.config/ghostty/config
'';
}
2 changes: 2 additions & 0 deletions tests/modules/programs/ghostty/example-config-expected
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
font-size = 10
theme = catppuccin-mocha
17 changes: 17 additions & 0 deletions tests/modules/programs/ghostty/example-settings.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{ config, ... }: {
programs.ghostty = {
enable = true;
package = config.lib.test.mkStubPackage { };

settings = {
theme = "catppuccin-mocha";
font-size = 10;
};
};

nmt.script = ''
assertFileContent \
home-files/.config/ghostty/config \
${./example-config-expected}
'';
}
21 changes: 21 additions & 0 deletions tests/modules/programs/ghostty/example-theme-expected
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
background = 1e1e2e
cursor-color = f5e0dc
foreground = cdd6f4
palette = 0=#45475a
palette = 1=#f38ba8
palette = 2=#a6e3a1
palette = 3=#f9e2af
palette = 4=#89b4fa
palette = 5=#f5c2e7
palette = 6=#94e2d5
palette = 7=#bac2de
palette = 8=#585b70
palette = 9=#f38ba8
palette = 10=#a6e3a1
palette = 11=#f9e2af
palette = 12=#89b4fa
palette = 13=#f5c2e7
palette = 14=#94e2d5
palette = 15=#a6adc8
selection-background = 353749
selection-foreground = cdd6f4
40 changes: 40 additions & 0 deletions tests/modules/programs/ghostty/example-theme.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
{ config, ... }: {
programs.ghostty = {
enable = true;
package = config.lib.test.mkStubPackage { };

themes = {
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";
};
};
};

nmt.script = ''
assertFileContent \
home-files/.config/ghostty/themes/catppuccin-mocha \
${./example-theme-expected}
'';
}
Loading