diff --git a/modules/programs/atuin.nix b/modules/programs/atuin.nix index a27bcf860..269aa70b5 100644 --- a/modules/programs/atuin.nix +++ b/modules/programs/atuin.nix @@ -5,11 +5,13 @@ with lib; let cfg = config.programs.atuin; + daemonCfg = cfg.daemon; tomlFormat = pkgs.formats.toml { }; + inherit (pkgs.stdenv) isLinux isDarwin; in { - meta.maintainers = [ maintainers.hawkw ]; + meta.maintainers = [ maintainers.hawkw maintainers.water-sucks ]; options.programs.atuin = { enable = mkEnableOption "atuin"; @@ -94,49 +96,132 @@ in { Whether to enable Nushell integration. ''; }; + + daemon = { + enable = mkEnableOption "Atuin daemon"; + + logLevel = mkOption { + default = null; + type = + types.nullOr (types.enum [ "trace" "debug" "info" "warn" "error" ]); + description = '' + Verbosity of Atuin daemon logging. + ''; + }; + }; }; config = let flagsStr = escapeShellArgs cfg.flags; - in mkIf cfg.enable { + in mkIf cfg.enable (mkMerge [ + { + # Always add the configured `atuin` package. + home.packages = [ cfg.package ]; - # Always add the configured `atuin` package. - home.packages = [ cfg.package ]; + # If there are user-provided settings, generate the config file. + xdg.configFile."atuin/config.toml" = mkIf (cfg.settings != { }) { + source = tomlFormat.generate "atuin-config" cfg.settings; + }; - # If there are user-provided settings, generate the config file. - xdg.configFile."atuin/config.toml" = mkIf (cfg.settings != { }) { - source = tomlFormat.generate "atuin-config" cfg.settings; - }; - - programs.bash.initExtra = mkIf cfg.enableBashIntegration '' - if [[ :$SHELLOPTS: =~ :(vi|emacs): ]]; then - source "${pkgs.bash-preexec}/share/bash/bash-preexec.sh" - eval "$(${lib.getExe cfg.package} init bash ${flagsStr})" - fi - ''; - - programs.zsh.initExtra = mkIf cfg.enableZshIntegration '' - if [[ $options[zle] = on ]]; then - eval "$(${lib.getExe cfg.package} init zsh ${flagsStr})" - fi - ''; - - programs.fish.interactiveShellInit = mkIf cfg.enableFishIntegration '' - ${lib.getExe cfg.package} init fish ${flagsStr} | source - ''; - - programs.nushell = mkIf cfg.enableNushellIntegration { - extraEnv = '' - let atuin_cache = "${config.xdg.cacheHome}/atuin" - if not ($atuin_cache | path exists) { - mkdir $atuin_cache - } - ${ - lib.getExe cfg.package - } init nu ${flagsStr} | save --force ${config.xdg.cacheHome}/atuin/init.nu + programs.bash.initExtra = mkIf cfg.enableBashIntegration '' + if [[ :$SHELLOPTS: =~ :(vi|emacs): ]]; then + source "${pkgs.bash-preexec}/share/bash/bash-preexec.sh" + eval "$(${lib.getExe cfg.package} init bash ${flagsStr})" + fi ''; - extraConfig = '' - source ${config.xdg.cacheHome}/atuin/init.nu + + programs.zsh.initExtra = mkIf cfg.enableZshIntegration '' + if [[ $options[zle] = on ]]; then + eval "$(${lib.getExe cfg.package} init zsh ${flagsStr})" + fi ''; - }; - }; + + programs.fish.interactiveShellInit = mkIf cfg.enableFishIntegration '' + ${lib.getExe cfg.package} init fish ${flagsStr} | source + ''; + + programs.nushell = mkIf cfg.enableNushellIntegration { + extraEnv = '' + let atuin_cache = "${config.xdg.cacheHome}/atuin" + if not ($atuin_cache | path exists) { + mkdir $atuin_cache + } + ${ + lib.getExe cfg.package + } init nu ${flagsStr} | save --force ${config.xdg.cacheHome}/atuin/init.nu + ''; + extraConfig = '' + source ${config.xdg.cacheHome}/atuin/init.nu + ''; + }; + } + + (mkIf daemonCfg.enable (mkMerge [ + { + assertions = [ + { + assertion = versionAtLeast cfg.package.version "18.2.0"; + message = '' + The Atuin daemon requires at least version 18.2.0 or later. + ''; + } + { + assertion = isLinux || isDarwin; + message = + "The Atuin daemon can only be configured on either Linux or macOS."; + } + ]; + + programs.atuin.settings = { daemon = { enabled = true; }; }; + } + (mkIf isLinux { + programs.atuin.settings = { daemon = { systemd_socket = true; }; }; + + systemd.user.services.atuin-daemon = { + Unit = { + Description = "Atuin daemon"; + Requires = [ "atuin-daemon.socket" ]; + }; + Install = { + Also = [ "atuin-daemon.socket" ]; + WantedBy = [ "default.target" ]; + }; + Service = { + ExecStart = "${lib.getExe cfg.package} daemon"; + Environment = lib.optionals (daemonCfg.logLevel != null) + [ "ATUIN_LOG=${daemonCfg.logLevel}" ]; + Restart = "on-failure"; + RestartSteps = 3; + RestartMaxDelaySec = 6; + }; + }; + + systemd.user.sockets.atuin-daemon = { + Unit = { Description = "Atuin daemon socket"; }; + Install = { WantedBy = [ "sockets.target" ]; }; + Socket = { + ListenStream = "%h/.local/share/atuin/atuin.sock"; + SocketMode = "0600"; + RemoveOnStop = true; + }; + }; + }) + (mkIf isDarwin { + launchd.agents.atuin-daemon = { + enable = true; + config = { + ProgramArguments = [ "${lib.getExe cfg.package}" "daemon" ]; + EnvironmentVariables = + lib.optionalAttrs (daemonCfg.logLevel != null) { + ATUIN_LOG = daemonCfg.logLevel; + }; + KeepAlive = { + Crashed = true; + SuccessfulExit = false; + }; + ProcessType = "Background"; + }; + }; + }) + ])) + ]); }