diff --git a/flake.lock b/flake.lock index 62e06142f..c0e3b5c70 100644 --- a/flake.lock +++ b/flake.lock @@ -2,11 +2,11 @@ "nodes": { "nixpkgs": { "locked": { - "lastModified": 1742422364, - "narHash": "sha256-mNqIplmEohk5jRkqYqG19GA8MbQ/D4gQSK0Mu4LvfRQ=", + "lastModified": 1742669843, + "narHash": "sha256-G5n+FOXLXcRx+3hCJ6Rt6ZQyF1zqQ0DL0sWAMn2Nk0w=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "a84ebe20c6bc2ecbcfb000a50776219f48d134cc", + "rev": "1e5b653dff12029333a6546c11e108ede13052eb", "type": "github" }, "original": { diff --git a/modules/lib/maintainers.nix b/modules/lib/maintainers.nix index efd76f28e..5b57ba8de 100644 --- a/modules/lib/maintainers.nix +++ b/modules/lib/maintainers.nix @@ -310,6 +310,12 @@ github = "mifom"; githubId = 23462908; }; + msyds = { + name = "Madeleine Sydney Ĺšlaga"; + email = "65362461+msyds@users.noreply.github.com"; + github = "msyds"; + githubId = 65362461; + }; nikp123 = { name = "nikp123"; email = "nikp123@users.noreply.github.com"; diff --git a/modules/misc/news.nix b/modules/misc/news.nix index 49db34015..3d5938444 100644 --- a/modules/misc/news.nix +++ b/modules/misc/news.nix @@ -2148,6 +2148,7 @@ in { under '$XDG_CONFIG_HOME/easyeffects/{input,output}/'. ''; } + { time = "2025-02-12T15:56:00+00:00"; message = '' @@ -2177,6 +2178,16 @@ in { - programs.zellij.enableZshIntegration ''; } + + { + time = "2025-01-02T11:21:19+00:00"; + message = '' + A new module is available: 'services.mpdscribble'. + + A MPD client which submits information about tracks being played to a + scrobbler (e.g. last.fm) + ''; + } ]; }; } diff --git a/modules/modules.nix b/modules/modules.nix index 4849769ee..36a830dce 100644 --- a/modules/modules.nix +++ b/modules/modules.nix @@ -170,6 +170,7 @@ let ./programs/mbsync.nix ./programs/mcfly.nix ./programs/mercurial.nix + ./programs/mergiraf.nix ./programs/micro.nix ./programs/mise.nix ./programs/mods.nix @@ -225,6 +226,7 @@ let ./programs/readline.nix ./programs/rio.nix ./programs/ripgrep.nix + ./programs/ripgrep-all.nix ./programs/rofi-pass.nix ./programs/rofi.nix ./programs/rtorrent.nix @@ -362,6 +364,7 @@ let ./services/mopidy.nix ./services/mpd.nix ./services/mpdris2.nix + ./services/mpdscribble.nix ./services/mpd-discord-rpc.nix ./services/mpd-mpris.nix ./services/mpris-proxy.nix diff --git a/modules/programs/carapace.nix b/modules/programs/carapace.nix index 6d1b6f8ac..d07cb6bd0 100644 --- a/modules/programs/carapace.nix +++ b/modules/programs/carapace.nix @@ -61,18 +61,23 @@ in { }; }; - xdg.configFile = - mkIf (config.programs.fish.enable && cfg.enableFishIntegration) ( + xdg.configFile = mkIf (config.programs.fish.enable + && cfg.enableFishIntegration + && lib.versionOlder config.programs.fish.package.version "4.0.0") ( # Convert the entries from `carapace --list` to empty # xdg.configFile."fish/completions/NAME.fish" entries. # # This is to disable fish builtin completion for each of the - # carapace-supported completions It is in line with the instructions from + # carapace-supported completions. + # + # This is necessary for carapace to properly work with fish version < 4.0b1. + # + # It is in line with the instructions from # carapace-bin: # # carapace --list | awk '{print $1}' | xargs -I{} touch ~/.config/fish/completions/{}.fish # - # See https://github.com/rsteube/carapace-bin#getting-started + # See https://carapace-sh.github.io/carapace-bin/setup.html#fish let carapaceListFile = pkgs.runCommandLocal "carapace-list" { buildInputs = [ cfg.package ]; diff --git a/modules/programs/direnv.nix b/modules/programs/direnv.nix index 644914d58..c588c6b14 100644 --- a/modules/programs/direnv.nix +++ b/modules/programs/direnv.nix @@ -54,7 +54,7 @@ in { enableFishIntegration = lib.hm.shell.mkFishIntegrationOption { inherit config; extraDescription = '' - Note, enabling the direnv module will always active its functionality + Note, enabling the direnv module will always activate its functionality for Fish since the direnv package automatically gets loaded in Fish. If this is not the case try adding diff --git a/modules/programs/distrobox.nix b/modules/programs/distrobox.nix index 1e9f0ac09..30e716644 100644 --- a/modules/programs/distrobox.nix +++ b/modules/programs/distrobox.nix @@ -47,7 +47,7 @@ in { } ''; description = '' - A set of containers and all its respective configurations. Each option cat be either a + A set of containers and all its respective configurations. Each option can be either a bool, string or a list of strings. If passed a list, the option will be repeated for each element. See common-debian in the example config. All the available options for the containers can be found in the distrobox-assemble documentation at . @@ -87,7 +87,7 @@ in { if [[ $prev_hash != $new_hash ]]; then rm -rf /tmp/storage-run-1000/containers rm -rf /tmp/storage-run-1000/libpod/tmp - $HOME/.nix-profile/bin/distrobox-assemble create --file $containers_file + ${cfg.package}/bin/distrobox-assemble create --file $containers_file echo $new_hash > $prev_hash_file fi ''}"; diff --git a/modules/programs/fish.nix b/modules/programs/fish.nix index 73691d5fb..d4f9751d9 100644 --- a/modules/programs/fish.nix +++ b/modules/programs/fish.nix @@ -449,7 +449,7 @@ in { for src in $srcs; do if [ -d $src/share/man ]; then find -L $src/share/man -type f \ - | xargs python ${cfg.package}/share/fish/tools/create_manpage_completions.py --directory $out \ + -exec python ${cfg.package}/share/fish/tools/create_manpage_completions.py --directory $out {} + \ > /dev/null fi done diff --git a/modules/programs/fzf.nix b/modules/programs/fzf.nix index 518ea22a7..76c5e2c4b 100644 --- a/modules/programs/fzf.nix +++ b/modules/programs/fzf.nix @@ -195,8 +195,10 @@ in { # Note, since fzf unconditionally binds C-r we use `mkOrder` to make the # initialization show up a bit earlier. This is to make initialization of # other history managers, like mcfly or atuin, take precedence. + # Still needs to be initialized after oh-my-zsh (order 800), otherwise + # omz will take precedence. programs.zsh.initContent = - mkIf cfg.enableZshIntegration (mkOrder 200 zshIntegration); + mkIf cfg.enableZshIntegration (mkOrder 910 zshIntegration); programs.fish.interactiveShellInit = mkIf cfg.enableFishIntegration (mkOrder 200 fishIntegration); diff --git a/modules/programs/helix.nix b/modules/programs/helix.nix index 840f5d82f..3119a06d4 100644 --- a/modules/programs/helix.nix +++ b/modules/programs/helix.nix @@ -1,7 +1,5 @@ { config, lib, pkgs, ... }: - with lib; - let cfg = config.programs.helix; tomlFormat = pkgs.formats.toml { }; @@ -26,6 +24,20 @@ in { description = "Extra packages available to hx."; }; + extraConfig = mkOption { + type = types.lines; + default = ""; + description = '' + Extra lines to be appended to the config file. + Use this if you would like to maintain order for helix settings (eg. for minor modes) + ''; + example = literalExpression '' + [keys.normal.g] # Reverse Alphabetical Order + G = "goto_file_end" + g = "goto_file_start" + ''; + }; + defaultEditor = mkOption { type = types.bool; default = false; @@ -200,7 +212,13 @@ in { xdg.configFile = let settings = { "helix/config.toml" = mkIf (cfg.settings != { }) { - source = tomlFormat.generate "helix-config" cfg.settings; + source = let + configFile = tomlFormat.generate "config.toml" cfg.settings; + extraConfigFile = + pkgs.writeText "extra-config.toml" ("\n" + cfg.extraConfig); + in pkgs.runCommand "helix-config.toml" { } '' + cat ${configFile} ${extraConfigFile} >> $out + ''; }; "helix/languages.toml" = mkIf (cfg.languages != { }) { source = tomlFormat.generate "helix-languages-config" cfg.languages; @@ -210,10 +228,10 @@ in { }; }; - themes = (mapAttrs' (n: v: + themes = mapAttrs' (n: v: nameValuePair "helix/themes/${n}.toml" { source = tomlFormat.generate "helix-theme-${n}" v; - }) cfg.themes); + }) cfg.themes; in settings // themes; }; } diff --git a/modules/programs/mergiraf.nix b/modules/programs/mergiraf.nix new file mode 100644 index 000000000..0597b7d93 --- /dev/null +++ b/modules/programs/mergiraf.nix @@ -0,0 +1,31 @@ +{ pkgs, config, lib, ... }: +let + inherit (lib) + mkEnableOption mkPackageOption types literalExpression mkIf maintainers; + cfg = config.programs.mergiraf; + mergiraf = "${cfg.package}/bin/mergiraf"; +in { + meta.maintainers = [ maintainers.bobvanderlinden ]; + + options = { + programs.mergiraf = { + enable = mkEnableOption "mergiraf"; + package = mkPackageOption pkgs "mergiraf" { }; + }; + }; + + config = mkIf cfg.enable { + home.packages = [ cfg.package ]; + + programs.git = { + attributes = [ "* merge=mergiraf" ]; + extraConfig = { + merge.mergiraf = { + name = "mergiraf"; + driver = + "${mergiraf} merge --git %O %A %B -s %S -x %X -y %Y -p %P -l %L"; + }; + }; + }; + }; +} diff --git a/modules/programs/ripgrep-all.nix b/modules/programs/ripgrep-all.nix new file mode 100644 index 000000000..cef0de21b --- /dev/null +++ b/modules/programs/ripgrep-all.nix @@ -0,0 +1,102 @@ +{ config, lib, pkgs, ... }: + +let + cfg = config.programs.ripgrep-all; + configPath = if pkgs.stdenv.hostPlatform.isDarwin then + "Library/Application Support/ripgrep-all/config.jsonc" + else + "${config.xdg.configHome}/ripgrep-all/config.jsonc"; + customAdapter = lib.types.submodule { + # Descriptions are largely copied from https://github.com/phiresky/ripgrep-all/blob/v1.0.0-alpha.5/src/adapters/custom.rs + options = { + name = lib.mkOption { + type = lib.types.str; + description = + "The unique identifier and name of this adapter; must only include a-z, 0-9, _"; + }; + version = lib.mkOption { + type = lib.types.int; + default = 1; + description = + "The version identifier used to key cache entries; change if the configuration or program changes"; + }; + description = lib.mkOption { + type = lib.types.str; + description = "A description of this adapter; shown in rga's help"; + }; + extensions = lib.mkOption { + type = with lib.types; listOf str; + description = "The file extensions this adapter supports"; + example = [ "pdf" ]; + }; + mimetypes = lib.mkOption { + type = with lib.types; nullOr (listOf str); + default = null; + description = + "If not null and --rga-accurate is enabled, mime type matching is used instead of file name matching"; + example = [ "application/pdf" ]; + }; + binary = lib.mkOption { + type = lib.types.path; + description = "The path of the binary to run"; + }; + args = lib.mkOption { + type = with lib.types; listOf str; + default = [ ]; + description = + "The output path hint; the placeholders are the same as for rga's `args`"; + }; + disabled_by_default = lib.mkOption { + type = with lib.types; nullOr bool; + default = null; + description = "If true, the adapter will be disabled by default"; + }; + match_only_by_mime = lib.mkOption { + type = with lib.types; nullOr bool; + default = null; + description = + "if --rga-accurate, only match by mime types, ignore extensions completely"; + }; + output_path_hint = lib.mkOption { + type = with lib.types; nullOr str; + default = null; + description = + "Setting this is useful if the output format is not plain text (.txt) but instead some other format that should be passed to another adapter"; + example = "$${input_virtual_path}.txt.asciipagebreaks"; + }; + }; + }; +in { + meta.maintainers = with lib.maintainers; [ lafrenierejm ]; + + options = { + programs.ripgrep-all = { + enable = lib.mkEnableOption "ripgrep-all (rga)"; + + package = lib.mkPackageOption pkgs "ripgrep-all" { nullable = true; }; + + custom_adapters = lib.mkOption { + type = lib.types.listOf customAdapter; + default = [ ]; + description = '' + Custom adapters that invoke external preprocessing scripts. + See . + ''; + }; + }; + }; + + config = lib.mkIf cfg.enable { + home = { + packages = lib.mkIf (cfg.package != null) [ cfg.package ]; + + file."${configPath}" = lib.mkIf (cfg.custom_adapters != [ ]) { + source = (pkgs.formats.json { }).generate "ripgrep-all" { + "$schema" = "./config.schema.json"; + custom_adapters = + map (lib.filterAttrs (n: v: v != null)) cfg.custom_adapters; + }; + }; + }; + }; +} diff --git a/modules/programs/thunderbird.nix b/modules/programs/thunderbird.nix index 9e869025f..d567ab44f 100644 --- a/modules/programs/thunderbird.nix +++ b/modules/programs/thunderbird.nix @@ -387,6 +387,8 @@ in { attrsOf (submodule ({ config, ... }: { config.thunderbird = { settings = lib.mkIf (config.flavor == "gmail.com") (id: { + "mail.smtpserver.smtp_${id}.authMethod" = + mkOptionDefault 10; # 10 = OAuth2 "mail.server.server_${id}.authMethod" = mkOptionDefault 10; # 10 = OAuth2 "mail.server.server_${id}.socketType" = diff --git a/modules/programs/vscode.nix b/modules/programs/vscode.nix index 69b7e1812..2fee53ac1 100644 --- a/modules/programs/vscode.nix +++ b/modules/programs/vscode.nix @@ -389,25 +389,26 @@ in { mkMerge (concatMap toPaths (flatten (mapAttrsToList (n: v: v.extensions) cfg.profiles)) ++ optional - (versionAtLeast vscodeVersion "1.74.0" && defaultProfile != { }) { - # Whenever our immutable extensions.json changes, force VSCode to regenerate - # extensions.json with both mutable and immutable extensions. - "${extensionPath}/.extensions-immutable.json" = { - text = extensionJson defaultProfile.extensions; - onChange = '' - run rm $VERBOSE_ARG -f ${extensionPath}/{extensions.json,.init-default-profile-extensions} - verboseEcho "Regenerating VSCode extensions.json" - run ${getExe cfg.package} --list-extensions > /dev/null - ''; - }; - }) + ((versionAtLeast vscodeVersion "1.74.0" || vscodePname == "cursor") + && defaultProfile != { }) { + # Whenever our immutable extensions.json changes, force VSCode to regenerate + # extensions.json with both mutable and immutable extensions. + "${extensionPath}/.extensions-immutable.json" = { + text = extensionJson defaultProfile.extensions; + onChange = '' + run rm $VERBOSE_ARG -f ${extensionPath}/{extensions.json,.init-default-profile-extensions} + verboseEcho "Regenerating VSCode extensions.json" + run ${getExe cfg.package} --list-extensions > /dev/null + ''; + }; + }) else { "${extensionPath}".source = let combinedExtensionsDrv = pkgs.buildEnv { name = "vscode-extensions"; paths = (flatten (mapAttrsToList (n: v: v.extensions) cfg.profiles)) - ++ optional - (versionAtLeast vscodeVersion "1.74.0" && defaultProfile != { }) + ++ optional ((versionAtLeast vscodeVersion "1.74.0" || vscodePname + == "cursor") && defaultProfile != { }) (extensionJsonFile "default" (extensionJson defaultProfile.extensions)); }; diff --git a/modules/programs/waybar.nix b/modules/programs/waybar.nix index 0d7294d03..c0ce4c169 100644 --- a/modules/programs/waybar.nix +++ b/modules/programs/waybar.nix @@ -321,7 +321,7 @@ in { Description = "Highly customizable Wayland bar for Sway and Wlroots based compositors."; Documentation = "https://github.com/Alexays/Waybar/wiki"; - PartOf = [ cfg.systemd.target ]; + PartOf = [ cfg.systemd.target "tray.target" ]; After = [ cfg.systemd.target ]; ConditionEnvironment = "WAYLAND_DISPLAY"; X-Restart-Triggers = optional (settings != [ ]) @@ -339,8 +339,8 @@ in { Environment = [ "GTK_DEBUG=interactive" ]; }; - Install.WantedBy = - lib.optional (cfg.systemd.target != null) cfg.systemd.target; + Install.WantedBy = [ "tray.target" ] + ++ lib.optional (cfg.systemd.target != null) cfg.systemd.target; }; }) ]); diff --git a/modules/services/davmail.nix b/modules/services/davmail.nix index 5eb2f80a2..a58a2fea7 100644 --- a/modules/services/davmail.nix +++ b/modules/services/davmail.nix @@ -19,6 +19,8 @@ in { enable = mkEnableOption "DavMail, an MS Exchange gateway."; + package = lib.mkPackageOption pkgs "davmail" { }; + imitateOutlook = mkOption { type = types.bool; default = false; @@ -91,7 +93,7 @@ in { Install.WantedBy = [ "graphical-session.target" ]; Service = { Type = "simple"; - ExecStart = "${pkgs.davmail}/bin/davmail ${settingsFile}"; + ExecStart = "${lib.getExe cfg.package} ${settingsFile}"; Restart = "on-failure"; CapabilityBoundingSet = [ "" ]; @@ -121,8 +123,6 @@ in { }; }; - home.packages = [ pkgs.davmail ]; - + home.packages = [ cfg.package ]; }; - } diff --git a/modules/services/mpdscribble.nix b/modules/services/mpdscribble.nix new file mode 100644 index 000000000..d868f24b1 --- /dev/null +++ b/modules/services/mpdscribble.nix @@ -0,0 +1,222 @@ +{ config, lib, options, pkgs, ... }: + +let + cfg = config.services.mpdscribble; + mpdCfg = config.services.mpd; + mpdOpt = options.services.mpd; + + endpointUrls = { + "last.fm" = "http://post.audioscrobbler.com"; + "libre.fm" = "http://turtle.libre.fm"; + "jamendo" = "http://postaudioscrobbler.jamendo.com"; + "listenbrainz" = "http://proxy.listenbrainz.org"; + }; +in { + options.services.mpdscribble = { + + enable = lib.mkEnableOption '' + mpdscribble, an MPD client which submits info about tracks being played to + Last.fm (formerly AudioScrobbler) + ''; + + proxy = lib.mkOption { + default = null; + type = lib.types.nullOr lib.types.str; + description = '' + HTTP proxy URL. + ''; + }; + + verbose = lib.mkOption { + default = 1; + type = lib.types.int; + description = '' + Log level for the mpdscribble daemon. + ''; + }; + + journalInterval = lib.mkOption { + default = 600; + example = 60; + type = lib.types.int; + description = '' + How often should mpdscribble save the journal file? [seconds] + ''; + }; + + host = lib.mkOption { + default = (if mpdCfg.network.listenAddress != "any" then + mpdCfg.network.listenAddress + else + "localhost"); + defaultText = lib.literalExpression '' + if config.${mpdOpt.network.listenAddress} != "any" + then config.${mpdOpt.network.listenAddress} + else "localhost" + ''; + type = lib.types.str; + description = '' + Host for the mpdscribble daemon to search for a mpd daemon on. + ''; + }; + + package = lib.mkPackageOption pkgs "mpdscribble" { }; + + passwordFile = lib.mkOption { + default = null; + type = lib.types.nullOr lib.types.str; + description = '' + File containing the password for the mpd daemon. + ''; + }; + + port = lib.mkOption { + default = mpdCfg.network.port; + defaultText = lib.literalExpression "config.${mpdOpt.network.port}"; + type = lib.types.port; + description = '' + Port for the mpdscribble daemon to search for a mpd daemon on. + ''; + }; + + endpoints = lib.mkOption { + type = let + endpoint = { name, ... }: { + options = { + url = lib.mkOption { + type = lib.types.str; + default = endpointUrls.${name} or ""; + description = + "The url endpoint where the scrobble API is listening."; + }; + username = lib.mkOption { + type = lib.types.str; + description = '' + Username for the scrobble service. + ''; + }; + passwordFile = lib.mkOption { + type = lib.types.nullOr lib.types.str; + description = + "File containing the password, either as MD5SUM or cleartext."; + }; + }; + }; + in lib.types.attrsOf (lib.types.submodule endpoint); + default = { }; + example = { + "last.fm" = { + username = "foo"; + passwordFile = "/run/secrets/lastfm_password"; + }; + }; + description = '' + Endpoints to scrobble to. + If the endpoint is one of "${ + lib.concatStringsSep ''", "'' (builtins.attrNames endpointUrls) + }" the url is set automatically. + ''; + }; + + }; + + config = lib.mkIf cfg.enable { + assertions = [ + (lib.hm.assertions.assertPlatform "services.mpdscribble" pkgs + lib.platforms.linux) + ]; + systemd.user.services.mpdscribble = let + localMpd = (cfg.host == "localhost" || cfg.host == "127.0.0.1"); + + mkSection = secname: secCfg: '' + [${secname}] + url = ${secCfg.url} + username = ${secCfg.username} + password = {{${secname}_PASSWORD}} + journal = /var/lib/mpdscribble/${secname}.journal + ''; + + endpoints = + lib.concatStringsSep "\n" (lib.mapAttrsToList mkSection cfg.endpoints); + cfgTemplate = pkgs.writeText "mpdscribble.conf" '' + ## This file was automatically genenrated by home-manager and will be + ## overwritten. Do not edit. Edit your home-manager configuration instead. + + ## mpdscribble - an audioscrobbler for the Music Player Daemon. + ## http://mpd.wikia.com/wiki/Client:mpdscribble + + # HTTP proxy URL. + ${lib.optionalString (cfg.proxy != null) "proxy = ${cfg.proxy}"} + + # The location of the mpdscribble log file. The special value + # "syslog" makes mpdscribble use the local syslog daemon. On most + # systems, log messages will appear in /var/log/daemon.log then. + # "-" means log to stderr (the current terminal). + log = - + + # How verbose mpdscribble's logging should be. Default is 1. + verbose = ${toString cfg.verbose} + + # How often should mpdscribble save the journal file? [seconds] + journal_interval = ${toString cfg.journalInterval} + + # The host running MPD, possibly protected by a password + # ([PASSWORD@]HOSTNAME). + host = ${ + (lib.optionalString (cfg.passwordFile != null) "{{MPD_PASSWORD}}@") + + cfg.host + } + + # The port that the MPD listens on and mpdscribble should try to + # connect to. + port = ${toString cfg.port} + + ${endpoints} + ''; + + configFile = + "\${XDG_RUNTIME_DIR:-/run/user/$(id -u)}/mpdscribble/mpdscribble.conf"; + + replaceSecret = secretFile: placeholder: targetFile: + lib.optionalString (secretFile != null) '' + ${pkgs.replace-secret}/bin/replace-secret '${placeholder}' '${secretFile}' "${targetFile}" + ''; + + preStart = pkgs.writeShellApplication { + name = "mpdscribble-pre-start"; + runtimeInputs = [ pkgs.replace-secret pkgs.coreutils ]; + text = '' + configFile="${configFile}" + mkdir -p "$(dirname "$configFile")" + cp --no-preserve=mode,ownership -f "${cfgTemplate}" "$configFile" + ${replaceSecret cfg.passwordFile "{{MPD_PASSWORD}}" "$configFile"} + ${lib.concatStringsSep "\n" (lib.mapAttrsToList (secname: cfg: + replaceSecret cfg.passwordFile "{{${secname}_PASSWORD}}" + "$configFile") cfg.endpoints)} + ''; + }; + + start = pkgs.writeShellScript "mpdscribble-start" '' + configFile="${configFile}" + exec "${lib.getExe cfg.package}" --no-daemon --conf "$configFile" + ''; + + in { + Unit = { + Description = "mpdscribble mpd scrobble client"; + After = [ "network.target" ] ++ lib.optional localMpd "mpd.service"; + }; + Install.WantedBy = [ "default.target" ]; + Service = { + StateDirectory = "mpdscribble"; + RuntimeDirectory = "mpdscribble"; + RuntimeDirectoryMode = "700"; + # TODO use LoadCredential= instead of running preStart with full privileges? + ExecStartPre = "+${preStart}/bin/mpdscribble-pre-start"; + ExecStart = "${start}"; + }; + }; + }; + + meta.maintainers = [ lib.hm.maintainers.msyds ]; +} diff --git a/modules/services/podman-linux/images.nix b/modules/services/podman-linux/images.nix index 957ed11bf..58bb97da1 100644 --- a/modules/services/podman-linux/images.nix +++ b/modules/services/podman-linux/images.nix @@ -77,7 +77,7 @@ in let decryptionKeyFile = mkOption { type = with types; nullOr path; default = null; - description = "Path to key used for decrpytion of images."; + description = "Path to key used for decryption of images."; }; description = mkOption { diff --git a/tests/default.nix b/tests/default.nix index a2deefc41..c422a60ab 100644 --- a/tests/default.nix +++ b/tests/default.nix @@ -131,6 +131,7 @@ let "lsd" "lieer" "mbsync" + "mergiraf" "micro" "mise" "mpv" @@ -342,6 +343,7 @@ in import nmtSrc { ./modules/programs/lieer ./modules/programs/man ./modules/programs/mbsync + ./modules/programs/mergiraf ./modules/programs/micro ./modules/programs/mise ./modules/programs/mods @@ -378,6 +380,7 @@ in import nmtSrc { ./modules/programs/readline ./modules/programs/rio ./modules/programs/ripgrep + ./modules/programs/ripgrep-all ./modules/programs/ruff ./modules/programs/sagemath ./modules/programs/sapling @@ -524,6 +527,7 @@ in import nmtSrc { ./modules/services/mpd ./modules/services/mpd-mpris ./modules/services/mpdris2 + ./modules/services/mpdscribble ./modules/services/nix-gc ./modules/services/ollama/linux ./modules/services/osmscout-server diff --git a/tests/modules/programs/carapace/fish.nix b/tests/modules/programs/carapace/fish.nix index f0a281d38..b83136c6c 100644 --- a/tests/modules/programs/carapace/fish.nix +++ b/tests/modules/programs/carapace/fish.nix @@ -8,13 +8,17 @@ lib.mkIf config.test.enableBig { nixpkgs.overlays = [ (self: super: { inherit (realPkgs) carapace; }) ]; - nmt.script = '' + nmt.script = let + needsCompletionOverrides = lib.versionOlder realPkgs.fish.version "4.0.0"; + in '' assertFileExists home-files/.config/fish/config.fish assertFileRegex home-files/.config/fish/config.fish \ '/nix/store/.*carapace.*/bin/carapace _carapace fish \| source' - - # Check whether completions are overridden. + '' + (lib.optionalString needsCompletionOverrides '' + # Check whether completions are overridden, necessary for fish < 4.0 assertFileExists home-files/.config/fish/completions/git.fish assertFileContent home-files/.config/fish/completions/git.fish /dev/null - ''; + '') + (lib.optionalString (!needsCompletionOverrides) '' + assertPathNotExists home-files/.config/fish/completions + ''); } diff --git a/tests/modules/programs/fish/default.nix b/tests/modules/programs/fish/default.nix index f81ff971e..f7da4d4d0 100644 --- a/tests/modules/programs/fish/default.nix +++ b/tests/modules/programs/fish/default.nix @@ -4,4 +4,5 @@ fish-functions = ./functions.nix; fish-no-functions = ./no-functions.nix; fish-plugins = ./plugins.nix; + fish-manpage = ./manpage.nix; } diff --git a/tests/modules/programs/fish/manpage.nix b/tests/modules/programs/fish/manpage.nix new file mode 100644 index 000000000..2601b69c7 --- /dev/null +++ b/tests/modules/programs/fish/manpage.nix @@ -0,0 +1,12 @@ +{ lib, pkgs, ... }: { + config = { + programs.fish = { enable = true; }; + + home.packages = [ + (pkgs.runCommand "manpage-with-space" { } '' + mkdir -p $out/share/man/man1 + echo "It works!" >"$out/share/man/man1/hello -inject.1" + '') + ]; + }; +} diff --git a/tests/modules/programs/helix/example-settings.nix b/tests/modules/programs/helix/example-settings.nix index 69a5ef557..e345725e4 100644 --- a/tests/modules/programs/helix/example-settings.nix +++ b/tests/modules/programs/helix/example-settings.nix @@ -1,6 +1,4 @@ -{ config, ... }: - -{ +{ config, ... }: { programs.helix = { enable = true; @@ -18,6 +16,12 @@ }; }; + extraConfig = '' + [keys.normal.G] + G = "goto_file_end" + g = "goto_file_start" + ''; + languages = { language-server.typescript-language-server = let typescript-language-server = config.lib.test.mkStubPackage { diff --git a/tests/modules/programs/helix/settings-expected.toml b/tests/modules/programs/helix/settings-expected.toml index 91682f0ae..5e218ed77 100644 --- a/tests/modules/programs/helix/settings-expected.toml +++ b/tests/modules/programs/helix/settings-expected.toml @@ -12,3 +12,7 @@ esc = ["collapse_selection", "keep_primary_selection"] q = ":q" space = "file_picker" w = ":w" + +[keys.normal.G] +G = "goto_file_end" +g = "goto_file_start" diff --git a/tests/modules/programs/mergiraf/basic-configuration.nix b/tests/modules/programs/mergiraf/basic-configuration.nix new file mode 100644 index 000000000..3d8688ad7 --- /dev/null +++ b/tests/modules/programs/mergiraf/basic-configuration.nix @@ -0,0 +1,13 @@ +{ config, lib, ... }: + +{ + programs.git.enable = true; + programs.mergiraf.enable = true; + + nmt.script = '' + assertFileContent "home-files/.config/git/config" ${./mergiraf-git.conf} + assertFileContent "home-files/.config/git/attributes" ${ + ./mergiraf-git-attributes.conf + } + ''; +} diff --git a/tests/modules/programs/mergiraf/default.nix b/tests/modules/programs/mergiraf/default.nix new file mode 100644 index 000000000..67d8916b7 --- /dev/null +++ b/tests/modules/programs/mergiraf/default.nix @@ -0,0 +1 @@ +{ mergiraf-basic-configuration = ./basic-configuration.nix; } diff --git a/tests/modules/programs/mergiraf/mergiraf-git-attributes.conf b/tests/modules/programs/mergiraf/mergiraf-git-attributes.conf new file mode 100644 index 000000000..789ed5db5 --- /dev/null +++ b/tests/modules/programs/mergiraf/mergiraf-git-attributes.conf @@ -0,0 +1 @@ +* merge=mergiraf diff --git a/tests/modules/programs/mergiraf/mergiraf-git.conf b/tests/modules/programs/mergiraf/mergiraf-git.conf new file mode 100644 index 000000000..46da0369f --- /dev/null +++ b/tests/modules/programs/mergiraf/mergiraf-git.conf @@ -0,0 +1,9 @@ +[gpg] + format = "openpgp" + +[gpg "openpgp"] + program = "@gnupg@/bin/gpg" + +[merge "mergiraf"] + driver = "@mergiraf@/bin/mergiraf merge --git %O %A %B -s %S -x %X -y %Y -p %P -l %L" + name = "mergiraf" diff --git a/tests/modules/programs/ripgrep-all/custom-arguments.nix b/tests/modules/programs/ripgrep-all/custom-arguments.nix new file mode 100644 index 000000000..01ee70db7 --- /dev/null +++ b/tests/modules/programs/ripgrep-all/custom-arguments.nix @@ -0,0 +1,51 @@ +{ pkgs, config, ... }: { + config = { + programs.ripgrep-all = { + enable = true; + package = config.lib.test.mkStubPackage { name = "ripgrep-all"; }; + custom_adapters = [{ + name = "gron"; + version = 1; + description = "Transform JSON into discrete JS assignments"; + extensions = [ "json" ]; + mimetypes = [ "application/json" ]; + binary = "/bin/gron"; + disabled_by_default = false; + match_only_by_mime = false; + }]; + }; + + nmt.script = let + configPath = if pkgs.stdenv.hostPlatform.isDarwin then + "Library/Application Support/ripgrep-all/config.jsonc" + else + ".config/ripgrep-all/config.jsonc"; + in '' + assertFileExists "home-files/${configPath}" + assertFileContent "home-files/${configPath}" ${ + pkgs.writeText "ripgrep-all.expected" '' + { + "$schema": "./config.schema.json", + "custom_adapters": [ + { + "args": [], + "binary": "/bin/gron", + "description": "Transform JSON into discrete JS assignments", + "disabled_by_default": false, + "extensions": [ + "json" + ], + "match_only_by_mime": false, + "mimetypes": [ + "application/json" + ], + "name": "gron", + "version": 1 + } + ] + } + '' + } + ''; + }; +} diff --git a/tests/modules/programs/ripgrep-all/default-arguments.nix b/tests/modules/programs/ripgrep-all/default-arguments.nix new file mode 100644 index 000000000..61ba46b62 --- /dev/null +++ b/tests/modules/programs/ripgrep-all/default-arguments.nix @@ -0,0 +1,13 @@ +{ config, ... }: { + config = { + programs.ripgrep-all = { + enable = true; + package = config.lib.test.mkStubPackage { name = "ripgrep-all"; }; + }; + + nmt.script = '' + assertPathNotExists home-files/.config/ripgrep-all/config.jsonc + assertPathNotExists 'home-files/Library/Application Support/ripgrep-all/config.jsonc' + ''; + }; +} diff --git a/tests/modules/programs/ripgrep-all/default.nix b/tests/modules/programs/ripgrep-all/default.nix new file mode 100644 index 000000000..ddc31c28b --- /dev/null +++ b/tests/modules/programs/ripgrep-all/default.nix @@ -0,0 +1,4 @@ +{ + ripgrep-all-default-arguments = ./default-arguments.nix; + ripgrep-all-custom-arguments = ./custom-arguments.nix; +} diff --git a/tests/modules/programs/waybar/systemd-with-graphical-session-target.service b/tests/modules/programs/waybar/systemd-with-graphical-session-target.service index f3e3b24a3..5056d1be4 100644 --- a/tests/modules/programs/waybar/systemd-with-graphical-session-target.service +++ b/tests/modules/programs/waybar/systemd-with-graphical-session-target.service @@ -1,4 +1,5 @@ [Install] +WantedBy=tray.target WantedBy=sway-session.target [Service] @@ -13,3 +14,4 @@ ConditionEnvironment=WAYLAND_DISPLAY Description=Highly customizable Wayland bar for Sway and Wlroots based compositors. Documentation=https://github.com/Alexays/Waybar/wiki PartOf=sway-session.target +PartOf=tray.target diff --git a/tests/modules/services/mpdscribble/basic-configuration.nix b/tests/modules/services/mpdscribble/basic-configuration.nix new file mode 100644 index 000000000..18c02585f --- /dev/null +++ b/tests/modules/services/mpdscribble/basic-configuration.nix @@ -0,0 +1,28 @@ +{ config, lib, pkgs, ... }: + +with lib; + +{ + services.mpdscribble = { + enable = true; + endpoints = { + "libre.fm" = { + username = "musicfan1992"; + passwordFile = toString ./password-file; + }; + "https://music.com/" = { + username = "musicHATER1000"; + passwordFile = toString ./password-file; + }; + }; + }; + + home.stateVersion = "22.11"; + + test.stubs.mpd = { }; + + nmt.script = '' + serviceFile=$(normalizeStorePaths home-files/.config/systemd/user/mpdscribble.service) + assertFileContent "$serviceFile" ${./basic-configuration.service} + ''; +} diff --git a/tests/modules/services/mpdscribble/basic-configuration.service b/tests/modules/services/mpdscribble/basic-configuration.service new file mode 100644 index 000000000..efa7da9ad --- /dev/null +++ b/tests/modules/services/mpdscribble/basic-configuration.service @@ -0,0 +1,14 @@ +[Install] +WantedBy=default.target + +[Service] +ExecStart=/nix/store/00000000000000000000000000000000-mpdscribble-start +ExecStartPre=+/nix/store/00000000000000000000000000000000-mpdscribble-pre-start/bin/mpdscribble-pre-start +RuntimeDirectory=mpdscribble +RuntimeDirectoryMode=700 +StateDirectory=mpdscribble + +[Unit] +After=network.target +After=mpd.service +Description=mpdscribble mpd scrobble client diff --git a/tests/modules/services/mpdscribble/default.nix b/tests/modules/services/mpdscribble/default.nix new file mode 100644 index 000000000..b44dae9dd --- /dev/null +++ b/tests/modules/services/mpdscribble/default.nix @@ -0,0 +1 @@ +{ mpdscribble-basic-configuration = ./basic-configuration.nix; }