diff --git a/atuin.nix b/atuin.nix deleted file mode 100644 index 22022835..00000000 --- a/atuin.nix +++ /dev/null @@ -1,44 +0,0 @@ -# Atuin package definition -# -# This file will be similar to the package definition in nixpkgs: -# https://github.com/NixOS/nixpkgs/blob/master/pkgs/by-name/at/atuin/package.nix -# -# Helpful documentation: https://github.com/NixOS/nixpkgs/blob/master/doc/languages-frameworks/rust.section.md -{ - lib, - stdenv, - installShellFiles, - rustPlatform, - libiconv, -}: -rustPlatform.buildRustPackage { - name = "atuin"; - - src = lib.cleanSource ./.; - - cargoLock = { - lockFile = ./Cargo.lock; - # Allow dependencies to be fetched from git and avoid having to set the outputHashes manually - allowBuiltinFetchGit = true; - }; - - nativeBuildInputs = [installShellFiles]; - - buildInputs = lib.optionals stdenv.isDarwin [libiconv]; - - postInstall = '' - installShellCompletion --cmd atuin \ - --bash <($out/bin/atuin gen-completions -s bash) \ - --fish <($out/bin/atuin gen-completions -s fish) \ - --zsh <($out/bin/atuin gen-completions -s zsh) - ''; - - doCheck = false; - - meta = with lib; { - description = "Replacement for a shell history which records additional commands context with optional encrypted synchronization between machines"; - homepage = "https://github.com/atuinsh/atuin"; - license = licenses.mit; - mainProgram = "atuin"; - }; -} diff --git a/flake.nix b/flake.nix index 5b90e099..4eb7b9d8 100644 --- a/flake.nix +++ b/flake.nix @@ -1,5 +1,5 @@ { - description = "atuin dev shell"; + description = "Replacement for a shell history which records additional command context"; inputs = { nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; @@ -21,8 +21,263 @@ inherit system; overlays = [rust-overlay.overlays.default]; }; + + atuinPackage = { + lib, + stdenv, + installShellFiles, + rustPlatform, + libiconv, + }: + rustPlatform.buildRustPackage { + pname = "atuin"; + version = (nixpkgs.lib.importTOML ./Cargo.toml).workspace.package.version; + + src = lib.cleanSource ./.; + + cargoLock = { + lockFile = ./Cargo.lock; + # avoid having to set outputHashes manually + allowBuiltinFetchGit = true; + }; + + nativeBuildInputs = [installShellFiles]; + + buildInputs = lib.optionals stdenv.isDarwin [libiconv]; + + postInstall = '' + installShellCompletion --cmd atuin \ + --bash <($out/bin/atuin gen-completions -s bash) \ + --fish <($out/bin/atuin gen-completions -s fish) \ + --zsh <($out/bin/atuin gen-completions -s zsh) + ''; + + doCheck = false; + + meta = { + description = "Replacement for a shell history which records additional command context"; + homepage = "https://github.com/atuinsh/atuin"; + license = lib.licenses.mit; + mainProgram = "atuin"; + }; + }; + + rustPlatformFor = pkgs: let + toolchain = pkgs.rust-bin.fromRustupToolchainFile ./rust-toolchain.toml; + in + pkgs.makeRustPlatform { + cargo = toolchain; + rustc = toolchain; + }; in { formatter = forAllSystems (system: (pkgsFor system).alejandra); + + packages = forAllSystems (system: let + pkgs = pkgsFor system; + in rec { + atuin = pkgs.callPackage atuinPackage { + rustPlatform = rustPlatformFor pkgs; + }; + default = atuin; + }); + + overlays.default = final: _prev: { + atuin = final.callPackage atuinPackage { + rustPlatform = rustPlatformFor final; + }; + }; + + # cloned from home-manager's atuin.nix file + homeManagerModules.atuin = { + config, + lib, + pkgs, + ... + }: let + cfg = config.programs.atuin; + tomlFormat = pkgs.formats.toml {}; + + inherit (lib) mkIf mkOption types; + in { + options.programs.atuin = { + enable = lib.mkEnableOption "atuin, a magical shell history"; + + package = mkOption { + type = types.package; + default = self.packages.${pkgs.stdenv.hostPlatform.system}.default; + defaultText = lib.literalExpression "atuin.packages.\${system}.default"; + description = "The atuin package to use."; + }; + + enableBashIntegration = lib.hm.shell.mkBashIntegrationOption { + inherit config; + extraDescription = "If enabled, this will bind `ctrl-r` to open the Atuin history."; + }; + + enableFishIntegration = lib.hm.shell.mkFishIntegrationOption { + inherit config; + extraDescription = "If enabled, this will bind the up-arrow key to open the Atuin history."; + }; + + enableNushellIntegration = lib.hm.shell.mkNushellIntegrationOption {inherit config;}; + + enableZshIntegration = lib.hm.shell.mkZshIntegrationOption { + inherit config; + extraDescription = '' + If enabled, this will bind `ctrl-r` and the up-arrow key to open the + Atuin history. + ''; + }; + + flags = mkOption { + default = []; + type = types.listOf types.str; + example = ["--disable-up-arrow" "--disable-ctrl-r"]; + description = "Flags to append to the shell hook."; + }; + + settings = mkOption { + type = with types; let + prim = oneOf [bool int str]; + primOrPrimAttrs = either prim (attrsOf prim); + entry = either prim (listOf primOrPrimAttrs); + entryOrAttrsOf = t: either entry (attrsOf t); + entries = entryOrAttrsOf (entryOrAttrsOf entry); + in + attrsOf entries // {description = "Atuin configuration";}; + default = {}; + example = lib.literalExpression '' + { + search_mode = "prefix"; + style = "compact"; + } + ''; + description = '' + Configuration written to + {file}`$XDG_CONFIG_HOME/atuin/config.toml`. + + See for the full list + of options. + ''; + }; + + forceOverwriteSettings = mkOption { + type = types.bool; + default = false; + description = '' + When enabled, force overwriting of the Atuin configuration file + ({file}`$XDG_CONFIG_HOME/atuin/config.toml`). + Any existing Atuin configuration will be lost. + + Enabling this is useful when adding settings for the first time + because Atuin writes its default config file after every single + shell command, which can make it difficult to manually remove. + ''; + }; + + themes = mkOption { + type = types.attrsOf (types.oneOf [ + tomlFormat.type + types.path + types.lines + ]); + default = {}; + example = lib.literalExpression '' + { + "my-theme" = { + theme.name = "My Theme"; + colors = { + Base = "#000000"; + Title = "#FFFFFF"; + }; + }; + } + ''; + description = '' + Each theme is written to + {file}`$XDG_CONFIG_HOME/atuin/themes/theme-name.toml` + where the name of each attribute is the theme-name. + + See for the full list + of options. + ''; + }; + }; + + config = let + flagsStr = lib.escapeShellArgs cfg.flags; + atuinFishConfig = + pkgs.runCommand "atuin-fish-config.fish" + {nativeBuildInputs = [pkgs.writableTmpDirAsHomeHook];} + '' + ${lib.getExe cfg.package} init fish ${flagsStr} > "$out" + ''; + in + mkIf cfg.enable (lib.mkMerge [ + { + home.packages = [cfg.package]; + + xdg.configFile = lib.mkMerge [ + (mkIf (cfg.settings != {}) { + "atuin/config.toml" = { + source = tomlFormat.generate "atuin-config" cfg.settings; + force = cfg.forceOverwriteSettings; + }; + }) + + (mkIf (cfg.themes != {}) (lib.mapAttrs' ( + name: theme: + lib.nameValuePair "atuin/themes/${name}.toml" { + source = + if lib.isString theme + then pkgs.writeText "atuin-theme-${name}" theme + else if builtins.isPath theme || lib.isStorePath theme + then theme + else tomlFormat.generate "atuin-theme-${name}" theme; + } + ) + cfg.themes)) + ]; + + 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.initContent = mkIf cfg.enableZshIntegration '' + if [[ $options[zle] = on ]]; then + eval "$(${lib.getExe cfg.package} init zsh ${flagsStr})" + fi + ''; + + programs.fish.interactiveShellInit = mkIf cfg.enableFishIntegration '' + source ${atuinFishConfig} + ''; + + programs.nushell = mkIf cfg.enableNushellIntegration { + extraConfig = lib.mkOrder 2000 '' + source ${ + pkgs.runCommand "atuin-nushell-config.nu" + {nativeBuildInputs = [pkgs.writableTmpDirAsHomeHook];} + '' + ${lib.getExe cfg.package} init nu ${flagsStr} >> "$out" + '' + } + ''; + }; + } + + (mkIf config.home.preferXdgDirectories { + programs.atuin.settings.logs = { + dir = lib.mkDefault "${config.xdg.stateHome}/atuin/logs"; + }; + }) + ]); + }; + homeManagerModules.default = self.homeManagerModules.atuin; + devShells = forAllSystems (system: let pkgs = pkgsFor system; toolchain = pkgs.rust-bin.fromRustupToolchainFile ./rust-toolchain.toml; @@ -33,6 +288,17 @@ pkgs.rust-analyzer pkgs.sqlite ]; + + RUST_SRC_PATH = "${pkgs.rustPlatform.rustLibSrc}"; + + shellHook = '' + echo >&2 "Setting development database path" + export ATUIN_DB_PATH="/tmp/atuin_dev.db" + + if [ -e "''${ATUIN_DB_PATH}" ]; then + echo >&2 "''${ATUIN_DB_PATH} already exists, you might want to double-check that" + fi + ''; }; }); };