mirror of
https://github.com/NixOS/nixpkgs.git
synced 2026-06-05 21:03:40 +00:00
nixos/atuin: add system-wide atuin program option
Add a `programs.atuin` module to enable atuin shell history
integration system-wide, without requiring home-manager.
Features:
- Shell integration for bash, zsh, and fish (enabled by default)
- Configuration via `settings` (written to /etc/atuin/config.toml,
using ATUIN_CONFIG_DIR since atuin does not support XDG_CONFIG_DIRS)
- Custom themes support
- Package selection via `package` option
- Additional flags via `flags` option
- Daemon option with systemd user service and socket activation
(Linux only), required for some configurations such as root-on-zfs
Example usage:
programs.atuin = {
enable = true;
settings = {
auto_sync = true;
search_mode = "prefix";
};
};
This commit is contained in:
@@ -57,6 +57,8 @@
|
||||
|
||||
- [OpenThread Border Router](https://openthread.io/), a Thread border router for POSIX-based platforms that bridges Thread mesh networks to IP networks. Available as [services.openthread-border-router](#opt-services.openthread-border-router.enable).
|
||||
|
||||
- [Atuin](https://atuin.sh), magical shell history — sync, search and backup your terminal history. Available as [programs.atuin](#opt-programs.atuin.enable).
|
||||
|
||||
- [Meshtastic](https://meshtastic.org), an open-source, off-grid, decentralised mesh network
|
||||
designed to run on affordable, low-power devices. Available as [services.meshtasticd]
|
||||
(#opt-services.meshtasticd.enable).
|
||||
|
||||
@@ -168,6 +168,7 @@
|
||||
./programs/appimage.nix
|
||||
./programs/arp-scan.nix
|
||||
./programs/atop.nix
|
||||
./programs/atuin.nix
|
||||
./programs/ausweisapp.nix
|
||||
./programs/autoenv.nix
|
||||
./programs/autojump.nix
|
||||
|
||||
195
nixos/modules/programs/atuin.nix
Normal file
195
nixos/modules/programs/atuin.nix
Normal file
@@ -0,0 +1,195 @@
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (lib) escapeShellArgs;
|
||||
|
||||
cfg = config.programs.atuin;
|
||||
|
||||
tomlFormat = pkgs.formats.toml { };
|
||||
|
||||
settingsFile = tomlFormat.generate "atuin-config" cfg.settings;
|
||||
in
|
||||
{
|
||||
options.programs.atuin = {
|
||||
enable = lib.mkEnableOption "atuin";
|
||||
|
||||
package = lib.mkPackageOption pkgs "atuin" { };
|
||||
|
||||
enableBashIntegration = lib.mkEnableOption "Bash integration" // {
|
||||
default = config.programs.bash.enable;
|
||||
defaultText = lib.literalExpression "config.programs.bash.enable";
|
||||
};
|
||||
|
||||
enableZshIntegration = lib.mkEnableOption "Zsh integration" // {
|
||||
default = config.programs.zsh.enable;
|
||||
defaultText = lib.literalExpression "config.programs.zsh.enable";
|
||||
};
|
||||
|
||||
enableFishIntegration = lib.mkEnableOption "Fish integration" // {
|
||||
default = config.programs.fish.enable;
|
||||
defaultText = lib.literalExpression "config.programs.fish.enable";
|
||||
};
|
||||
|
||||
flags = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
default = [ ];
|
||||
example = [
|
||||
"--disable-up-arrow"
|
||||
"--disable-ctrl-r"
|
||||
];
|
||||
description = ''
|
||||
Flags to append to the shell hook.
|
||||
'';
|
||||
};
|
||||
|
||||
settings = lib.mkOption {
|
||||
type = tomlFormat.type;
|
||||
default = { };
|
||||
example = lib.literalExpression ''
|
||||
{
|
||||
auto_sync = true;
|
||||
sync_frequency = "5m";
|
||||
sync_address = "https://api.atuin.sh";
|
||||
search_mode = "prefix";
|
||||
}
|
||||
'';
|
||||
description = ''
|
||||
Configuration written to {file}`/etc/atuin/config.toml`.
|
||||
|
||||
See <https://docs.atuin.sh/configuration/config/> for the full list
|
||||
of options.
|
||||
'';
|
||||
};
|
||||
|
||||
daemon = {
|
||||
enable = lib.mkEnableOption "the Atuin daemon" // {
|
||||
default = pkgs.stdenv.hostPlatform.isLinux;
|
||||
defaultText = lib.literalExpression "pkgs.stdenv.hostPlatform.isLinux";
|
||||
};
|
||||
|
||||
logLevel = lib.mkOption {
|
||||
type = lib.types.enum [
|
||||
"trace"
|
||||
"debug"
|
||||
"info"
|
||||
"warn"
|
||||
"error"
|
||||
];
|
||||
default = "info";
|
||||
description = ''
|
||||
Log level for the Atuin daemon.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
themes = lib.mkOption {
|
||||
type = lib.types.attrsOf (
|
||||
lib.types.oneOf [
|
||||
tomlFormat.type
|
||||
lib.types.path
|
||||
lib.types.lines
|
||||
]
|
||||
);
|
||||
description = ''
|
||||
Each theme is written to
|
||||
{file}`/etc/atuin/themes/theme-name.toml`
|
||||
where the name of each attribute is the theme-name
|
||||
|
||||
See <https://docs.atuin.sh/guide/theming/> for the full list
|
||||
of options.
|
||||
'';
|
||||
default = { };
|
||||
example = lib.literalExpression ''
|
||||
{
|
||||
"my-theme" = {
|
||||
theme.name = "My Theme";
|
||||
colors = {
|
||||
Base = "#000000";
|
||||
Title = "#FFFFFF";
|
||||
};
|
||||
};
|
||||
}
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
environment.systemPackages = [ cfg.package ];
|
||||
|
||||
# Atuin only reads from ATUIN_CONFIG_DIR or XDG_CONFIG_HOME, not XDG_CONFIG_DIRS,
|
||||
# so we must set ATUIN_CONFIG_DIR to point to the system-wide config location.
|
||||
environment.variables.ATUIN_CONFIG_DIR = "/etc/atuin";
|
||||
|
||||
environment.etc = lib.mkMerge [
|
||||
(lib.mkIf (cfg.settings != { }) {
|
||||
"atuin/config.toml".source = settingsFile;
|
||||
})
|
||||
|
||||
(lib.mkIf (cfg.themes != { }) (
|
||||
builtins.mapAttrs' (
|
||||
name: theme:
|
||||
lib.nameValuePair "atuin/themes/${name}.toml" {
|
||||
source =
|
||||
if builtins.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.interactiveShellInit = lib.mkIf cfg.enableBashIntegration ''
|
||||
if [[ :$SHELLOPTS: =~ :(vi|emacs): ]]; then
|
||||
eval "$(${lib.getExe cfg.package} init bash ${escapeShellArgs cfg.flags})"
|
||||
fi
|
||||
'';
|
||||
|
||||
programs.zsh.interactiveShellInit = lib.mkIf cfg.enableZshIntegration ''
|
||||
if [[ $options[zle] = on ]]; then
|
||||
eval "$(${lib.getExe cfg.package} init zsh ${escapeShellArgs cfg.flags})"
|
||||
fi
|
||||
'';
|
||||
|
||||
programs.fish.interactiveShellInit = lib.mkIf cfg.enableFishIntegration ''
|
||||
${lib.getExe cfg.package} init fish ${escapeShellArgs cfg.flags} | source
|
||||
'';
|
||||
|
||||
systemd = lib.mkIf (cfg.daemon.enable && pkgs.stdenv.hostPlatform.isLinux) {
|
||||
user.services.atuin-daemon = {
|
||||
unitConfig = {
|
||||
Description = "Atuin daemon";
|
||||
Requires = [ "atuin-daemon.socket" ];
|
||||
};
|
||||
serviceConfig = {
|
||||
ExecStart = "${lib.getExe cfg.package} daemon start";
|
||||
Environment = [ "ATUIN_LOG=${cfg.daemon.logLevel}" ];
|
||||
Restart = "on-failure";
|
||||
RestartSteps = 3;
|
||||
RestartMaxDelaySec = 6;
|
||||
};
|
||||
};
|
||||
|
||||
user.sockets.atuin-daemon = {
|
||||
unitConfig = {
|
||||
Description = "Atuin daemon socket";
|
||||
};
|
||||
socketConfig = {
|
||||
ListenStream = "%t/atuin/atuin.sock";
|
||||
SocketMode = "0640";
|
||||
DirectoryMode = "0740";
|
||||
RemoveOnStop = true;
|
||||
};
|
||||
wantedBy = [ "sockets.target" ];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
meta.maintainers = cfg.package.meta.maintainers;
|
||||
}
|
||||
@@ -236,6 +236,7 @@ in
|
||||
atticd = runTest ./atticd.nix;
|
||||
attr = pkgs.callPackage ./attr.nix { };
|
||||
atuin = runTest ./atuin.nix;
|
||||
atuin-programs = runTest ./atuin-programs.nix;
|
||||
audiobookshelf = runTest ./audiobookshelf.nix;
|
||||
audit = runTest ./audit.nix;
|
||||
audit-testsuite = runTest ./audit-testsuite.nix;
|
||||
|
||||
39
nixos/tests/atuin-programs.nix
Normal file
39
nixos/tests/atuin-programs.nix
Normal file
@@ -0,0 +1,39 @@
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
name = "atuin";
|
||||
meta.maintainers = pkgs.atuin.meta.maintainers;
|
||||
|
||||
nodes.machine = {
|
||||
programs = {
|
||||
bash.enable = true;
|
||||
fish.enable = true;
|
||||
zsh.enable = true;
|
||||
|
||||
atuin = {
|
||||
enable = true;
|
||||
settings = {
|
||||
auto_sync = false;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
testScript = ''
|
||||
start_all()
|
||||
machine.wait_for_unit("default.target")
|
||||
|
||||
# Check atuin is installed
|
||||
machine.succeed("atuin --version")
|
||||
|
||||
# Check shell integration - verify the init scripts can be sourced without error
|
||||
machine.succeed("bash -c 'eval \"$(atuin init bash)\"'")
|
||||
machine.succeed("zsh -c 'eval \"$(atuin init zsh)\"'")
|
||||
machine.succeed("fish -c 'atuin init fish | source'")
|
||||
|
||||
# Verify config file was created
|
||||
machine.succeed("grep -q 'auto_sync = false' /etc/atuin/config.toml")
|
||||
|
||||
# Verify daemon socket unit is enabled
|
||||
machine.succeed("systemctl --user --machine=root@ is-enabled atuin-daemon.socket")
|
||||
'';
|
||||
}
|
||||
@@ -58,7 +58,7 @@ rustPlatform.buildRustPackage (finalAttrs: {
|
||||
|
||||
passthru = {
|
||||
tests = {
|
||||
inherit (nixosTests) atuin;
|
||||
inherit (nixosTests) atuin atuin-programs;
|
||||
};
|
||||
updateScript = nix-update-script { };
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user