From 5f6aa268e419d053c3d5025da740e390b12ac936 Mon Sep 17 00:00:00 2001 From: Heitor Augusto Date: Thu, 26 Dec 2024 20:01:54 -0300 Subject: [PATCH] ghostty: add module --- modules/misc/news.nix | 12 ++ modules/modules.nix | 1 + modules/programs/ghostty.nix | 173 ++++++++++++++++++ tests/default.nix | 1 + tests/modules/programs/ghostty/default.nix | 5 + .../programs/ghostty/empty-settings.nix | 7 + .../programs/ghostty/example-config-expected | 2 + .../programs/ghostty/example-settings.nix | 17 ++ .../programs/ghostty/example-theme-expected | 21 +++ .../programs/ghostty/example-theme.nix | 40 ++++ 10 files changed, 279 insertions(+) create mode 100644 modules/programs/ghostty.nix create mode 100644 tests/modules/programs/ghostty/default.nix create mode 100644 tests/modules/programs/ghostty/empty-settings.nix create mode 100644 tests/modules/programs/ghostty/example-config-expected create mode 100644 tests/modules/programs/ghostty/example-settings.nix create mode 100644 tests/modules/programs/ghostty/example-theme-expected create mode 100644 tests/modules/programs/ghostty/example-theme.nix diff --git a/modules/misc/news.nix b/modules/misc/news.nix index 4cfa0e64..699398de 100644 --- a/modules/misc/news.nix +++ b/modules/misc/news.nix @@ -1935,6 +1935,18 @@ in { be deprecated for removal in the future. ''; } + + { + 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. + ''; + } ]; }; } diff --git a/modules/modules.nix b/modules/modules.nix index d7f13933..c5a81b42 100644 --- a/modules/modules.nix +++ b/modules/modules.nix @@ -104,6 +104,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 diff --git a/modules/programs/ghostty.nix b/modules/programs/ghostty.nix new file mode 100644 index 00000000..026f89dc --- /dev/null +++ b/modules/programs/ghostty.nix @@ -0,0 +1,173 @@ +{ 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 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 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 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 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 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; + }; + } + + (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 = [ "*/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 + ''; + }) + ]); +} diff --git a/tests/default.nix b/tests/default.nix index 68474f22..3530138d 100644 --- a/tests/default.nix +++ b/tests/default.nix @@ -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 diff --git a/tests/modules/programs/ghostty/default.nix b/tests/modules/programs/ghostty/default.nix new file mode 100644 index 00000000..e9db62d5 --- /dev/null +++ b/tests/modules/programs/ghostty/default.nix @@ -0,0 +1,5 @@ +{ + ghostty-example-settings = ./example-settings.nix; + ghostty-empty-settings = ./empty-settings.nix; + ghostty-example-theme = ./example-theme.nix; +} diff --git a/tests/modules/programs/ghostty/empty-settings.nix b/tests/modules/programs/ghostty/empty-settings.nix new file mode 100644 index 00000000..4e5e83e8 --- /dev/null +++ b/tests/modules/programs/ghostty/empty-settings.nix @@ -0,0 +1,7 @@ +{ + programs.ghostty.enable = true; + test.stubs.ghostty = { }; + nmt.script = '' + assertPathNotExists home-files/.config/ghostty/config + ''; +} diff --git a/tests/modules/programs/ghostty/example-config-expected b/tests/modules/programs/ghostty/example-config-expected new file mode 100644 index 00000000..8f52b631 --- /dev/null +++ b/tests/modules/programs/ghostty/example-config-expected @@ -0,0 +1,2 @@ +font-size = 10 +theme = catppuccin-mocha diff --git a/tests/modules/programs/ghostty/example-settings.nix b/tests/modules/programs/ghostty/example-settings.nix new file mode 100644 index 00000000..ea48122d --- /dev/null +++ b/tests/modules/programs/ghostty/example-settings.nix @@ -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} + ''; +} diff --git a/tests/modules/programs/ghostty/example-theme-expected b/tests/modules/programs/ghostty/example-theme-expected new file mode 100644 index 00000000..8644b132 --- /dev/null +++ b/tests/modules/programs/ghostty/example-theme-expected @@ -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 diff --git a/tests/modules/programs/ghostty/example-theme.nix b/tests/modules/programs/ghostty/example-theme.nix new file mode 100644 index 00000000..b4d21159 --- /dev/null +++ b/tests/modules/programs/ghostty/example-theme.nix @@ -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} + ''; +}