diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 11b8324c1..cd468e16a 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -23,7 +23,8 @@ Also make sure to read the guidelines found at - [ ] Code formatted with `./format`. -- [ ] Code tested through `nix-shell --pure tests -A run.all` or `nix develop --ignore-environment .#all` using Flakes. +- [ ] Code tested through `nix-shell --pure tests -A run.all` + or `nix build --reference-lock-file flake.lock ./tests#test-all` using Flakes. - [ ] Test cases updated/added. See [example](https://github.com/nix-community/home-manager/commit/f3fbb50b68df20da47f9b0def5607857fcc0d021#diff-b61a6d542f9036550ba9c401c80f00ef). diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 2aea2da27..b34df60ea 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -15,3 +15,11 @@ updates: interval: "weekly" commit-message: prefix: "ci:" + + - package-ecosystem: "github-actions" + directory: "/" + target-branch: "release-24.11" + schedule: + interval: "weekly" + commit-message: + prefix: "ci:" diff --git a/.github/labeler.yml b/.github/labeler.yml index cab1b5438..e41e05a14 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -25,6 +25,15 @@ - modules/programs/neovim.nix - tests/modules/programs/neovim/**/* +"program: firefox": + - changed-files: + - any-glob-to-any-file: + - modules/programs/firefox/**/* + - tests/modules/programs/firefox/**/* + - modules/misc/mozilla-messaging-hosts.nix + - modules/programs/floorp.nix + - modules/programs/librewolf.nix + "shell": - changed-files: - any-glob-to-any-file: diff --git a/.github/workflows/github_pages.yml b/.github/workflows/github_pages.yml index 9f49d49a8..4e10f9ccb 100644 --- a/.github/workflows/github_pages.yml +++ b/.github/workflows/github_pages.yml @@ -11,7 +11,7 @@ jobs: runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v4 - - uses: cachix/install-nix-action@v27 + - uses: cachix/install-nix-action@v30 with: nix_path: nixpkgs=channel:nixos-unstable - uses: cachix/cachix-action@v15 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 99a2f5a1a..e4189723a 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -12,7 +12,7 @@ jobs: runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v4 - - uses: cachix/install-nix-action@v27 + - uses: cachix/install-nix-action@v30 with: nix_path: nixpkgs=channel:nixos-unstable - run: | @@ -24,6 +24,6 @@ jobs: - run: ./format -c - run: nix-shell --show-trace . -A install - run: yes | home-manager -I home-manager=. uninstall - - run: nix-shell --show-trace --arg enableBig false --pure tests -A run.all - # Somebody please help us fix the macos tests. - if: matrix.os != 'macos-latest' + - run: nix-shell -j auto --show-trace --arg enableBig false --pure tests -A run.all + env: + GC_INITIAL_HEAP_SIZE: 4294967296 diff --git a/.github/workflows/update-flake.yml b/.github/workflows/update-flake.yml index ba9b5f818..9b0e4b443 100644 --- a/.github/workflows/update-flake.yml +++ b/.github/workflows/update-flake.yml @@ -12,7 +12,7 @@ jobs: - name: Checkout repository uses: actions/checkout@v4 - name: Install Nix - uses: cachix/install-nix-action@v27 + uses: cachix/install-nix-action@v30 - name: Update flake.lock uses: DeterminateSystems/update-flake-lock@v24 with: diff --git a/LICENSE b/LICENSE index 5a9b130ab..78b5f88cd 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2017-2023 Home Manager contributors +Copyright (c) 2017-2025 Home Manager contributors Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index 075ccaae8..d90efb9e6 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ Releases Home Manager is developed against `nixpkgs-unstable` branch, which often causes it to contain tweaks for changes/packages not yet released in stable [NixOS][]. To avoid breaking users' configurations, Home Manager is released in branches -corresponding to NixOS releases (e.g. `release-24.05`). These branches get +corresponding to NixOS releases (e.g. `release-24.11`). These branches get fixes, but usually not new modules. If you need a module to be backported, then feel free to open an issue. @@ -49,7 +49,7 @@ dconf store and cannot tell whether a configuration that it is about to be overwritten was from a previous Home Manager generation or from manual configuration. -Home Manager targets [NixOS][] unstable and NixOS version 24.05 (the current +Home Manager targets [NixOS][] unstable and NixOS version 24.11 (the current stable version), it may or may not work on other Linux distributions and NixOS versions. diff --git a/default.nix b/default.nix index 541a5a388..abf4e678b 100644 --- a/default.nix +++ b/default.nix @@ -1,6 +1,12 @@ { pkgs ? import { } }: -rec { +let + path = builtins.path { + path = ./.; + name = "home-manager-source"; + }; + +in rec { docs = let releaseInfo = pkgs.lib.importJSON ./release.json; in with import ./docs { inherit pkgs; @@ -12,12 +18,13 @@ rec { jsonModuleMaintainers = jsonModuleMaintainers; # Unstable, mainly for CI. }; - home-manager = pkgs.callPackage ./home-manager { path = toString ./.; }; + home-manager = pkgs.callPackage ./home-manager { inherit path; }; install = pkgs.callPackage ./home-manager/install.nix { inherit home-manager; }; nixos = import ./nixos; + lib = import ./lib { inherit (pkgs) lib; }; - path = ./.; + inherit path; } diff --git a/docs/home-manager-manual.nix b/docs/home-manager-manual.nix index 23b2d1e65..f87803962 100644 --- a/docs/home-manager-manual.nix +++ b/docs/home-manager-manual.nix @@ -59,5 +59,7 @@ in stdenv.mkDerivation { echo "doc manual $dest index.html" >> $out/nix-support/hydra-build-products ''; + passthru = { inherit home-manager-options; }; + meta = { maintainers = [ lib.maintainers.considerate ]; }; } diff --git a/docs/home-manager.1 b/docs/home-manager.1 index 41406aca0..46ee43033 100644 --- a/docs/home-manager.1 +++ b/docs/home-manager.1 @@ -396,5 +396,5 @@ Author. .Sh COPYRIGHT .br -Copyright \(co 2017\(en2022 Home Manager contributors +Copyright \(co 2017\(en2025 Home Manager contributors .br diff --git a/docs/manual/contributing/tests.md b/docs/manual/contributing/tests.md index bc3956ae3..41eec3447 100644 --- a/docs/manual/contributing/tests.md +++ b/docs/manual/contributing/tests.md @@ -29,10 +29,16 @@ through $ nix-shell --pure tests -A run.alacritty-empty-settings ``` -However, those invocations will impurely source the system's nixpkgs, -and may cause failures. To run against the nixpkgs from the flake.lock, +However, those invocations will impurely source the system's Nixpkgs, +and may cause failures. To run against the Nixpkgs from the `flake.lock` file, use instead e.g. ``` shell -$ nix develop --ignore-environment .#all +$ nix build --reference-lock-file flake.lock ./tests#test-all +``` + +or + +``` shell +$ nix build --reference-lock-file flake.lock ./tests#test-alacritty-empty-settings ``` diff --git a/docs/manual/installation/nix-darwin.md b/docs/manual/installation/nix-darwin.md index f10253064..97ff95dab 100644 --- a/docs/manual/installation/nix-darwin.md +++ b/docs/manual/installation/nix-darwin.md @@ -15,10 +15,10 @@ $ nix-channel --add https://github.com/nix-community/home-manager/archive/master $ nix-channel --update ``` -and if you follow a Nixpkgs version 24.05 channel, you can run +and if you follow a Nixpkgs version 24.11 channel, you can run ``` shell -$ nix-channel --add https://github.com/nix-community/home-manager/archive/release-24.05.tar.gz home-manager +$ nix-channel --add https://github.com/nix-community/home-manager/archive/release-24.11.tar.gz home-manager $ nix-channel --update ``` @@ -45,7 +45,7 @@ home-manager.users.eve = { pkgs, ... }: { # The state version is required and should stay at the version you # originally installed. - home.stateVersion = "24.05"; + home.stateVersion = "24.11"; }; ``` diff --git a/docs/manual/installation/nixos.md b/docs/manual/installation/nixos.md index d432a54be..6ec201638 100644 --- a/docs/manual/installation/nixos.md +++ b/docs/manual/installation/nixos.md @@ -17,10 +17,10 @@ $ sudo nix-channel --add https://github.com/nix-community/home-manager/archive/m $ sudo nix-channel --update ``` -and if you follow a Nixpkgs version 24.05 channel, you can run +and if you follow a Nixpkgs version 24.11 channel, you can run ``` shell -$ sudo nix-channel --add https://github.com/nix-community/home-manager/archive/release-24.05.tar.gz home-manager +$ sudo nix-channel --add https://github.com/nix-community/home-manager/archive/release-24.11.tar.gz home-manager $ sudo nix-channel --update ``` @@ -42,9 +42,15 @@ home-manager.users.eve = { pkgs, ... }: { home.packages = [ pkgs.atool pkgs.httpie ]; programs.bash.enable = true; - # The state version is required and should stay at the version you - # originally installed. - home.stateVersion = "24.05"; + # This value determines the Home Manager release that your configuration is + # compatible with. This helps avoid breakage when a new Home Manager release + # introduces backwards incompatible changes. + # + # You should not change this value, even if you update Home Manager. If you do + # want to update the value, then make sure to first check the Home Manager + # release notes. + home.stateVersion = "24.05"; # Please read the comment before changing. + }; ``` diff --git a/docs/manual/installation/standalone.md b/docs/manual/installation/standalone.md index 4afb7f347..4d430af9d 100644 --- a/docs/manual/installation/standalone.md +++ b/docs/manual/installation/standalone.md @@ -19,10 +19,10 @@ $ nix-channel --update ``` - and if you follow a Nixpkgs version 24.05 channel you can run + and if you follow a Nixpkgs version 24.11 channel you can run ``` shell - $ nix-channel --add https://github.com/nix-community/home-manager/archive/release-24.05.tar.gz home-manager + $ nix-channel --add https://github.com/nix-community/home-manager/archive/release-24.11.tar.gz home-manager $ nix-channel --update ``` diff --git a/docs/manual/manual.md b/docs/manual/manual.md index 0f81642f7..2aa6024ae 100644 --- a/docs/manual/manual.md +++ b/docs/manual/manual.md @@ -1,6 +1,6 @@ # Home Manager Manual {#home-manager-manual} -## Version 24.05 (unstable) +## Version 25.05 (unstable) ```{=include=} preface diff --git a/docs/manual/nix-flakes.md b/docs/manual/nix-flakes.md index 93f71feb8..bd33120c6 100644 --- a/docs/manual/nix-flakes.md +++ b/docs/manual/nix-flakes.md @@ -30,6 +30,7 @@ nix-flakes/prerequisites.md nix-flakes/standalone.md nix-flakes/nixos.md nix-flakes/nix-darwin.md +nix-flakes/flake-parts.md ``` diff --git a/docs/manual/nix-flakes/flake-parts.md b/docs/manual/nix-flakes/flake-parts.md new file mode 100644 index 000000000..b314bef3c --- /dev/null +++ b/docs/manual/nix-flakes/flake-parts.md @@ -0,0 +1,39 @@ +# flake-parts module {#sec-flakes-flake-parts-module} + +When using [flake-parts](https://flake.parts) +you may wish to import Home Manager's flake module, +`flakeModules.home-manager`. + +``` nix +{ + description = "flake-parts configuration"; + + inputs = { + nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; + home-manager.url = "github:nix-community/home-manager"; + home-manager.inputs.nixpkgs.follows = "nixpkgs"; + flake-parts.url = "github:hercules-ci/flake-parts"; + }; + + outputs = inputs@{ flake-parts, ... }: + flake-parts.lib.mkFlake { inherit inputs; } { + imports = [ + # Import home-manager's flake module + inputs.home-manager.flakeModules.home-manager + ]; + flake = { + # Define `homeModules`, `homeConfigurations`, + # `nixosConfigurations`, etc here + }; + # See flake.parts for more features, such as `perSystem` + }; +} +``` + +The flake module defines the `flake.homeModules` and `flake.homeConfigurations` +options, allowing them to be properly merged if they are defined in multiple +modules. + +If you are only defining `homeModules` and/or `homeConfigurations` once in a +single module, flake-parts should work fine without importing +`flakeModules.home-manager`. diff --git a/docs/manual/nix-flakes/standalone.md b/docs/manual/nix-flakes/standalone.md index fc967f460..4cfac424c 100644 --- a/docs/manual/nix-flakes/standalone.md +++ b/docs/manual/nix-flakes/standalone.md @@ -11,10 +11,10 @@ then to generate and activate a basic configuration run the command $ nix run home-manager/master -- init --switch ``` -For Nixpkgs or NixOS version 24.05 run +For Nixpkgs or NixOS version 24.11 run ``` shell -$ nix run home-manager/release-24.05 -- init --switch +$ nix run home-manager/release-24.11 -- init --switch ``` This will generate a `flake.nix` and a `home.nix` file in @@ -30,7 +30,7 @@ $ # Edit files in ~/.config/home-manager $ nix run home-manager/$branch -- init --switch ``` -Where `$branch` is one of `master` or `release-24.05`. +Where `$branch` is one of `master` or `release-24.11`. After the initial activation has completed successfully then building and activating your flake-based configuration is as simple as diff --git a/docs/manual/usage.md b/docs/manual/usage.md index 2a569aaf9..88e884546 100644 --- a/docs/manual/usage.md +++ b/docs/manual/usage.md @@ -59,5 +59,6 @@ usage/configuration.md usage/rollbacks.md usage/dotfiles.md usage/graphical.md +usage/gpu-non-nixos.md usage/updating.md ``` diff --git a/docs/manual/usage/configuration.md b/docs/manual/usage/configuration.md index deb046a6b..868b93521 100644 --- a/docs/manual/usage/configuration.md +++ b/docs/manual/usage/configuration.md @@ -20,7 +20,7 @@ A fresh install of Home Manager will generate a minimal # You can update Home Manager without changing this value. See # the Home Manager release notes for a list of state version # changes in each release. - home.stateVersion = "24.05"; + home.stateVersion = "24.11"; # Let Home Manager install and manage itself. programs.home-manager.enable = true; @@ -65,7 +65,7 @@ follows: # You can update Home Manager without changing this value. See # the Home Manager release notes for a list of state version # changes in each release. - home.stateVersion = "24.05"; + home.stateVersion = "24.11"; # Let Home Manager install and manage itself. programs.home-manager.enable = true; diff --git a/docs/manual/usage/gpu-non-nixos.md b/docs/manual/usage/gpu-non-nixos.md new file mode 100644 index 000000000..0aefa4ae3 --- /dev/null +++ b/docs/manual/usage/gpu-non-nixos.md @@ -0,0 +1,81 @@ +# GPU on non-NixOS systems {#sec-usage-gpu-non-nixos} + +To access the GPU, programs need access to OpenGL and Vulkan libraries. While +this works transparently on NixOS, it does not on other Linux systems. A +solution is provided by [NixGL](https://github.com/nix-community/nixGL), which +can be integrated into Home Manager. + +To enable the integration, import NixGL into your home configuration, either as +a channel, or as a flake input passed via `extraSpecialArgs`. Then, set the +`nixGL.packages` option to the package set provided by NixGL. + +Once integration is enabled, it can be used in two ways: as Nix functions for +wrapping programs installed via Home Manager, and as shell commands for running +programs installed by other means (such as `nix shell`). In either case, there +are several wrappers available. They can be broadly categorized + +- by vendor: as Mesa (for Free drivers of all vendors) and Nvidia (for + Nvidia-specific proprietary drivers). +- by GPU selection: as primary and secondary (offloading). + +For example, the `mesa` wrapper provides support for running programs on the +primary GPU for Intel, AMD and Nouveau drivers, while the `mesaPrime` wrapper +does the same for the secondary GPU. + +**Note:** when using Nvidia wrappers together with flakes, your home +configuration will not be pure and needs to be built using `home-manager switch +--impure`. Otherwise, the build will fail, complaining about missing attribute +`currentTime`. + +Wrapper functions are available under `config.lib.nixGL.wrappers`. However, it +can be more convenient to use the `config.lib.nixGL.wrap` alias, which can be +configured to use any of the wrappers. It is intended to provide a customization +point when the same home configuration is used across several machines with +different hardware. There is also the `config.lib.nixGL.wrapOffload` alias for +two-GPU systems. + +Another convenience is that all wrapper functions are always available. However, +when `nixGL.packages` option is unset, they are no-ops. This allows them to be +used even when the home configuration is used on NixOS machines. The exception +is the `prime-offload` script which ignores `nixGL.packages` and is installed +into the environment whenever `nixGL.prime.installScript` is set. This script, +which can be used to start a program on a secondary GPU, does not depend on +NixGL and is useful on NixOS systems as well. + +Below is an abbreviated example for an Optimus laptop that makes use of both +Mesa and Nvidia wrappers, where the latter is used in dGPU offloading mode. It +demonstrates how to wrap `mpv` to run on the integrated Intel GPU, wrap FreeCAD +to run on the Nvidia dGPU, and how to install the wrapper scripts. It also wraps +Xonotic to run on the dGPU, but uses the wrapper function directly for +demonstration purposes. + +```nix +{ config, lib, pkgs, nixgl, ... }: +{ + nixGL.packages = nixgl.packages; + nixGL.defaultWrapper = "mesa"; + nixGL.offloadWrapper = "nvidiaPrime"; + nixGL.installScripts = [ "mesa" "nvidiaPrime" ]; + + programs.mpv = { + enable = true; + package = config.lib.nixGL.wrap pkgs.mpv; + }; + + home.packages = [ + (config.lib.nixGL.wrapOffload pkgs.freecad) + (config.lib.nixGL.wrappers.nvidiaPrime pkgs.xonotic) + ]; +} +``` + +The above example assumes a flake-based setup where `nixgl` was passed from the +flake. When using channels, the example would instead begin with + +```nix +{ config, lib, pkgs, ... }: +{ + nixGL.packages = import { inherit pkgs; }; + # The rest is the same as above + ... +``` diff --git a/docs/release-notes/release-notes.md b/docs/release-notes/release-notes.md index dabeba0c9..b7d1b4380 100644 --- a/docs/release-notes/release-notes.md +++ b/docs/release-notes/release-notes.md @@ -4,6 +4,7 @@ This section lists the release notes for stable versions of Home Manager and the current unstable version. ```{=include=} chapters +rl-2505.md rl-2411.md rl-2405.md rl-2311.md diff --git a/docs/release-notes/rl-2411.md b/docs/release-notes/rl-2411.md index 6f7a6b7b0..b30cf2dc3 100644 --- a/docs/release-notes/rl-2411.md +++ b/docs/release-notes/rl-2411.md @@ -1,7 +1,6 @@ # Release 24.11 {#sec-release-24.11} -This is the current unstable branch and the information in this section -is therefore not final. +The 24.11 release branch became stable in November, 2024. ## Highlights {#sec-release-24.11-highlights} @@ -18,10 +17,15 @@ This release has the following notable changes: add `-w` to your assignment of [services.swayidle.extraArgs](#opt-services.swayidle.extraArgs). +- Support for Boolean values in the option + [programs.eza.icons](#opt-programs.eza.icons) is deprecated for + future removal. The new value for `true` is `"auto"`, and for + `false` it is `null`. + ## State Version Changes {#sec-release-24.11-state-version-changes} The state version in this release includes the changes below. These changes are only active if the `home.stateVersion` option is set to \"24.11\" or later. -- No changes. +- There was no state version change in this release. diff --git a/docs/release-notes/rl-2505.md b/docs/release-notes/rl-2505.md new file mode 100644 index 000000000..588ce5b47 --- /dev/null +++ b/docs/release-notes/rl-2505.md @@ -0,0 +1,31 @@ +# Release 25.05 {#sec-release-25.05} + +This is the current unstable branch and the information in this +section is therefore not final. + +## Highlights {#sec-release-25.05-highlights} + +This release has the following notable changes: + +- The [](#opt-systemd.user.startServices) option now defaults to + `true`, meaning that services will automatically be restarted as + needed when activating a configuration. + + Further, the `"legacy"` alternative has been removed and will now + result in an evaluation error if used. + + The `"suggest"` alternative will remain for a while longer but may + also be deprecated for removal in the future. + +- The Home Manager test suite has been removed from the main Nix Flake + since it caused unnecessary evaluations and downloads. Instead the + tests are available through a Nix Flake file inside the `tests` + directory. See [](#sec-tests) for example commands. + +## State Version Changes {#sec-release-25.05-state-version-changes} + +The state version in this release includes the changes below. These +changes are only active if the `home.stateVersion` option is set to +\"25.05\" or later. + +- No changes. diff --git a/flake-module.nix b/flake-module.nix new file mode 100644 index 000000000..cc5f1551a --- /dev/null +++ b/flake-module.nix @@ -0,0 +1,33 @@ +{ lib, flake-parts-lib, moduleLocation, ... }: +let inherit (lib) toString mapAttrs mkOption types; +in { + options = { + flake = flake-parts-lib.mkSubmoduleOptions { + homeConfigurations = mkOption { + type = types.lazyAttrsOf types.raw; + default = { }; + description = '' + Instantiated Home Manager configurations. + + `homeConfigurations` is for specific installations. If you want to expose + reusable configurations, add them to `homeModules` in the form of modules, so + that you can reference them in this or another flake's `homeConfigurations`. + ''; + }; + homeModules = mkOption { + type = types.lazyAttrsOf types.deferredModule; + default = { }; + apply = mapAttrs (k: v: { + _class = "homeManager"; + _file = "${toString moduleLocation}#homeModules.${k}"; + imports = [ v ]; + }); + description = '' + Home Manager modules. + + You may use this for reusable pieces of configuration, service modules, etc. + ''; + }; + }; + }; +} diff --git a/flake.lock b/flake.lock index 557a2e855..dd029164e 100644 --- a/flake.lock +++ b/flake.lock @@ -2,11 +2,11 @@ "nodes": { "nixpkgs": { "locked": { - "lastModified": 1726937504, - "narHash": "sha256-bvGoiQBvponpZh8ClUcmJ6QnsNKw0EMrCQJARK3bI1c=", + "lastModified": 1741513245, + "narHash": "sha256-7rTAMNTY1xoBwz0h7ZMtEcd8LELk9R5TzBPoHuhNSCk=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "9357f4f23713673f310988025d9dc261c20e70c6", + "rev": "e3e32b642a31e6714ec1b712de8c91a3352ce7e1", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index 3a90f89c0..918507dde 100644 --- a/flake.nix +++ b/flake.nix @@ -6,24 +6,22 @@ outputs = { self, nixpkgs, ... }: { nixosModules = rec { - home-manager = import ./nixos; + home-manager = ./nixos; default = home-manager; }; - # deprecated in Nix 2.8 - nixosModule = self.nixosModules.default; darwinModules = rec { - home-manager = import ./nix-darwin; + home-manager = ./nix-darwin; + default = home-manager; + }; + + flakeModules = rec { + home-manager = ./flake-module.nix; default = home-manager; }; - # unofficial; deprecated in Nix 2.8 - darwinModule = self.darwinModules.default; templates = { - standalone = { - path = ./templates/standalone; - description = "Standalone setup"; - }; + default = self.templates.standalone; nixos = { path = ./templates/nixos; description = "Home Manager as a NixOS module,"; @@ -32,69 +30,16 @@ path = ./templates/nix-darwin; description = "Home Manager as a nix-darwin module,"; }; + standalone = { + path = ./templates/standalone; + description = "Standalone setup"; + }; }; - defaultTemplate = self.templates.standalone; - - lib = { - hm = (import ./modules/lib/stdlib-extended.nix nixpkgs.lib).hm; - homeManagerConfiguration = { modules ? [ ], pkgs, lib ? pkgs.lib - , extraSpecialArgs ? { }, check ? true - # Deprecated: - , configuration ? null, extraModules ? null, stateVersion ? null - , username ? null, homeDirectory ? null, system ? null }@args: - let - msgForRemovedArg = '' - The 'homeManagerConfiguration' arguments - - - 'configuration', - - 'username', - - 'homeDirectory' - - 'stateVersion', - - 'extraModules', and - - 'system' - - have been removed. Instead use the arguments 'pkgs' and - 'modules'. See the 22.11 release notes for more: https://nix-community.github.io/home-manager/release-notes.xhtml#sec-release-22.11-highlights - ''; - - throwForRemovedArgs = v: - let - used = builtins.filter (n: (args.${n} or null) != null) [ - "configuration" - "username" - "homeDirectory" - "stateVersion" - "extraModules" - "system" - ]; - msg = msgForRemovedArg + '' - - - Deprecated args passed: '' - + builtins.concatStringsSep " " used; - in lib.throwIf (used != [ ]) msg v; - - in throwForRemovedArgs (import ./modules { - inherit pkgs lib check extraSpecialArgs; - configuration = { ... }: { - imports = modules ++ [{ programs.home-manager.path = "${./.}"; }]; - nixpkgs = { - config = nixpkgs.lib.mkDefault pkgs.config; - inherit (pkgs) overlays; - }; - }; - }); - }; + lib = import ./lib { inherit (nixpkgs) lib; }; } // (let forAllSystems = nixpkgs.lib.genAttrs nixpkgs.lib.systems.flakeExposed; in { - devShells = forAllSystems (system: - let - pkgs = nixpkgs.legacyPackages.${system}; - tests = import ./tests { inherit pkgs; }; - in tests.run); - formatter = forAllSystems (system: let pkgs = nixpkgs.legacyPackages.${system}; in pkgs.linkFarm "format" [{ @@ -105,23 +50,12 @@ packages = forAllSystems (system: let pkgs = nixpkgs.legacyPackages.${system}; - lib = pkgs.lib; releaseInfo = nixpkgs.lib.importJSON ./release.json; docs = import ./docs { inherit pkgs; inherit (releaseInfo) release isReleaseBranch; }; - hmPkg = pkgs.callPackage ./home-manager { path = "${./.}"; }; - - testPackages = let - tests = import ./tests { inherit pkgs; }; - renameTestPkg = n: lib.nameValuePair "test-${n}"; - in lib.mapAttrs' renameTestPkg tests.build; - - integrationTestPackages = let - tests = import ./tests/integration { inherit pkgs; }; - renameTestPkg = n: lib.nameValuePair "integration-test-${n}"; - in lib.mapAttrs' renameTestPkg tests; + hmPkg = pkgs.callPackage ./home-manager { path = "${self}"; }; in { default = hmPkg; home-manager = hmPkg; @@ -129,8 +63,6 @@ docs-html = docs.manual.html; docs-json = docs.options.json; docs-manpages = docs.manPages; - } // testPackages // integrationTestPackages); - - defaultPackage = forAllSystems (system: self.packages.${system}.default); + }); }); } diff --git a/format b/format index 4f46c7b9e..2eb16d9af 100755 --- a/format +++ b/format @@ -1,6 +1,11 @@ #! /usr/bin/env nix-shell #! nix-shell -I nixpkgs=https://github.com/NixOS/nixpkgs/archive/6616de389ed55fba6eeba60377fc04732d5a207c.tar.gz -i bash -p git gnugrep gnused findutils nixfmt +# Avoid being affected by system and user git config. +export GIT_CONFIG_NOSYSTEM=1 +export HOME= +export XDG_CONFIG_HOME= + nixfmt_args=() files=() diff --git a/home-manager/default.nix b/home-manager/default.nix index 50fda77e5..6b594c4fd 100644 --- a/home-manager/default.nix +++ b/home-manager/default.nix @@ -16,12 +16,12 @@ let in runCommand "home-manager" { preferLocalBuild = true; nativeBuildInputs = [ gettext ]; - meta = with lib; { + meta = { mainProgram = "home-manager"; description = "A user environment configurator"; - maintainers = [ maintainers.rycee ]; - platforms = platforms.unix; - license = licenses.mit; + maintainers = [ lib.maintainers.rycee ]; + platforms = lib.platforms.unix; + license = lib.licenses.mit; }; } '' install -v -D -m755 ${./home-manager} $out/bin/home-manager diff --git a/home-manager/home-manager b/home-manager/home-manager index 5bf796b47..e64bb884d 100644 --- a/home-manager/home-manager +++ b/home-manager/home-manager @@ -52,6 +52,11 @@ function hasFlakeSupport() { | grep -q nix-command } +# Escape string for use in Nix files. +function escapeForNix() { + printf %s "$1" | sed 's/["$\\]/\\\0/g' +} + # Attempts to set the HOME_MANAGER_CONFIG global variable. # # If no configuration file can be found then this function will print @@ -186,7 +191,7 @@ function setFlakeAttribute() { fi if [[ -v configFlake ]]; then - FLAKE_ARG="path:$(dirname "$(readlink -f "$configFlake")")" + FLAKE_ARG="$(dirname "$(readlink -f "$configFlake")")" fi fi @@ -201,7 +206,7 @@ function setFlakeAttribute() { # Check FQDN, long, and short hostnames; long first to preserve # pre-existing behaviour in case both happen to be defined. for n in "$USER@$(hostname -f)" "$USER@$(hostname)" "$USER@$(hostname -s)"; do - if [[ "$(nix eval "$flake#homeConfigurations" --apply "x: x ? \"$n\"")" == "true" ]]; then + if [[ "$(nix eval "$flake#homeConfigurations" --apply "x: x ? \"$(escapeForNix "$n")\"")" == "true" ]]; then name="$n" if [[ -v VERBOSE ]]; then echo "Using flake homeConfiguration for $name" @@ -210,7 +215,7 @@ function setFlakeAttribute() { done ;; esac - export FLAKE_CONFIG_URI="$flake#homeConfigurations.\"$name\"" + export FLAKE_CONFIG_URI="$flake#homeConfigurations.\"$(printf %s "$name" | jq -sRr @uri)\"" fi } @@ -349,8 +354,8 @@ function doInit() { { # Home Manager needs a bit of information about you and the paths it should # manage. - home.username = "$USER"; - home.homeDirectory = "$HOME"; + home.username = "$(escapeForNix "$USER")"; + home.homeDirectory = "$(escapeForNix "$HOME")"; $xdgVars # This value determines the Home Manager release that your configuration is # compatible with. This helps avoid breakage when a new Home Manager release @@ -359,7 +364,7 @@ $xdgVars # You should not change this value, even if you update Home Manager. If you do # want to update the value, then make sure to first check the Home Manager # release notes. - home.stateVersion = "24.05"; # Please read the comment before changing. + home.stateVersion = "24.11"; # Please read the comment before changing. # The home.packages option allows you to install Nix packages into your # environment. @@ -439,7 +444,7 @@ EOF mkdir -p "$confDir" cat > "$flakeFile" <' \ - --arg newsJsonFile "$newsJsonFile" \ - --arg newsReadIdsFile "$readIdsFile" \ + --arg newsJsonFile "\"$(escapeForNix "$newsJsonFile")\"" \ + --arg newsReadIdsFile "\"$(escapeForNix "$readIdsFile")\"" \ "${extraArgs[@]}" \ > "$newsNixFile" } @@ -802,23 +807,23 @@ function doShowNews() { local readIdsFile readIdsFile="$(newsReadIdsFile)" - local news + local newsAttr - # shellcheck disable=2154,2046 case $1 in --all) - news="$(nix-instantiate --quiet --eval --expr "(import ${newsNixFile}).news.all")" + newsAttr="all" ;; --unread) - news="$(nix-instantiate --quiet --eval --expr "(import ${newsNixFile}).news.unread")" + newsAttr="unread" ;; *) _i 'Unknown argument %s' "$1" return 1 esac - # Prints the news without surrounding quotes. - echo -e "${news:1:-1}" | ${PAGER:-less} + nix-instantiate --quiet --eval --json --expr "(import ${newsNixFile}).news.$newsAttr" \ + | jq -r . \ + | ${PAGER:-less} local allIds allIds="$(nix-instantiate --quiet --eval --expr "(import ${newsNixFile}).meta.ids")" @@ -855,9 +860,9 @@ function doUninstall() { cat > "$HOME_MANAGER_CONFIG" <, YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: Home Manager\n" +"Report-Msgid-Bugs-To: https://github.com/nix-community/home-manager/issues\n" +"POT-Creation-Date: 2025-01-03 09:09+0100\n" +"PO-Revision-Date: 2025-01-30 16:22+0000\n" +"Last-Translator: Kiril Pan \n" +"Language-Team: Bulgarian \n" +"Language: bg\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 5.10-dev\n" + +#. translators: For example: "home-manager: missing argument for --cores" +#: home-manager/home-manager:16 +msgid "%s: missing argument for %s" +msgstr "%s: липсващ аргумент за %s" + +#: home-manager/home-manager:69 +msgid "No configuration file found at %s" +msgstr "Не е намерен конфигурационен файл на %s" + +#. translators: The first '%s' specifier will be replaced by either +#. 'home.nix' or 'flake.nix'. +#: home-manager/home-manager:86 home-manager/home-manager:90 +#: home-manager/home-manager:189 +msgid "" +"Keeping your Home Manager %s in %s is deprecated,\n" +"please move it to %s" +msgstr "" +"Запазването на Вашия Домоуправител %s в %s \n" +"е остаряла практика, моля преместете го в %s" + +#: home-manager/home-manager:97 +msgid "No configuration file found. Please create one at %s" +msgstr "Конфигурационният файл не намерен. Моля създайте такъв в %s" + +#: home-manager/home-manager:112 +msgid "Home Manager not found at %s." +msgstr "Home Manager не е открит в %s." + +#. translators: This message will be seen by very few users that likely are familiar with English. So feel free to leave this untranslated. +#: home-manager/home-manager:120 +msgid "" +"The fallback Home Manager path %s has been deprecated and a file/directory " +"was found there." +msgstr "" +"Изборът на резервната локация на Home Manager в %s е остаряла практика и " +"файлът/директорията беше намерен/а там." + +#. translators: This message will be seen by very few users that likely are familiar with English. So feel free to leave this untranslated. +#: home-manager/home-manager:123 +msgid "" +"To remove this warning, do one of the following.\n" +"\n" +"1. Explicitly tell Home Manager to use the path, for example by adding\n" +"\n" +" { programs.home-manager.path = \"%s\"; }\n" +"\n" +" to your configuration.\n" +"\n" +" If you import Home Manager directly, you can use the `path` parameter\n" +"\n" +" pkgs.callPackage /path/to/home-manager-package { path = \"%s\"; }\n" +"\n" +" when calling the Home Manager package.\n" +"\n" +"2. Remove the deprecated path.\n" +"\n" +" $ rm -r \"%s\"" +msgstr "" +"За да премахнете това предупреждение, направенете една от следните опции:\n" +"\n" +"1. Изрично наредете на Home Manager да ползва локацията, като например " +"добавите:\n" +"\n" +" { programs.home-manager.path = \"%s\"; }\n" +"\n" +" в конфигурацията си.\n" +"\n" +" Ако импортирате Home Manager директно, можете да ползвате `path` " +"параметъра.\n" +"\n" +" pkgs.callPackage /path/to/home-manager-package { path = \"%s\"; }\n" +"\n" +" Когато повиквате Home Manager пакета.\n" +"\n" +"2. Премахнате остарялата локация.\n" +"\n" +" $ rm -r \"%s\"" + +#: home-manager/home-manager:151 +msgid "Sanity checking Nix" +msgstr "Разумна проверка на Nix" + +#: home-manager/home-manager:171 +msgid "Could not find suitable profile directory, tried %s and %s" +msgstr "Не е намерена подходяща профилна директория, пробвани са %s и %s" + +#. translators: Here "flake" is a noun that refers to the Nix Flakes feature. +#: home-manager/home-manager:226 +msgid "Can't inspect options of a flake configuration" +msgstr "Опциите на флейк конфигурацията не могат да бъдат прегледани" + +#: home-manager/home-manager:301 home-manager/home-manager:324 +#: home-manager/home-manager:1061 +msgid "%s: unknown option '%s'" +msgstr "%s: непозната опция '%s'" + +#: home-manager/home-manager:306 home-manager/home-manager:1062 +msgid "Run '%s --help' for usage help" +msgstr "Изпълнете командата '%s --help' за повече информация" + +#: home-manager/home-manager:332 home-manager/home-manager:437 +msgid "The file %s already exists, leaving it unchanged..." +msgstr "Файлът %s вече съществува, пропускане на промениете му..." + +#: home-manager/home-manager:334 home-manager/home-manager:439 +msgid "Creating %s..." +msgstr "Създаване на %s..." + +#: home-manager/home-manager:481 +msgid "Creating initial Home Manager generation..." +msgstr "Създаване на първоначалната Home Manager генерация..." + +#. translators: The "%s" specifier will be replaced by a file path. +#: home-manager/home-manager:486 +msgid "" +"All done! The home-manager tool should now be installed and you can edit\n" +"\n" +" %s\n" +"\n" +"to configure Home Manager. Run 'man home-configuration.nix' to\n" +"see all available options." +msgstr "" +"Всичко е готово! Инструментът home-manager е инсталиран и Вие можете да " +"редактирате\n" +"\n" +"....%s\n" +"\n" +"за да конфигурате Home Manager. Изпълнете командата 'man home-" +"configuration.nix'\n" +"за да видите всички налични опции." + +#. translators: The "%s" specifier will be replaced by a URL. +#: home-manager/home-manager:491 +msgid "" +"Uh oh, the installation failed! Please create an issue at\n" +"\n" +" %s\n" +"\n" +"if the error seems to be the fault of Home Manager." +msgstr "" +"О не, инсталацията се провали! Моля създайте запитване на\n" +"\n" +"....%s\n" +"\n" +"ако смятате, че грешката се дължи на Home Manager." + +#. translators: Here "flake" is a noun that refers to the Nix Flakes feature. +#: home-manager/home-manager:502 +msgid "Can't instantiate a flake configuration" +msgstr "Флейк конфигурацията не може да се инстанцира" + +#: home-manager/home-manager:578 +msgid "" +"There is %d unread and relevant news item.\n" +"Read it by running the command \"%s news\"." +msgid_plural "" +"There are %d unread and relevant news items.\n" +"Read them by running the command \"%s news\"." +msgstr[0] "" +"Има %d непрочетена релевантна новина.\n" +"Прочетете я като изпълните \"%s news\" командата." +msgstr[1] "" +"Има %d непрочетени релевантни новини.\n" +"Прочетете ги като изпълните \"%s news\" командата." + +#: home-manager/home-manager:592 +msgid "Unknown \"news.display\" setting \"%s\"." +msgstr "Непозната \"news.display\" настройка \"%s\"." + +#: home-manager/home-manager:600 +#, sh-format +msgid "Please set the $EDITOR or $VISUAL environment variable" +msgstr "Моля задайте $EDITOR или $VISUAL променливите на средата" + +#: home-manager/home-manager:618 +msgid "Cannot run build in read-only directory" +msgstr "" +"Компилацията не може да се стартира в директория предназначена само за четене" + +#: home-manager/home-manager:699 +msgid "No generation with ID %s" +msgstr "Не е намерена генерация с ID %s" + +#: home-manager/home-manager:701 +msgid "Cannot remove the current generation %s" +msgstr "Не може да бъде премахната сегашната генерация %s" + +#: home-manager/home-manager:703 +msgid "Removing generation %s" +msgstr "Премахване генерацията %s" + +#: home-manager/home-manager:724 +msgid "No generations to expire" +msgstr "Няма изтичащи генерации" + +#: home-manager/home-manager:735 +msgid "No home-manager packages seem to be installed." +msgstr "Изглежда няма нито един инсталиран home-manager пакет." + +#: home-manager/home-manager:820 +msgid "Unknown argument %s" +msgstr "Непознат аргумент %s" + +#: home-manager/home-manager:845 +msgid "This will remove Home Manager from your system." +msgstr "Това ще премахне Home Manager от системата Ви." + +#: home-manager/home-manager:848 +msgid "This is a dry run, nothing will actually be uninstalled." +msgstr "Това е сухо изпълнение - нищо няма да бъде деинсталирано." + +#: home-manager/home-manager:852 +msgid "Really uninstall Home Manager?" +msgstr "Наистина ли искате да деинсталирате Home Manager?" + +#: home-manager/home-manager:858 +msgid "Switching to empty Home Manager configuration..." +msgstr "Превключване към празна Home Manager конфигурация..." + +#: home-manager/home-manager:873 +msgid "Yay!" +msgstr "Ура!" + +#: home-manager/home-manager:878 +msgid "Home Manager is uninstalled but your home.nix is left untouched." +msgstr "" +"Home Manager бе деинсталиран но Вашия home.nix файл е оставен непроменен." + +#: home-manager/home-manager:1101 +msgid "expire-generations expects one argument, got %d." +msgstr "expire-generations очаква един аргумент, получил е %d." + +#: home-manager/home-manager:1123 +msgid "Unknown command: %s" +msgstr "Непозната команда: %s" + +#: home-manager/install.nix:18 +msgid "This derivation is not buildable, please run it using nix-shell." +msgstr "" +"Тази деривация не може да се компилира, моля стартирайте я ползвайки nix-" +"shell." diff --git a/home-manager/po/ca.po b/home-manager/po/ca.po index 12992995a..148a42ff9 100644 --- a/home-manager/po/ca.po +++ b/home-manager/po/ca.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: Home Manager\n" "Report-Msgid-Bugs-To: https://github.com/nix-community/home-manager/issues\n" -"POT-Creation-Date: 2024-04-17 23:19+0200\n" +"POT-Creation-Date: 2025-01-03 09:09+0100\n" "PO-Revision-Date: 2024-08-07 17:09+0000\n" "Last-Translator: Tomi Ockier \n" "Language-Team: Catalan \n" +"POT-Creation-Date: 2025-01-03 09:09+0100\n" +"PO-Revision-Date: 2024-12-22 17:00+0000\n" +"Last-Translator: David Chocholatý \n" "Language-Team: Czech \n" "Language: cs\n" @@ -17,21 +17,21 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=((n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2);\n" -"X-Generator: Weblate 5.4\n" +"X-Generator: Weblate 5.10-dev\n" #. translators: For example: "home-manager: missing argument for --cores" #: home-manager/home-manager:16 msgid "%s: missing argument for %s" -msgstr "" +msgstr "%s: chybějící argument pro %s" -#: home-manager/home-manager:64 +#: home-manager/home-manager:69 msgid "No configuration file found at %s" msgstr "V %s nebyl nalezen konfigurační soubor" #. translators: The first '%s' specifier will be replaced by either #. 'home.nix' or 'flake.nix'. -#: home-manager/home-manager:81 home-manager/home-manager:85 -#: home-manager/home-manager:184 +#: home-manager/home-manager:86 home-manager/home-manager:90 +#: home-manager/home-manager:189 msgid "" "Keeping your Home Manager %s in %s is deprecated,\n" "please move it to %s" @@ -39,16 +39,16 @@ msgstr "" "Udržovat Home Manager %s v %s je zastaralé,\n" "prosím přesuňte jej do %s" -#: home-manager/home-manager:92 +#: home-manager/home-manager:97 msgid "No configuration file found. Please create one at %s" msgstr "Konfigurační soubor nenalezen. Prosím vytvořte jej v %s" -#: home-manager/home-manager:107 +#: home-manager/home-manager:112 msgid "Home Manager not found at %s." msgstr "Home Manager nebyl nalezen v %s." #. translators: This message will be seen by very few users that likely are familiar with English. So feel free to leave this untranslated. -#: home-manager/home-manager:115 +#: home-manager/home-manager:120 msgid "" "The fallback Home Manager path %s has been deprecated and a file/directory " "was found there." @@ -57,7 +57,7 @@ msgstr "" "adresář." #. translators: This message will be seen by very few users that likely are familiar with English. So feel free to leave this untranslated. -#: home-manager/home-manager:118 +#: home-manager/home-manager:123 msgid "" "To remove this warning, do one of the following.\n" "\n" @@ -96,42 +96,42 @@ msgstr "" "\n" " $ rm -r \"%s\"" -#: home-manager/home-manager:146 +#: home-manager/home-manager:151 msgid "Sanity checking Nix" msgstr "Kontrola správnosti Nix" -#: home-manager/home-manager:166 +#: home-manager/home-manager:171 msgid "Could not find suitable profile directory, tried %s and %s" msgstr "Nebyl nalezen vhodný adresář profilu, byly zkoušeny %s a %s" #. translators: Here "flake" is a noun that refers to the Nix Flakes feature. -#: home-manager/home-manager:221 +#: home-manager/home-manager:226 msgid "Can't inspect options of a flake configuration" msgstr "Nelze ověřit parametry z konfigurace flake" -#: home-manager/home-manager:296 home-manager/home-manager:319 -#: home-manager/home-manager:1051 +#: home-manager/home-manager:301 home-manager/home-manager:324 +#: home-manager/home-manager:1061 msgid "%s: unknown option '%s'" msgstr "%s: neznámý parametr '%s'" -#: home-manager/home-manager:301 home-manager/home-manager:1052 +#: home-manager/home-manager:306 home-manager/home-manager:1062 msgid "Run '%s --help' for usage help" msgstr "Spusťte '%s --help' pro vypsání nápovědy" -#: home-manager/home-manager:327 home-manager/home-manager:431 +#: home-manager/home-manager:332 home-manager/home-manager:437 msgid "The file %s already exists, leaving it unchanged..." msgstr "Soubor %s již existuje, ponechán beze změn..." -#: home-manager/home-manager:329 home-manager/home-manager:433 +#: home-manager/home-manager:334 home-manager/home-manager:439 msgid "Creating %s..." msgstr "Vytvářím %s..." -#: home-manager/home-manager:475 +#: home-manager/home-manager:481 msgid "Creating initial Home Manager generation..." msgstr "Vytvářím první generaci Home Manageru..." #. translators: The "%s" specifier will be replaced by a file path. -#: home-manager/home-manager:480 +#: home-manager/home-manager:486 msgid "" "All done! The home-manager tool should now be installed and you can edit\n" "\n" @@ -148,7 +148,7 @@ msgstr "" "k zobrazení všech dostupných možností." #. translators: The "%s" specifier will be replaced by a URL. -#: home-manager/home-manager:485 +#: home-manager/home-manager:491 msgid "" "Uh oh, the installation failed! Please create an issue at\n" "\n" @@ -162,11 +162,11 @@ msgstr "" " %s" #. translators: Here "flake" is a noun that refers to the Nix Flakes feature. -#: home-manager/home-manager:496 +#: home-manager/home-manager:502 msgid "Can't instantiate a flake configuration" msgstr "Nelze vytvořit instanci flake konfigurace" -#: home-manager/home-manager:572 +#: home-manager/home-manager:578 msgid "" "There is %d unread and relevant news item.\n" "Read it by running the command \"%s news\"." @@ -183,72 +183,72 @@ msgstr[2] "" "%d nepřečtených novinek.\n" "Přečtěte je pomocí příkazu \"%s news\"." -#: home-manager/home-manager:586 +#: home-manager/home-manager:592 msgid "Unknown \"news.display\" setting \"%s\"." msgstr "Neznáme nastavení \"news.display\" \"%s\"." -#: home-manager/home-manager:594 +#: home-manager/home-manager:600 #, sh-format msgid "Please set the $EDITOR or $VISUAL environment variable" -msgstr "" +msgstr "Nastavte, prosím, proměnnou prostředí $EDITOR nebo $VISUAL" -#: home-manager/home-manager:612 +#: home-manager/home-manager:618 msgid "Cannot run build in read-only directory" msgstr "Sestavení nelze provést v adresáři dostupném pouze pro čtení" -#: home-manager/home-manager:693 +#: home-manager/home-manager:699 msgid "No generation with ID %s" msgstr "Generace s ID %s neexistuje" -#: home-manager/home-manager:695 +#: home-manager/home-manager:701 msgid "Cannot remove the current generation %s" msgstr "Nelze odstranit současnou generaci %s" -#: home-manager/home-manager:697 +#: home-manager/home-manager:703 msgid "Removing generation %s" msgstr "Odstraňuji generaci %s" -#: home-manager/home-manager:718 +#: home-manager/home-manager:724 msgid "No generations to expire" msgstr "Žádná generace k vypršení platnosti" -#: home-manager/home-manager:729 +#: home-manager/home-manager:735 msgid "No home-manager packages seem to be installed." msgstr "Žádný home-manager balíček není nainstalován." -#: home-manager/home-manager:811 +#: home-manager/home-manager:820 msgid "Unknown argument %s" msgstr "Neznámý parametr %s" -#: home-manager/home-manager:835 +#: home-manager/home-manager:845 msgid "This will remove Home Manager from your system." msgstr "Toto odstraní Home Manager z vašeho systému." -#: home-manager/home-manager:838 +#: home-manager/home-manager:848 msgid "This is a dry run, nothing will actually be uninstalled." msgstr "Toto zkouška na nečisto, nic nebude odinstalováno." -#: home-manager/home-manager:842 +#: home-manager/home-manager:852 msgid "Really uninstall Home Manager?" msgstr "Opravdu odinstalovat Home Manager?" -#: home-manager/home-manager:848 +#: home-manager/home-manager:858 msgid "Switching to empty Home Manager configuration..." msgstr "Přepínám na prázdou konfiguraci Home Manageru..." -#: home-manager/home-manager:863 +#: home-manager/home-manager:873 msgid "Yay!" msgstr "Hurá!" -#: home-manager/home-manager:868 +#: home-manager/home-manager:878 msgid "Home Manager is uninstalled but your home.nix is left untouched." msgstr "Home Manager se odinstalovává, ale váš home.nix nebyl změněn." -#: home-manager/home-manager:1091 +#: home-manager/home-manager:1101 msgid "expire-generations expects one argument, got %d." msgstr "expire-generations očekává jeden parametr, přítomno %d." -#: home-manager/home-manager:1113 +#: home-manager/home-manager:1123 msgid "Unknown command: %s" msgstr "Neznámý příkaz: %s" diff --git a/home-manager/po/da.po b/home-manager/po/da.po index b05d5c231..c93e5875c 100644 --- a/home-manager/po/da.po +++ b/home-manager/po/da.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: Home Manager\n" "Report-Msgid-Bugs-To: https://github.com/nix-community/home-manager/issues\n" -"POT-Creation-Date: 2024-04-17 23:19+0200\n" +"POT-Creation-Date: 2025-01-03 09:09+0100\n" "PO-Revision-Date: 2024-05-25 11:09+0000\n" "Last-Translator: DeeKahy \n" "Language-Team: Danish \n" "Language-Team: German \n" "Language-Team: Spanish \n" "Language-Team: Persian \n" +"POT-Creation-Date: 2025-01-03 09:09+0100\n" +"PO-Revision-Date: 2024-12-03 13:00+0000\n" +"Last-Translator: Ricky Tigg \n" "Language-Team: Finnish \n" "Language: fi\n" @@ -17,43 +17,45 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 5.6-dev\n" +"X-Generator: Weblate 5.9-dev\n" #. translators: For example: "home-manager: missing argument for --cores" #: home-manager/home-manager:16 msgid "%s: missing argument for %s" msgstr "%s: puuttuva argumentti kohteelle %s" -#: home-manager/home-manager:64 +#: home-manager/home-manager:69 msgid "No configuration file found at %s" -msgstr "Konfiguraatiotiedostoa ei löytynyt sijainnista %s" +msgstr "Kokoonpanotiedostoa ei löydy %s:sta" #. translators: The first '%s' specifier will be replaced by either #. 'home.nix' or 'flake.nix'. -#: home-manager/home-manager:81 home-manager/home-manager:85 -#: home-manager/home-manager:184 +#: home-manager/home-manager:86 home-manager/home-manager:90 +#: home-manager/home-manager:189 msgid "" "Keeping your Home Manager %s in %s is deprecated,\n" "please move it to %s" msgstr "" +"Home Managerin %s pitäminen %s:ssa on vanhentunut.\n" +"ole hyvä ja siirrä se %s:een" -#: home-manager/home-manager:92 +#: home-manager/home-manager:97 msgid "No configuration file found. Please create one at %s" -msgstr "Konfiguraatiotiedostoa ei löytynyt. Luo sellainen sijaintiin %s" +msgstr "Kokoonpanotiedostoa ei löytynyt. Luo sellainen %s:lla" -#: home-manager/home-manager:107 +#: home-manager/home-manager:112 msgid "Home Manager not found at %s." msgstr "Home Manageria ei löytynyt sijainnista %s." #. translators: This message will be seen by very few users that likely are familiar with English. So feel free to leave this untranslated. -#: home-manager/home-manager:115 +#: home-manager/home-manager:120 msgid "" "The fallback Home Manager path %s has been deprecated and a file/directory " "was found there." msgstr "" #. translators: This message will be seen by very few users that likely are familiar with English. So feel free to leave this untranslated. -#: home-manager/home-manager:118 +#: home-manager/home-manager:123 msgid "" "To remove this warning, do one of the following.\n" "\n" @@ -74,42 +76,42 @@ msgid "" " $ rm -r \"%s\"" msgstr "" -#: home-manager/home-manager:146 +#: home-manager/home-manager:151 msgid "Sanity checking Nix" msgstr "Nixin eheys tarkistetaan" -#: home-manager/home-manager:166 +#: home-manager/home-manager:171 msgid "Could not find suitable profile directory, tried %s and %s" msgstr "Sopivaa profiilihakemistoa ei löytynyt, yritettiin %s ja %s" #. translators: Here "flake" is a noun that refers to the Nix Flakes feature. -#: home-manager/home-manager:221 +#: home-manager/home-manager:226 msgid "Can't inspect options of a flake configuration" msgstr "Flake-konfiguraation asetuksia ei voi tarkastella" -#: home-manager/home-manager:296 home-manager/home-manager:319 -#: home-manager/home-manager:1051 +#: home-manager/home-manager:301 home-manager/home-manager:324 +#: home-manager/home-manager:1061 msgid "%s: unknown option '%s'" msgstr "%s: tuntematon vaihtoehto '%s" -#: home-manager/home-manager:301 home-manager/home-manager:1052 +#: home-manager/home-manager:306 home-manager/home-manager:1062 msgid "Run '%s --help' for usage help" msgstr "Aja '%s --help' saadaksesi käyttöohjeita" -#: home-manager/home-manager:327 home-manager/home-manager:431 +#: home-manager/home-manager:332 home-manager/home-manager:437 msgid "The file %s already exists, leaving it unchanged..." msgstr "Tiedosto %s on jo olemassa, jätetään se muuttumattomaksi..." -#: home-manager/home-manager:329 home-manager/home-manager:433 +#: home-manager/home-manager:334 home-manager/home-manager:439 msgid "Creating %s..." msgstr "Luodaan tiedostoa %s..." -#: home-manager/home-manager:475 +#: home-manager/home-manager:481 msgid "Creating initial Home Manager generation..." msgstr "Luodaan alkuperäistä Home Manager -generaatiota..." #. translators: The "%s" specifier will be replaced by a file path. -#: home-manager/home-manager:480 +#: home-manager/home-manager:486 msgid "" "All done! The home-manager tool should now be installed and you can edit\n" "\n" @@ -120,7 +122,7 @@ msgid "" msgstr "" #. translators: The "%s" specifier will be replaced by a URL. -#: home-manager/home-manager:485 +#: home-manager/home-manager:491 msgid "" "Uh oh, the installation failed! Please create an issue at\n" "\n" @@ -130,11 +132,11 @@ msgid "" msgstr "" #. translators: Here "flake" is a noun that refers to the Nix Flakes feature. -#: home-manager/home-manager:496 +#: home-manager/home-manager:502 msgid "Can't instantiate a flake configuration" msgstr "Flake-konfiguraatiota ei voi luoda" -#: home-manager/home-manager:572 +#: home-manager/home-manager:578 msgid "" "There is %d unread and relevant news item.\n" "Read it by running the command \"%s news\"." @@ -148,73 +150,73 @@ msgstr[1] "" "Sinulla on %d lukematonta ja oleellista uutisartikkelia.\n" "Lue ne ajamalla komento \"%s news\"." -#: home-manager/home-manager:586 +#: home-manager/home-manager:592 msgid "Unknown \"news.display\" setting \"%s\"." msgstr "Tuntematon asetus \"news.display\" \"%s\"." -#: home-manager/home-manager:594 +#: home-manager/home-manager:600 #, sh-format msgid "Please set the $EDITOR or $VISUAL environment variable" msgstr "Aseta $EDITOR- tai $VISUAL-ympäristömuuttujaksi" -#: home-manager/home-manager:612 +#: home-manager/home-manager:618 msgid "Cannot run build in read-only directory" msgstr "" -#: home-manager/home-manager:693 +#: home-manager/home-manager:699 msgid "No generation with ID %s" msgstr "" -#: home-manager/home-manager:695 +#: home-manager/home-manager:701 msgid "Cannot remove the current generation %s" msgstr "Nykyistä generaatiota %s ei voi poistaa" -#: home-manager/home-manager:697 +#: home-manager/home-manager:703 msgid "Removing generation %s" msgstr "Generaatio %s poistetaan" -#: home-manager/home-manager:718 +#: home-manager/home-manager:724 msgid "No generations to expire" msgstr "" -#: home-manager/home-manager:729 +#: home-manager/home-manager:735 msgid "No home-manager packages seem to be installed." msgstr "Näyttää siltä, ettei yhtään home-manager-pakettia ole asennettu." -#: home-manager/home-manager:811 +#: home-manager/home-manager:820 msgid "Unknown argument %s" msgstr "Tuntematon argumentti %s" -#: home-manager/home-manager:835 +#: home-manager/home-manager:845 msgid "This will remove Home Manager from your system." msgstr "Tämä poistaa Home Managerin järjestelmästäsi." -#: home-manager/home-manager:838 +#: home-manager/home-manager:848 msgid "This is a dry run, nothing will actually be uninstalled." msgstr "Tämä on kuivaharjoitus, mitään ei oikeasti poisteta." -#: home-manager/home-manager:842 +#: home-manager/home-manager:852 msgid "Really uninstall Home Manager?" msgstr "Haluatko varmasti poistaa Home Managerin?" -#: home-manager/home-manager:848 +#: home-manager/home-manager:858 msgid "Switching to empty Home Manager configuration..." msgstr "Vaihdetaan tyhjään Home Manager -konfiguraatioon..." -#: home-manager/home-manager:863 +#: home-manager/home-manager:873 msgid "Yay!" msgstr "Jes!" -#: home-manager/home-manager:868 +#: home-manager/home-manager:878 msgid "Home Manager is uninstalled but your home.nix is left untouched." msgstr "" "Home Manager on poistettu, mutta home.nix-tiedostosi jää koskemattomaksi." -#: home-manager/home-manager:1091 +#: home-manager/home-manager:1101 msgid "expire-generations expects one argument, got %d." msgstr "" -#: home-manager/home-manager:1113 +#: home-manager/home-manager:1123 msgid "Unknown command: %s" msgstr "Tuntematon komento: %s" diff --git a/home-manager/po/fr.po b/home-manager/po/fr.po index de1c061bf..af18581d5 100644 --- a/home-manager/po/fr.po +++ b/home-manager/po/fr.po @@ -7,9 +7,9 @@ msgid "" msgstr "" "Project-Id-Version: Home Manager\n" "Report-Msgid-Bugs-To: https://github.com/nix-community/home-manager/issues\n" -"POT-Creation-Date: 2024-04-17 23:19+0200\n" -"PO-Revision-Date: 2024-04-29 18:07+0000\n" -"Last-Translator: Michael Thomas \n" +"POT-Creation-Date: 2025-01-03 09:09+0100\n" +"PO-Revision-Date: 2025-01-05 15:00+0000\n" +"Last-Translator: Dorian Burgun \n" "Language-Team: French \n" "Language: fr\n" @@ -17,21 +17,21 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n > 1;\n" -"X-Generator: Weblate 5.5.2\n" +"X-Generator: Weblate 5.10-dev\n" #. translators: For example: "home-manager: missing argument for --cores" #: home-manager/home-manager:16 msgid "%s: missing argument for %s" -msgstr "%s : argument manquant pour %s" +msgstr "%s: argument manquant pour %s" -#: home-manager/home-manager:64 +#: home-manager/home-manager:69 msgid "No configuration file found at %s" msgstr "Aucun fichier de configuration trouvé à l'emplacement %s" #. translators: The first '%s' specifier will be replaced by either #. 'home.nix' or 'flake.nix'. -#: home-manager/home-manager:81 home-manager/home-manager:85 -#: home-manager/home-manager:184 +#: home-manager/home-manager:86 home-manager/home-manager:90 +#: home-manager/home-manager:189 msgid "" "Keeping your Home Manager %s in %s is deprecated,\n" "please move it to %s" @@ -39,18 +39,18 @@ msgstr "" "Garder votre Home Manager %s dans %s est obsolète,\n" "Veuillez le déplacer à %s" -#: home-manager/home-manager:92 +#: home-manager/home-manager:97 msgid "No configuration file found. Please create one at %s" msgstr "" "Aucun fichier de configuration trouvé. Veuillez en créer un à l'emplacement " "%s" -#: home-manager/home-manager:107 +#: home-manager/home-manager:112 msgid "Home Manager not found at %s." msgstr "Home Manager indisponible à %s." #. translators: This message will be seen by very few users that likely are familiar with English. So feel free to leave this untranslated. -#: home-manager/home-manager:115 +#: home-manager/home-manager:120 msgid "" "The fallback Home Manager path %s has been deprecated and a file/directory " "was found there." @@ -59,7 +59,7 @@ msgstr "" "dossier y a été trouvé." #. translators: This message will be seen by very few users that likely are familiar with English. So feel free to leave this untranslated. -#: home-manager/home-manager:118 +#: home-manager/home-manager:123 msgid "" "To remove this warning, do one of the following.\n" "\n" @@ -95,42 +95,42 @@ msgstr "" "\n" "\t$ rm -r \"%s\"" -#: home-manager/home-manager:146 +#: home-manager/home-manager:151 msgid "Sanity checking Nix" msgstr "Vérification de Nix" -#: home-manager/home-manager:166 +#: home-manager/home-manager:171 msgid "Could not find suitable profile directory, tried %s and %s" msgstr "Impossible de trouver le dossier de profil approprié, essayé %s et %s" #. translators: Here "flake" is a noun that refers to the Nix Flakes feature. -#: home-manager/home-manager:221 +#: home-manager/home-manager:226 msgid "Can't inspect options of a flake configuration" msgstr "Impossible d'inspecter les options de la configuration d'un flake" -#: home-manager/home-manager:296 home-manager/home-manager:319 -#: home-manager/home-manager:1051 +#: home-manager/home-manager:301 home-manager/home-manager:324 +#: home-manager/home-manager:1061 msgid "%s: unknown option '%s'" msgstr "%s : option inconnue '%s'" -#: home-manager/home-manager:301 home-manager/home-manager:1052 +#: home-manager/home-manager:306 home-manager/home-manager:1062 msgid "Run '%s --help' for usage help" msgstr "Exécuter « %s --help » pour de l'aide sur l'utilisation" -#: home-manager/home-manager:327 home-manager/home-manager:431 +#: home-manager/home-manager:332 home-manager/home-manager:437 msgid "The file %s already exists, leaving it unchanged..." msgstr "Le fichier %s existe déjà, il sera laissé inchangé..." -#: home-manager/home-manager:329 home-manager/home-manager:433 +#: home-manager/home-manager:334 home-manager/home-manager:439 msgid "Creating %s..." msgstr "Création de %s ..." -#: home-manager/home-manager:475 +#: home-manager/home-manager:481 msgid "Creating initial Home Manager generation..." msgstr "Création de la génération initiale de Home Manager..." #. translators: The "%s" specifier will be replaced by a file path. -#: home-manager/home-manager:480 +#: home-manager/home-manager:486 msgid "" "All done! The home-manager tool should now be installed and you can edit\n" "\n" @@ -148,7 +148,7 @@ msgstr "" "essayez 'man home-configuration.nix'." #. translators: The "%s" specifier will be replaced by a URL. -#: home-manager/home-manager:485 +#: home-manager/home-manager:491 msgid "" "Uh oh, the installation failed! Please create an issue at\n" "\n" @@ -164,11 +164,11 @@ msgstr "" "si l'erreur semble être liée à Home Manager." #. translators: Here "flake" is a noun that refers to the Nix Flakes feature. -#: home-manager/home-manager:496 +#: home-manager/home-manager:502 msgid "Can't instantiate a flake configuration" msgstr "Impossible d'instancier une configuration flake" -#: home-manager/home-manager:572 +#: home-manager/home-manager:578 msgid "" "There is %d unread and relevant news item.\n" "Read it by running the command \"%s news\"." @@ -182,72 +182,72 @@ msgstr[1] "" "Il y a %d nouveaux éléments non lus et pertinents.\n" "Vous pouvez les lire en exécutant la commande \"%s news\"." -#: home-manager/home-manager:586 +#: home-manager/home-manager:592 msgid "Unknown \"news.display\" setting \"%s\"." msgstr "Configuration \"news.display\" inconnue \"%s\"." -#: home-manager/home-manager:594 +#: home-manager/home-manager:600 #, sh-format msgid "Please set the $EDITOR or $VISUAL environment variable" msgstr "Veuillez remplir la variable d'environnement $EDITOR ou VISUAL" -#: home-manager/home-manager:612 +#: home-manager/home-manager:618 msgid "Cannot run build in read-only directory" msgstr "Impossible de lancer une compilation dans un dossier en écriture seule" -#: home-manager/home-manager:693 +#: home-manager/home-manager:699 msgid "No generation with ID %s" msgstr "Aucune génération avec l'ID %s" -#: home-manager/home-manager:695 +#: home-manager/home-manager:701 msgid "Cannot remove the current generation %s" msgstr "Impossible de supprimer la génération courante %s" -#: home-manager/home-manager:697 +#: home-manager/home-manager:703 msgid "Removing generation %s" msgstr "Suppression de la génération %s" -#: home-manager/home-manager:718 +#: home-manager/home-manager:724 msgid "No generations to expire" msgstr "Aucune génération expirée" -#: home-manager/home-manager:729 +#: home-manager/home-manager:735 msgid "No home-manager packages seem to be installed." msgstr "Aucun package home-manager ne semble être installé." -#: home-manager/home-manager:811 +#: home-manager/home-manager:820 msgid "Unknown argument %s" msgstr "Argument inconnu %s" -#: home-manager/home-manager:835 +#: home-manager/home-manager:845 msgid "This will remove Home Manager from your system." msgstr "Cela va supprimer Home Manager de votre système." -#: home-manager/home-manager:838 +#: home-manager/home-manager:848 msgid "This is a dry run, nothing will actually be uninstalled." msgstr "C'est un essai, rien ne sera réellement désinstallé." -#: home-manager/home-manager:842 +#: home-manager/home-manager:852 msgid "Really uninstall Home Manager?" msgstr "Voulez-vous vraiment désinstaller Home Manager ?" -#: home-manager/home-manager:848 +#: home-manager/home-manager:858 msgid "Switching to empty Home Manager configuration..." msgstr "Changement vers une configuration vierge de Home Manager..." -#: home-manager/home-manager:863 +#: home-manager/home-manager:873 msgid "Yay!" msgstr "Yay !" -#: home-manager/home-manager:868 +#: home-manager/home-manager:878 msgid "Home Manager is uninstalled but your home.nix is left untouched." msgstr "Home Manager est désinstallé mais votre home.nix reste intact." -#: home-manager/home-manager:1091 +#: home-manager/home-manager:1101 msgid "expire-generations expects one argument, got %d." msgstr "expire-generations attend un argument, a obtenu %d." -#: home-manager/home-manager:1113 +#: home-manager/home-manager:1123 msgid "Unknown command: %s" msgstr "Commande inconnue : %s" diff --git a/home-manager/po/hi.po b/home-manager/po/hi.po index 43d873123..171aebb77 100644 --- a/home-manager/po/hi.po +++ b/home-manager/po/hi.po @@ -7,9 +7,9 @@ msgid "" msgstr "" "Project-Id-Version: Home Manager\n" "Report-Msgid-Bugs-To: https://github.com/nix-community/home-manager/issues\n" -"POT-Creation-Date: 2024-04-17 23:19+0200\n" -"PO-Revision-Date: 2024-09-13 03:09+0000\n" -"Last-Translator: Jay Thomas \n" +"POT-Creation-Date: 2025-01-03 09:09+0100\n" +"PO-Revision-Date: 2024-10-09 14:31+0000\n" +"Last-Translator: Utkarsh Sharma \n" "Language-Team: Hindi \n" "Language: hi\n" @@ -22,16 +22,16 @@ msgstr "" #. translators: For example: "home-manager: missing argument for --cores" #: home-manager/home-manager:16 msgid "%s: missing argument for %s" -msgstr "" +msgstr "%s: ‌%s के लिए कोई आर्ग्यूमेंट नहीं दिया" -#: home-manager/home-manager:64 +#: home-manager/home-manager:69 msgid "No configuration file found at %s" -msgstr "" +msgstr "%s में कोई कन्फि़गरेशन फाइल नहीं मिली" #. translators: The first '%s' specifier will be replaced by either #. 'home.nix' or 'flake.nix'. -#: home-manager/home-manager:81 home-manager/home-manager:85 -#: home-manager/home-manager:184 +#: home-manager/home-manager:86 home-manager/home-manager:90 +#: home-manager/home-manager:189 msgid "" "Keeping your Home Manager %s in %s is deprecated,\n" "please move it to %s" @@ -39,23 +39,23 @@ msgstr "" "अपने Home Manager %s को %s में रखना अप्रचलित है,\n" "कृपया इसे %s में स्थानांतरित करें" -#: home-manager/home-manager:92 +#: home-manager/home-manager:97 msgid "No configuration file found. Please create one at %s" msgstr "कोई कॉन्फ़िगरेशन फ़ाइल नहीं मिली। कृपया %s पर एक फ़ाइल बनाएं।" -#: home-manager/home-manager:107 +#: home-manager/home-manager:112 msgid "Home Manager not found at %s." msgstr "%s पर Home Manager नहीं मिला।" #. translators: This message will be seen by very few users that likely are familiar with English. So feel free to leave this untranslated. -#: home-manager/home-manager:115 +#: home-manager/home-manager:120 msgid "" "The fallback Home Manager path %s has been deprecated and a file/directory " "was found there." msgstr "" #. translators: This message will be seen by very few users that likely are familiar with English. So feel free to leave this untranslated. -#: home-manager/home-manager:118 +#: home-manager/home-manager:123 msgid "" "To remove this warning, do one of the following.\n" "\n" @@ -76,42 +76,42 @@ msgid "" " $ rm -r \"%s\"" msgstr "" -#: home-manager/home-manager:146 +#: home-manager/home-manager:151 msgid "Sanity checking Nix" msgstr "" -#: home-manager/home-manager:166 +#: home-manager/home-manager:171 msgid "Could not find suitable profile directory, tried %s and %s" msgstr "" #. translators: Here "flake" is a noun that refers to the Nix Flakes feature. -#: home-manager/home-manager:221 +#: home-manager/home-manager:226 msgid "Can't inspect options of a flake configuration" msgstr "" -#: home-manager/home-manager:296 home-manager/home-manager:319 -#: home-manager/home-manager:1051 +#: home-manager/home-manager:301 home-manager/home-manager:324 +#: home-manager/home-manager:1061 msgid "%s: unknown option '%s'" msgstr "" -#: home-manager/home-manager:301 home-manager/home-manager:1052 +#: home-manager/home-manager:306 home-manager/home-manager:1062 msgid "Run '%s --help' for usage help" msgstr "" -#: home-manager/home-manager:327 home-manager/home-manager:431 +#: home-manager/home-manager:332 home-manager/home-manager:437 msgid "The file %s already exists, leaving it unchanged..." msgstr "" -#: home-manager/home-manager:329 home-manager/home-manager:433 +#: home-manager/home-manager:334 home-manager/home-manager:439 msgid "Creating %s..." msgstr "" -#: home-manager/home-manager:475 +#: home-manager/home-manager:481 msgid "Creating initial Home Manager generation..." msgstr "" #. translators: The "%s" specifier will be replaced by a file path. -#: home-manager/home-manager:480 +#: home-manager/home-manager:486 msgid "" "All done! The home-manager tool should now be installed and you can edit\n" "\n" @@ -122,7 +122,7 @@ msgid "" msgstr "" #. translators: The "%s" specifier will be replaced by a URL. -#: home-manager/home-manager:485 +#: home-manager/home-manager:491 msgid "" "Uh oh, the installation failed! Please create an issue at\n" "\n" @@ -132,11 +132,11 @@ msgid "" msgstr "" #. translators: Here "flake" is a noun that refers to the Nix Flakes feature. -#: home-manager/home-manager:496 +#: home-manager/home-manager:502 msgid "Can't instantiate a flake configuration" msgstr "" -#: home-manager/home-manager:572 +#: home-manager/home-manager:578 msgid "" "There is %d unread and relevant news item.\n" "Read it by running the command \"%s news\"." @@ -146,72 +146,72 @@ msgid_plural "" msgstr[0] "" msgstr[1] "" -#: home-manager/home-manager:586 +#: home-manager/home-manager:592 msgid "Unknown \"news.display\" setting \"%s\"." msgstr "" -#: home-manager/home-manager:594 +#: home-manager/home-manager:600 #, sh-format msgid "Please set the $EDITOR or $VISUAL environment variable" msgstr "" -#: home-manager/home-manager:612 +#: home-manager/home-manager:618 msgid "Cannot run build in read-only directory" msgstr "" -#: home-manager/home-manager:693 +#: home-manager/home-manager:699 msgid "No generation with ID %s" msgstr "" -#: home-manager/home-manager:695 +#: home-manager/home-manager:701 msgid "Cannot remove the current generation %s" msgstr "" -#: home-manager/home-manager:697 +#: home-manager/home-manager:703 msgid "Removing generation %s" msgstr "" -#: home-manager/home-manager:718 +#: home-manager/home-manager:724 msgid "No generations to expire" msgstr "" -#: home-manager/home-manager:729 +#: home-manager/home-manager:735 msgid "No home-manager packages seem to be installed." msgstr "" -#: home-manager/home-manager:811 +#: home-manager/home-manager:820 msgid "Unknown argument %s" msgstr "" -#: home-manager/home-manager:835 +#: home-manager/home-manager:845 msgid "This will remove Home Manager from your system." msgstr "" -#: home-manager/home-manager:838 +#: home-manager/home-manager:848 msgid "This is a dry run, nothing will actually be uninstalled." msgstr "" -#: home-manager/home-manager:842 +#: home-manager/home-manager:852 msgid "Really uninstall Home Manager?" msgstr "" -#: home-manager/home-manager:848 +#: home-manager/home-manager:858 msgid "Switching to empty Home Manager configuration..." msgstr "" -#: home-manager/home-manager:863 +#: home-manager/home-manager:873 msgid "Yay!" msgstr "" -#: home-manager/home-manager:868 +#: home-manager/home-manager:878 msgid "Home Manager is uninstalled but your home.nix is left untouched." msgstr "" -#: home-manager/home-manager:1091 +#: home-manager/home-manager:1101 msgid "expire-generations expects one argument, got %d." msgstr "" -#: home-manager/home-manager:1113 +#: home-manager/home-manager:1123 msgid "Unknown command: %s" msgstr "" diff --git a/home-manager/po/home-manager.pot b/home-manager/po/home-manager.pot index 2fcdc5a60..6817fd554 100644 --- a/home-manager/po/home-manager.pot +++ b/home-manager/po/home-manager.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: Home Manager\n" "Report-Msgid-Bugs-To: https://github.com/nix-community/home-manager/issues\n" -"POT-Creation-Date: 2024-04-17 23:19+0200\n" +"POT-Creation-Date: 2025-01-03 09:09+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -23,36 +23,36 @@ msgstr "" msgid "%s: missing argument for %s" msgstr "" -#: home-manager/home-manager:64 +#: home-manager/home-manager:69 msgid "No configuration file found at %s" msgstr "" #. translators: The first '%s' specifier will be replaced by either #. 'home.nix' or 'flake.nix'. -#: home-manager/home-manager:81 home-manager/home-manager:85 -#: home-manager/home-manager:184 +#: home-manager/home-manager:86 home-manager/home-manager:90 +#: home-manager/home-manager:189 msgid "" "Keeping your Home Manager %s in %s is deprecated,\n" "please move it to %s" msgstr "" -#: home-manager/home-manager:92 +#: home-manager/home-manager:97 msgid "No configuration file found. Please create one at %s" msgstr "" -#: home-manager/home-manager:107 +#: home-manager/home-manager:112 msgid "Home Manager not found at %s." msgstr "" #. translators: This message will be seen by very few users that likely are familiar with English. So feel free to leave this untranslated. -#: home-manager/home-manager:115 +#: home-manager/home-manager:120 msgid "" "The fallback Home Manager path %s has been deprecated and a file/directory " "was found there." msgstr "" #. translators: This message will be seen by very few users that likely are familiar with English. So feel free to leave this untranslated. -#: home-manager/home-manager:118 +#: home-manager/home-manager:123 msgid "" "To remove this warning, do one of the following.\n" "\n" @@ -73,42 +73,42 @@ msgid "" " $ rm -r \"%s\"" msgstr "" -#: home-manager/home-manager:146 +#: home-manager/home-manager:151 msgid "Sanity checking Nix" msgstr "" -#: home-manager/home-manager:166 +#: home-manager/home-manager:171 msgid "Could not find suitable profile directory, tried %s and %s" msgstr "" #. translators: Here "flake" is a noun that refers to the Nix Flakes feature. -#: home-manager/home-manager:221 +#: home-manager/home-manager:226 msgid "Can't inspect options of a flake configuration" msgstr "" -#: home-manager/home-manager:296 home-manager/home-manager:319 -#: home-manager/home-manager:1051 +#: home-manager/home-manager:301 home-manager/home-manager:324 +#: home-manager/home-manager:1061 msgid "%s: unknown option '%s'" msgstr "" -#: home-manager/home-manager:301 home-manager/home-manager:1052 +#: home-manager/home-manager:306 home-manager/home-manager:1062 msgid "Run '%s --help' for usage help" msgstr "" -#: home-manager/home-manager:327 home-manager/home-manager:431 +#: home-manager/home-manager:332 home-manager/home-manager:437 msgid "The file %s already exists, leaving it unchanged..." msgstr "" -#: home-manager/home-manager:329 home-manager/home-manager:433 +#: home-manager/home-manager:334 home-manager/home-manager:439 msgid "Creating %s..." msgstr "" -#: home-manager/home-manager:475 +#: home-manager/home-manager:481 msgid "Creating initial Home Manager generation..." msgstr "" #. translators: The "%s" specifier will be replaced by a file path. -#: home-manager/home-manager:480 +#: home-manager/home-manager:486 msgid "" "All done! The home-manager tool should now be installed and you can edit\n" "\n" @@ -119,7 +119,7 @@ msgid "" msgstr "" #. translators: The "%s" specifier will be replaced by a URL. -#: home-manager/home-manager:485 +#: home-manager/home-manager:491 msgid "" "Uh oh, the installation failed! Please create an issue at\n" "\n" @@ -129,11 +129,11 @@ msgid "" msgstr "" #. translators: Here "flake" is a noun that refers to the Nix Flakes feature. -#: home-manager/home-manager:496 +#: home-manager/home-manager:502 msgid "Can't instantiate a flake configuration" msgstr "" -#: home-manager/home-manager:572 +#: home-manager/home-manager:578 msgid "" "There is %d unread and relevant news item.\n" "Read it by running the command \"%s news\"." @@ -143,72 +143,72 @@ msgid_plural "" msgstr[0] "" msgstr[1] "" -#: home-manager/home-manager:586 +#: home-manager/home-manager:592 msgid "Unknown \"news.display\" setting \"%s\"." msgstr "" -#: home-manager/home-manager:594 +#: home-manager/home-manager:600 #, sh-format msgid "Please set the $EDITOR or $VISUAL environment variable" msgstr "" -#: home-manager/home-manager:612 +#: home-manager/home-manager:618 msgid "Cannot run build in read-only directory" msgstr "" -#: home-manager/home-manager:693 +#: home-manager/home-manager:699 msgid "No generation with ID %s" msgstr "" -#: home-manager/home-manager:695 +#: home-manager/home-manager:701 msgid "Cannot remove the current generation %s" msgstr "" -#: home-manager/home-manager:697 +#: home-manager/home-manager:703 msgid "Removing generation %s" msgstr "" -#: home-manager/home-manager:718 +#: home-manager/home-manager:724 msgid "No generations to expire" msgstr "" -#: home-manager/home-manager:729 +#: home-manager/home-manager:735 msgid "No home-manager packages seem to be installed." msgstr "" -#: home-manager/home-manager:811 +#: home-manager/home-manager:820 msgid "Unknown argument %s" msgstr "" -#: home-manager/home-manager:835 +#: home-manager/home-manager:845 msgid "This will remove Home Manager from your system." msgstr "" -#: home-manager/home-manager:838 +#: home-manager/home-manager:848 msgid "This is a dry run, nothing will actually be uninstalled." msgstr "" -#: home-manager/home-manager:842 +#: home-manager/home-manager:852 msgid "Really uninstall Home Manager?" msgstr "" -#: home-manager/home-manager:848 +#: home-manager/home-manager:858 msgid "Switching to empty Home Manager configuration..." msgstr "" -#: home-manager/home-manager:863 +#: home-manager/home-manager:873 msgid "Yay!" msgstr "" -#: home-manager/home-manager:868 +#: home-manager/home-manager:878 msgid "Home Manager is uninstalled but your home.nix is left untouched." msgstr "" -#: home-manager/home-manager:1091 +#: home-manager/home-manager:1101 msgid "expire-generations expects one argument, got %d." msgstr "" -#: home-manager/home-manager:1113 +#: home-manager/home-manager:1123 msgid "Unknown command: %s" msgstr "" diff --git a/home-manager/po/hu.po b/home-manager/po/hu.po index 3cfab2551..450f01dbb 100644 --- a/home-manager/po/hu.po +++ b/home-manager/po/hu.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: Home Manager\n" "Report-Msgid-Bugs-To: https://github.com/nix-community/home-manager/issues\n" -"POT-Creation-Date: 2024-04-17 23:19+0200\n" +"POT-Creation-Date: 2025-01-03 09:09+0100\n" "PO-Revision-Date: 2024-09-02 17:09+0000\n" "Last-Translator: Ferenci Ákos \n" "Language-Team: Hungarian \n" "Language-Team: Indonesian \n" "Language-Team: Icelandic \n" +"POT-Creation-Date: 2025-01-03 09:09+0100\n" +"PO-Revision-Date: 2024-11-18 15:00+0000\n" +"Last-Translator: Lorenzo Bevilacqua \n" "Language-Team: Italian \n" "Language: it\n" @@ -17,21 +17,21 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 5.5-dev\n" +"X-Generator: Weblate 5.9-dev\n" #. translators: For example: "home-manager: missing argument for --cores" #: home-manager/home-manager:16 msgid "%s: missing argument for %s" -msgstr "" +msgstr "%s: argomento mancante per %s" -#: home-manager/home-manager:64 +#: home-manager/home-manager:69 msgid "No configuration file found at %s" msgstr "Nessun file di configurazione trovato in %s" #. translators: The first '%s' specifier will be replaced by either #. 'home.nix' or 'flake.nix'. -#: home-manager/home-manager:81 home-manager/home-manager:85 -#: home-manager/home-manager:184 +#: home-manager/home-manager:86 home-manager/home-manager:90 +#: home-manager/home-manager:189 msgid "" "Keeping your Home Manager %s in %s is deprecated,\n" "please move it to %s" @@ -39,16 +39,16 @@ msgstr "" "Mantere il tuo Home Manger su %s su %s è obsoleto,\n" "si raccomanda di spostarlo su %s" -#: home-manager/home-manager:92 +#: home-manager/home-manager:97 msgid "No configuration file found. Please create one at %s" msgstr "Nessun file di configurazione trovato. Per favore creane uno in %s" -#: home-manager/home-manager:107 +#: home-manager/home-manager:112 msgid "Home Manager not found at %s." msgstr "Home Manager non è stato trovato in %s." #. translators: This message will be seen by very few users that likely are familiar with English. So feel free to leave this untranslated. -#: home-manager/home-manager:115 +#: home-manager/home-manager:120 msgid "" "The fallback Home Manager path %s has been deprecated and a file/directory " "was found there." @@ -57,7 +57,7 @@ msgstr "" "directory è stato trovato lì." #. translators: This message will be seen by very few users that likely are familiar with English. So feel free to leave this untranslated. -#: home-manager/home-manager:118 +#: home-manager/home-manager:123 msgid "" "To remove this warning, do one of the following.\n" "\n" @@ -98,43 +98,43 @@ msgstr "" "\n" "· · · · · $ rm -r \"%s\"" -#: home-manager/home-manager:146 +#: home-manager/home-manager:151 msgid "Sanity checking Nix" msgstr "Controllando Nix" -#: home-manager/home-manager:166 +#: home-manager/home-manager:171 msgid "Could not find suitable profile directory, tried %s and %s" msgstr "" "Impossibile trovare la directory del profilo adatta, si è provato con %s e %s" #. translators: Here "flake" is a noun that refers to the Nix Flakes feature. -#: home-manager/home-manager:221 +#: home-manager/home-manager:226 msgid "Can't inspect options of a flake configuration" msgstr "Impossibile ispezionare le opzioni di configurazione flake" -#: home-manager/home-manager:296 home-manager/home-manager:319 -#: home-manager/home-manager:1051 +#: home-manager/home-manager:301 home-manager/home-manager:324 +#: home-manager/home-manager:1061 msgid "%s: unknown option '%s'" msgstr "%s: opzione sconosciuta '%s'" -#: home-manager/home-manager:301 home-manager/home-manager:1052 +#: home-manager/home-manager:306 home-manager/home-manager:1062 msgid "Run '%s --help' for usage help" msgstr "Esegui '%s --help' per le informazioni d'uso" -#: home-manager/home-manager:327 home-manager/home-manager:431 +#: home-manager/home-manager:332 home-manager/home-manager:437 msgid "The file %s already exists, leaving it unchanged..." msgstr "Il file %s esiste già, non verrà modificato..." -#: home-manager/home-manager:329 home-manager/home-manager:433 +#: home-manager/home-manager:334 home-manager/home-manager:439 msgid "Creating %s..." msgstr "Creando %s..." -#: home-manager/home-manager:475 +#: home-manager/home-manager:481 msgid "Creating initial Home Manager generation..." msgstr "Creando la generazione iniziale di Home Manager..." #. translators: The "%s" specifier will be replaced by a file path. -#: home-manager/home-manager:480 +#: home-manager/home-manager:486 msgid "" "All done! The home-manager tool should now be installed and you can edit\n" "\n" @@ -151,7 +151,7 @@ msgstr "" "consultare tutte le opzioni disponibili." #. translators: The "%s" specifier will be replaced by a URL. -#: home-manager/home-manager:485 +#: home-manager/home-manager:491 msgid "" "Uh oh, the installation failed! Please create an issue at\n" "\n" @@ -167,11 +167,11 @@ msgstr "" "se l'errore sembra essere causato da Home Manager." #. translators: Here "flake" is a noun that refers to the Nix Flakes feature. -#: home-manager/home-manager:496 +#: home-manager/home-manager:502 msgid "Can't instantiate a flake configuration" msgstr "Impossibile istanziare una configurazione flake" -#: home-manager/home-manager:572 +#: home-manager/home-manager:578 msgid "" "There is %d unread and relevant news item.\n" "Read it by running the command \"%s news\"." @@ -185,72 +185,72 @@ msgstr[1] "" "Ci sono %d novità rilevanti non lette.\n" "Leggile con il comando \"%s news\"." -#: home-manager/home-manager:586 +#: home-manager/home-manager:592 msgid "Unknown \"news.display\" setting \"%s\"." msgstr "Opzione \"news.display\" sconosciuta \"%s\"." -#: home-manager/home-manager:594 +#: home-manager/home-manager:600 #, sh-format msgid "Please set the $EDITOR or $VISUAL environment variable" msgstr "Per favore definisci le variabili d'ambiente $EDITOR o $VISUAL" -#: home-manager/home-manager:612 +#: home-manager/home-manager:618 msgid "Cannot run build in read-only directory" msgstr "Impossibile eseguire la build in una cartella in sola lettura" -#: home-manager/home-manager:693 +#: home-manager/home-manager:699 msgid "No generation with ID %s" msgstr "Nessuna generazione con ID %s" -#: home-manager/home-manager:695 +#: home-manager/home-manager:701 msgid "Cannot remove the current generation %s" msgstr "Impossibile rimuovere la generazione corrente %s" -#: home-manager/home-manager:697 +#: home-manager/home-manager:703 msgid "Removing generation %s" msgstr "Rimuovo la generazione %s" -#: home-manager/home-manager:718 +#: home-manager/home-manager:724 msgid "No generations to expire" msgstr "Nessuna generazione in scadenza" -#: home-manager/home-manager:729 +#: home-manager/home-manager:735 msgid "No home-manager packages seem to be installed." msgstr "Sembrerebbe che nessun pacchetto home-manager sia installato." -#: home-manager/home-manager:811 +#: home-manager/home-manager:820 msgid "Unknown argument %s" msgstr "Argomento sconosciuto: %s" -#: home-manager/home-manager:835 +#: home-manager/home-manager:845 msgid "This will remove Home Manager from your system." msgstr "Questo rimuoverà Home Manger dal tuo sistema." -#: home-manager/home-manager:838 +#: home-manager/home-manager:848 msgid "This is a dry run, nothing will actually be uninstalled." msgstr "Questo è un avvio a secco, nulla verrà realmente disinstallato." -#: home-manager/home-manager:842 +#: home-manager/home-manager:852 msgid "Really uninstall Home Manager?" msgstr "Vuoi davvero disinstallare Home Manager?" -#: home-manager/home-manager:848 +#: home-manager/home-manager:858 msgid "Switching to empty Home Manager configuration..." msgstr "Passaando ad una configurazione Home Manager vuota..." -#: home-manager/home-manager:863 +#: home-manager/home-manager:873 msgid "Yay!" msgstr "Urrà!" -#: home-manager/home-manager:868 +#: home-manager/home-manager:878 msgid "Home Manager is uninstalled but your home.nix is left untouched." msgstr "Home Manager è disinstallato ma la tua home.nix non è stata toccata." -#: home-manager/home-manager:1091 +#: home-manager/home-manager:1101 msgid "expire-generations expects one argument, got %d." msgstr "expire-generations si aspetta un solo argomento, invece di %d." -#: home-manager/home-manager:1113 +#: home-manager/home-manager:1123 msgid "Unknown command: %s" msgstr "Comando sconosciuto: %s" diff --git a/home-manager/po/ja.po b/home-manager/po/ja.po index 5a558d365..6f1ad5ed6 100644 --- a/home-manager/po/ja.po +++ b/home-manager/po/ja.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: Home Manager\n" "Report-Msgid-Bugs-To: https://github.com/nix-community/home-manager/issues\n" -"POT-Creation-Date: 2024-04-17 23:19+0200\n" +"POT-Creation-Date: 2025-01-03 09:09+0100\n" "PO-Revision-Date: 2024-05-25 11:09+0000\n" "Last-Translator: TANIGUCHI Kohei \n" "Language-Team: Japanese \n" "Language-Team: Korean \n" +"POT-Creation-Date: 2025-01-03 09:09+0100\n" +"PO-Revision-Date: 2024-10-17 00:20+0000\n" +"Last-Translator: Julius Marozas \n" "Language-Team: Lithuanian \n" "Language: lt\n" @@ -18,21 +18,21 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && " "(n%100<10 || n%100>=20) ? 1 : 2);\n" -"X-Generator: Weblate 5.4\n" +"X-Generator: Weblate 5.8-rc\n" #. translators: For example: "home-manager: missing argument for --cores" #: home-manager/home-manager:16 msgid "%s: missing argument for %s" -msgstr "" +msgstr "%s: trūksta argumento %s" -#: home-manager/home-manager:64 +#: home-manager/home-manager:69 msgid "No configuration file found at %s" msgstr "Nerastas konfigūracijos failas %s" #. translators: The first '%s' specifier will be replaced by either #. 'home.nix' or 'flake.nix'. -#: home-manager/home-manager:81 home-manager/home-manager:85 -#: home-manager/home-manager:184 +#: home-manager/home-manager:86 home-manager/home-manager:90 +#: home-manager/home-manager:189 #, fuzzy msgid "" "Keeping your Home Manager %s in %s is deprecated,\n" @@ -41,23 +41,25 @@ msgstr "" "Home Manager saugojimas %s viduje %s yra pasenes,\n" "prašome perkelti į %s" -#: home-manager/home-manager:92 +#: home-manager/home-manager:97 msgid "No configuration file found. Please create one at %s" msgstr "Nerastas konfigūracijos failas. Sukurkite jį adresu %s" -#: home-manager/home-manager:107 +#: home-manager/home-manager:112 msgid "Home Manager not found at %s." msgstr "Nerastas Home Manager šioje vietoje %s." #. translators: This message will be seen by very few users that likely are familiar with English. So feel free to leave this untranslated. -#: home-manager/home-manager:115 +#: home-manager/home-manager:120 msgid "" "The fallback Home Manager path %s has been deprecated and a file/directory " "was found there." msgstr "" +"Atsarginis kelias %s į Home Manager jau nebenaudojamas, tačiau jame buvo " +"rastas failas/katalogas." #. translators: This message will be seen by very few users that likely are familiar with English. So feel free to leave this untranslated. -#: home-manager/home-manager:118 +#: home-manager/home-manager:123 msgid "" "To remove this warning, do one of the following.\n" "\n" @@ -77,43 +79,61 @@ msgid "" "\n" " $ rm -r \"%s\"" msgstr "" +"Norėdami pašalinti šį įspėjimą, atlikite vieną iš šių veiksmų.\n" +"\n" +"1. Aiškiai nurodykite kelią į Home Manager, pavyzdžiui, pridėdami\n" +"\n" +" { programs.home-manager.path = \"%s\"; }\n" +"\n" +" prie jūsų konfigūracijos.\n" +"\n" +" Jei importuojate Home Manager tiesiogiai, galite naudoti parametrą " +"`path`.\n" +"\n" +" pkgs.callPackage /path/to/home-manager-package { path = \"%s\"; }\n" +"\n" +" kviečiant į Home Manager paketą.\n" +"\n" +"2. Pašalinkite nebenaudojamą kelią.\n" +"\n" +" $ rm -r \"%s\"" -#: home-manager/home-manager:146 +#: home-manager/home-manager:151 msgid "Sanity checking Nix" msgstr "Nix tikrinamas" -#: home-manager/home-manager:166 +#: home-manager/home-manager:171 msgid "Could not find suitable profile directory, tried %s and %s" msgstr "Nepavyko rasti tinkamo profilio katalogo, bandyta naudoti %s ir %s" #. translators: Here "flake" is a noun that refers to the Nix Flakes feature. -#: home-manager/home-manager:221 +#: home-manager/home-manager:226 msgid "Can't inspect options of a flake configuration" msgstr "Negalima patikrinti flake konfigūracijos pasirinkimų" -#: home-manager/home-manager:296 home-manager/home-manager:319 -#: home-manager/home-manager:1051 +#: home-manager/home-manager:301 home-manager/home-manager:324 +#: home-manager/home-manager:1061 msgid "%s: unknown option '%s'" msgstr "%s: nežinomas pasirinkimas „%s“" -#: home-manager/home-manager:301 home-manager/home-manager:1052 +#: home-manager/home-manager:306 home-manager/home-manager:1062 msgid "Run '%s --help' for usage help" msgstr "Paleiskite „%s --help“, kad gautumėte naudojimosi instrukcijas" -#: home-manager/home-manager:327 home-manager/home-manager:431 +#: home-manager/home-manager:332 home-manager/home-manager:437 msgid "The file %s already exists, leaving it unchanged..." msgstr "Failas %s jau egzistuoja, jis paliekamas nepakeistas..." -#: home-manager/home-manager:329 home-manager/home-manager:433 +#: home-manager/home-manager:334 home-manager/home-manager:439 msgid "Creating %s..." msgstr "Kuriamas %s..." -#: home-manager/home-manager:475 +#: home-manager/home-manager:481 msgid "Creating initial Home Manager generation..." msgstr "Kuriama pradinė Home Manager generacija..." #. translators: The "%s" specifier will be replaced by a file path. -#: home-manager/home-manager:480 +#: home-manager/home-manager:486 msgid "" "All done! The home-manager tool should now be installed and you can edit\n" "\n" @@ -132,7 +152,7 @@ msgstr "" "jei norite pamatyti visus pasirinkimus." #. translators: The "%s" specifier will be replaced by a URL. -#: home-manager/home-manager:485 +#: home-manager/home-manager:491 msgid "" "Uh oh, the installation failed! Please create an issue at\n" "\n" @@ -147,11 +167,11 @@ msgstr "" "jei atrodo, kad klaida įvyko dėl Home Manager." #. translators: Here "flake" is a noun that refers to the Nix Flakes feature. -#: home-manager/home-manager:496 +#: home-manager/home-manager:502 msgid "Can't instantiate a flake configuration" msgstr "Negalima sukurti pradinės flake konfigūracijos" -#: home-manager/home-manager:572 +#: home-manager/home-manager:578 msgid "" "There is %d unread and relevant news item.\n" "Read it by running the command \"%s news\"." @@ -168,73 +188,72 @@ msgstr[2] "" "Yra %d neperskaitytų ir aktualių naujienų.\n" "Perskaitykite jas paleidus komandą \"%s news\"." -#: home-manager/home-manager:586 +#: home-manager/home-manager:592 msgid "Unknown \"news.display\" setting \"%s\"." msgstr "Nežinomas \"news.display\" nustatymas \"%s\"." -#: home-manager/home-manager:594 +#: home-manager/home-manager:600 #, sh-format msgid "Please set the $EDITOR or $VISUAL environment variable" -msgstr "" +msgstr "Nustatykite $EDITOR arba $VISUAL aplinkos kintamuosius" -#: home-manager/home-manager:612 -#, fuzzy +#: home-manager/home-manager:618 msgid "Cannot run build in read-only directory" msgstr "Negalima vykdyti kompiliavimo read-only kataloge" -#: home-manager/home-manager:693 +#: home-manager/home-manager:699 msgid "No generation with ID %s" msgstr "Nėra generacijos su ID %s" -#: home-manager/home-manager:695 +#: home-manager/home-manager:701 msgid "Cannot remove the current generation %s" msgstr "Negalima pašalinti esamos generacijos %s" -#: home-manager/home-manager:697 +#: home-manager/home-manager:703 msgid "Removing generation %s" msgstr "Pašalinama generacija %s" -#: home-manager/home-manager:718 +#: home-manager/home-manager:724 msgid "No generations to expire" msgstr "Nėra generacijų, kurios baigtų galioti" -#: home-manager/home-manager:729 +#: home-manager/home-manager:735 msgid "No home-manager packages seem to be installed." msgstr "Nėra instaliuotų home-manager paketų." -#: home-manager/home-manager:811 +#: home-manager/home-manager:820 msgid "Unknown argument %s" msgstr "Nežinomas argumentas %s" -#: home-manager/home-manager:835 +#: home-manager/home-manager:845 msgid "This will remove Home Manager from your system." msgstr "Tai pašalins Home Manager iš jūsų sistemos." -#: home-manager/home-manager:838 +#: home-manager/home-manager:848 msgid "This is a dry run, nothing will actually be uninstalled." msgstr "Tai bandomasis paleidimas, niekas nebus ištrinta." -#: home-manager/home-manager:842 +#: home-manager/home-manager:852 msgid "Really uninstall Home Manager?" msgstr "Tikrai išdiegti Home Manager?" -#: home-manager/home-manager:848 +#: home-manager/home-manager:858 msgid "Switching to empty Home Manager configuration..." msgstr "Perjungiama į tuščią Home Manager konfigūraciją..." -#: home-manager/home-manager:863 +#: home-manager/home-manager:873 msgid "Yay!" msgstr "Valio!" -#: home-manager/home-manager:868 +#: home-manager/home-manager:878 msgid "Home Manager is uninstalled but your home.nix is left untouched." msgstr "Home Manager yra išdiegtas, bet jūsų home.nix liko nepaliestas." -#: home-manager/home-manager:1091 +#: home-manager/home-manager:1101 msgid "expire-generations expects one argument, got %d." msgstr "expire-generations tikisi vieno argumento, gauta %d." -#: home-manager/home-manager:1113 +#: home-manager/home-manager:1123 msgid "Unknown command: %s" msgstr "Nežinoma komanda: %s" diff --git a/home-manager/po/nb_NO.po b/home-manager/po/nb_NO.po index 41f5035c4..eb810d19f 100644 --- a/home-manager/po/nb_NO.po +++ b/home-manager/po/nb_NO.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: Home Manager\n" "Report-Msgid-Bugs-To: https://github.com/nix-community/home-manager/issues\n" -"POT-Creation-Date: 2024-04-17 23:19+0200\n" +"POT-Creation-Date: 2025-01-03 09:09+0100\n" "PO-Revision-Date: 2024-04-02 21:38+0000\n" "Last-Translator: LilleAila \n" "Language-Team: Norwegian Bokmål \n" "Language-Team: Dutch \n" "Language-Team: Polish \n" "Language-Team: Portuguese \n" -"Language-Team: Portuguese (Brazil) \n" +"Language-Team: Portuguese (Brazil) \n" "Language: pt_BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -24,14 +24,14 @@ msgstr "" msgid "%s: missing argument for %s" msgstr "%s: faltando argumento para %s" -#: home-manager/home-manager:64 +#: home-manager/home-manager:69 msgid "No configuration file found at %s" msgstr "Nenhum arquivo de configuração encontrado no %s" #. translators: The first '%s' specifier will be replaced by either #. 'home.nix' or 'flake.nix'. -#: home-manager/home-manager:81 home-manager/home-manager:85 -#: home-manager/home-manager:184 +#: home-manager/home-manager:86 home-manager/home-manager:90 +#: home-manager/home-manager:189 msgid "" "Keeping your Home Manager %s in %s is deprecated,\n" "please move it to %s" @@ -39,16 +39,16 @@ msgstr "" "Manter seu Home Manager %s em %s foi descontinuado,\n" "por favor mova-o para %s" -#: home-manager/home-manager:92 +#: home-manager/home-manager:97 msgid "No configuration file found. Please create one at %s" msgstr "Arquivo de configuração não encontrado. Por favor crie um em %s" -#: home-manager/home-manager:107 +#: home-manager/home-manager:112 msgid "Home Manager not found at %s." msgstr "Home Manager não encontrado em %s." #. translators: This message will be seen by very few users that likely are familiar with English. So feel free to leave this untranslated. -#: home-manager/home-manager:115 +#: home-manager/home-manager:120 msgid "" "The fallback Home Manager path %s has been deprecated and a file/directory " "was found there." @@ -57,7 +57,7 @@ msgstr "" "algum arquivo/diretório nele." #. translators: This message will be seen by very few users that likely are familiar with English. So feel free to leave this untranslated. -#: home-manager/home-manager:118 +#: home-manager/home-manager:123 msgid "" "To remove this warning, do one of the following.\n" "\n" @@ -97,43 +97,43 @@ msgstr "" "\n" " $ rm -r \"%s\"" -#: home-manager/home-manager:146 +#: home-manager/home-manager:151 msgid "Sanity checking Nix" msgstr "Revalidando Nix" -#: home-manager/home-manager:166 +#: home-manager/home-manager:171 msgid "Could not find suitable profile directory, tried %s and %s" msgstr "" "Não foi possível encontrar um diretório de perfil apropriado, tentou %s e %s" #. translators: Here "flake" is a noun that refers to the Nix Flakes feature. -#: home-manager/home-manager:221 +#: home-manager/home-manager:226 msgid "Can't inspect options of a flake configuration" msgstr "Não é possivel inspecionar a opção de configuração do flake" -#: home-manager/home-manager:296 home-manager/home-manager:319 -#: home-manager/home-manager:1051 +#: home-manager/home-manager:301 home-manager/home-manager:324 +#: home-manager/home-manager:1061 msgid "%s: unknown option '%s'" msgstr "%s: opção não reconhecida '%s'" -#: home-manager/home-manager:301 home-manager/home-manager:1052 +#: home-manager/home-manager:306 home-manager/home-manager:1062 msgid "Run '%s --help' for usage help" msgstr "Execute '%s --help' para instruções de uso" -#: home-manager/home-manager:327 home-manager/home-manager:431 +#: home-manager/home-manager:332 home-manager/home-manager:437 msgid "The file %s already exists, leaving it unchanged..." msgstr "O arquivo %s já existe, mantendo ele sem modificações..." -#: home-manager/home-manager:329 home-manager/home-manager:433 +#: home-manager/home-manager:334 home-manager/home-manager:439 msgid "Creating %s..." msgstr "Criando %s..." -#: home-manager/home-manager:475 +#: home-manager/home-manager:481 msgid "Creating initial Home Manager generation..." msgstr "Criando a geração inicial do Home Manager..." #. translators: The "%s" specifier will be replaced by a file path. -#: home-manager/home-manager:480 +#: home-manager/home-manager:486 msgid "" "All done! The home-manager tool should now be installed and you can edit\n" "\n" @@ -151,7 +151,7 @@ msgstr "" "ver todas as opções disponíveis." #. translators: The "%s" specifier will be replaced by a URL. -#: home-manager/home-manager:485 +#: home-manager/home-manager:491 msgid "" "Uh oh, the installation failed! Please create an issue at\n" "\n" @@ -166,11 +166,11 @@ msgstr "" "se o erro lhe parecer ser um problema do Home Manager." #. translators: Here "flake" is a noun that refers to the Nix Flakes feature. -#: home-manager/home-manager:496 +#: home-manager/home-manager:502 msgid "Can't instantiate a flake configuration" msgstr "Não foi possível instanciar a configuração de flake" -#: home-manager/home-manager:572 +#: home-manager/home-manager:578 msgid "" "There is %d unread and relevant news item.\n" "Read it by running the command \"%s news\"." @@ -184,72 +184,72 @@ msgstr[1] "" "Há %d novos itens relevants não lidos\n" "Leia executando o comando \"%s news\"." -#: home-manager/home-manager:586 +#: home-manager/home-manager:592 msgid "Unknown \"news.display\" setting \"%s\"." msgstr "Valor \"%s\" para configuração \"news.display\" não reconhecido." -#: home-manager/home-manager:594 +#: home-manager/home-manager:600 #, sh-format msgid "Please set the $EDITOR or $VISUAL environment variable" msgstr "Por favor, defina a variável de ambiente $EDITOR ou $VISUAL" -#: home-manager/home-manager:612 +#: home-manager/home-manager:618 msgid "Cannot run build in read-only directory" msgstr "Não é possível fazer o build em um diretório somente leitura" -#: home-manager/home-manager:693 +#: home-manager/home-manager:699 msgid "No generation with ID %s" msgstr "Nenhuma geração com ID %s" -#: home-manager/home-manager:695 +#: home-manager/home-manager:701 msgid "Cannot remove the current generation %s" msgstr "Não foi possível remover a geração atual %s" -#: home-manager/home-manager:697 +#: home-manager/home-manager:703 msgid "Removing generation %s" msgstr "Removendo geração %s" -#: home-manager/home-manager:718 +#: home-manager/home-manager:724 msgid "No generations to expire" msgstr "Nenhuma geração a expirar" -#: home-manager/home-manager:729 +#: home-manager/home-manager:735 msgid "No home-manager packages seem to be installed." msgstr "Nenhum pacote parece instalado com home-manager." -#: home-manager/home-manager:811 +#: home-manager/home-manager:820 msgid "Unknown argument %s" msgstr "Argumento desconhecido %s" -#: home-manager/home-manager:835 +#: home-manager/home-manager:845 msgid "This will remove Home Manager from your system." msgstr "Isso irá remover o Home Manager do seu sistema." -#: home-manager/home-manager:838 +#: home-manager/home-manager:848 msgid "This is a dry run, nothing will actually be uninstalled." msgstr "Essa é uma execução de teste, nada de fato será desinstalado." -#: home-manager/home-manager:842 +#: home-manager/home-manager:852 msgid "Really uninstall Home Manager?" msgstr "Confirma a desinstalação do Home Manager?" -#: home-manager/home-manager:848 +#: home-manager/home-manager:858 msgid "Switching to empty Home Manager configuration..." msgstr "Trocando para configuração vazia do Home Manager..." -#: home-manager/home-manager:863 +#: home-manager/home-manager:873 msgid "Yay!" msgstr "Boa!" -#: home-manager/home-manager:868 +#: home-manager/home-manager:878 msgid "Home Manager is uninstalled but your home.nix is left untouched." msgstr "Home Manager foi desinstalado, mas o seu home.nix foi deixado intacto." -#: home-manager/home-manager:1091 +#: home-manager/home-manager:1101 msgid "expire-generations expects one argument, got %d." msgstr "expire-generations espera um argumento, recebeu %d." -#: home-manager/home-manager:1113 +#: home-manager/home-manager:1123 msgid "Unknown command: %s" msgstr "Comando não reconhecido: %s" diff --git a/home-manager/po/ro.po b/home-manager/po/ro.po index b4be27ce4..de20d8a3d 100644 --- a/home-manager/po/ro.po +++ b/home-manager/po/ro.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: Home Manager\n" "Report-Msgid-Bugs-To: https://github.com/nix-community/home-manager/issues\n" -"POT-Creation-Date: 2024-04-17 23:19+0200\n" +"POT-Creation-Date: 2025-01-03 09:09+0100\n" "PO-Revision-Date: 2024-09-09 10:09+0000\n" "Last-Translator: Felix Puscasu \n" "Language-Team: Romanian \n" "Language-Team: Russian \n" "Language-Team: Swedish , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: Home Manager\n" +"Report-Msgid-Bugs-To: https://github.com/nix-community/home-manager/issues\n" +"POT-Creation-Date: 2025-01-03 09:09+0100\n" +"PO-Revision-Date: 2025-01-03 08:16+0000\n" +"Last-Translator: தமிழ்நேரம் \n" +"Language-Team: Tamil \n" +"Language: ta\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 5.10-dev\n" + +#. translators: For example: "home-manager: missing argument for --cores" +#: home-manager/home-manager:16 +msgid "%s: missing argument for %s" +msgstr "%s: %s காணவில்லை" + +#: home-manager/home-manager:69 +msgid "No configuration file found at %s" +msgstr "%s இல் உள்ளமைவு கோப்பு இல்லை" + +#. translators: The first '%s' specifier will be replaced by either +#. 'home.nix' or 'flake.nix'. +#: home-manager/home-manager:86 home-manager/home-manager:90 +#: home-manager/home-manager:189 +msgid "" +"Keeping your Home Manager %s in %s is deprecated,\n" +"please move it to %s" +msgstr "" +"உங்கள் வீட்டு மேலாளரை %s %s இல் வைத்திருப்பது நீக்கப்பட்டது,\n" +" தயவுசெய்து அதை %s க்கு நகர்த்தவும்" + +#: home-manager/home-manager:97 +msgid "No configuration file found. Please create one at %s" +msgstr "உள்ளமைவு கோப்பு எதுவும் கிடைக்கவில்லை. தயவுசெய்து ஒன்றை %s இல் உருவாக்கவும்" + +#: home-manager/home-manager:112 +msgid "Home Manager not found at %s." +msgstr "வீட்டு மேலாளர் %s இல் காணப்படவில்லை." + +#. translators: This message will be seen by very few users that likely are familiar with English. So feel free to leave this untranslated. +#: home-manager/home-manager:120 +msgid "" +"The fallback Home Manager path %s has been deprecated and a file/directory " +"was found there." +msgstr "" +"குறைவடையும் வீட்டு மேலாளர் பாதை %s நீக்கப்பட்டு, ஒரு கோப்பு/அடைவு அங்கு காணப்பட்டது." + +#. translators: This message will be seen by very few users that likely are familiar with English. So feel free to leave this untranslated. +#: home-manager/home-manager:123 +msgid "" +"To remove this warning, do one of the following.\n" +"\n" +"1. Explicitly tell Home Manager to use the path, for example by adding\n" +"\n" +" { programs.home-manager.path = \"%s\"; }\n" +"\n" +" to your configuration.\n" +"\n" +" If you import Home Manager directly, you can use the `path` parameter\n" +"\n" +" pkgs.callPackage /path/to/home-manager-package { path = \"%s\"; }\n" +"\n" +" when calling the Home Manager package.\n" +"\n" +"2. Remove the deprecated path.\n" +"\n" +" $ rm -r \"%s\"" +msgstr "" +"இந்த எச்சரிக்கையை அகற்ற, பின்வருவனவற்றில் ஒன்றைச் செய்யுங்கள்.\n" +"\n" +" 1. ஓம் மேனேசரை பாதையை பயன்படுத்துமாறு வெளிப்படையாகச் சொல்லுங்கள், எடுத்துக்காட்டாக " +"சேர்ப்பதன் மூலம்\n" +"\n" +" {programs.home-manager.path = \"%s\"; }\n" +"\n" +" உங்கள் உள்ளமைவுக்கு.\n" +"\n" +" நீங்கள் வீட்டு மேலாளரை நேரடியாக இறக்குமதி செய்தால், நீங்கள் `பாதை` அளவுருவைப் " +"பயன்படுத்தலாம்\n" +"\n" +" pkgs.callpackage/path/to/home-manager- பேக்கேச் {பாதை = \"%s\"; }\n" +"\n" +" வீட்டு மேலாளர் தொகுப்பை அழைக்கும் போது.\n" +"\n" +" 2. நீக்கப்பட்ட பாதையை அகற்று.\n" +"\n" +" $ rm -r \"%s\"" + +#: home-manager/home-manager:151 +msgid "Sanity checking Nix" +msgstr "நல்லறிவு சோதனை நிக்ச்" + +#: home-manager/home-manager:171 +msgid "Could not find suitable profile directory, tried %s and %s" +msgstr "" +"பொருத்தமான சுயவிவர கோப்பகத்தைக் கண்டுபிடிக்க முடியவில்லை, முயற்சித்த %s மற்றும் %s" + +#. translators: Here "flake" is a noun that refers to the Nix Flakes feature. +#: home-manager/home-manager:226 +msgid "Can't inspect options of a flake configuration" +msgstr "ஒரு ஃப்ளேக் உள்ளமைவின் விருப்பங்களை ஆய்வு செய்ய முடியாது" + +#: home-manager/home-manager:301 home-manager/home-manager:324 +#: home-manager/home-manager:1061 +msgid "%s: unknown option '%s'" +msgstr "%s: அறியப்படாத விருப்பம் '%s'" + +#: home-manager/home-manager:306 home-manager/home-manager:1062 +msgid "Run '%s --help' for usage help" +msgstr "பயன்பாட்டு உதவிக்காக '%s - -help' ஐ இயக்கவும்" + +#: home-manager/home-manager:332 home-manager/home-manager:437 +msgid "The file %s already exists, leaving it unchanged..." +msgstr "%s ஏற்கனவே உள்ளது, அதை மாற்றாமல் விட்டுவிடுகிறது ..." + +#: home-manager/home-manager:334 home-manager/home-manager:439 +msgid "Creating %s..." +msgstr "%s ஐ உருவாக்குதல் ..." + +#: home-manager/home-manager:481 +msgid "Creating initial Home Manager generation..." +msgstr "ஆரம்ப வீட்டு மேலாளர் தலைமுறையை உருவாக்குதல் ..." + +#. translators: The "%s" specifier will be replaced by a file path. +#: home-manager/home-manager:486 +msgid "" +"All done! The home-manager tool should now be installed and you can edit\n" +"\n" +" %s\n" +"\n" +"to configure Home Manager. Run 'man home-configuration.nix' to\n" +"see all available options." +msgstr "" +"எல்லாம் முடிந்தது! வீட்டு மேலாளர் கருவி இப்போது நிறுவப்பட வேண்டும், நீங்கள் திருத்தலாம்\n" +"\n" +" %s\n" +"\n" +" வீட்டு மேலாளரை உள்ளமைக்க. 'மேன் ஓம்-கான்ஃபிகரேசன்.நிக்ச்' ஐ இயக்கவும்\n" +" கிடைக்கக்கூடிய அனைத்து விருப்பங்களையும் காண்க." + +#. translators: The "%s" specifier will be replaced by a URL. +#: home-manager/home-manager:491 +msgid "" +"Uh oh, the installation failed! Please create an issue at\n" +"\n" +" %s\n" +"\n" +"if the error seems to be the fault of Home Manager." +msgstr "" +"ஓ, நிறுவல் தோல்வியடைந்தது! தயவுசெய்து ஒரு சிக்கலை உருவாக்கவும்\n" +"\n" +" %s\n" +"\n" +" பிழை வீட்டு மேலாளரின் தவறு என்று தோன்றினால்." + +#. translators: Here "flake" is a noun that refers to the Nix Flakes feature. +#: home-manager/home-manager:502 +msgid "Can't instantiate a flake configuration" +msgstr "ஒரு ஃப்ளேக் உள்ளமைவை உடனடிப்படுத்த முடியாது" + +#: home-manager/home-manager:578 +msgid "" +"There is %d unread and relevant news item.\n" +"Read it by running the command \"%s news\"." +msgid_plural "" +"There are %d unread and relevant news items.\n" +"Read them by running the command \"%s news\"." +msgstr[0] "" +"%d படிக்காத மற்றும் பொருத்தமான செய்திகள் உள்ளன.\n" +" \"%s செய்திகள்\" என்ற கட்டளையை இயக்குவதன் மூலம் அதைப் படியுங்கள்." +msgstr[1] "" +"%d படிக்காத மற்றும் தொடர்புடைய செய்திகள் உள்ளன.\n" +" \"%s செய்திகள்\" என்ற கட்டளையை இயக்குவதன் மூலம் அவற்றைப் படியுங்கள்." + +#: home-manager/home-manager:592 +msgid "Unknown \"news.display\" setting \"%s\"." +msgstr "தெரியாத \"News.Display\" அமைப்புகள் \"." + +#: home-manager/home-manager:600 +#, sh-format +msgid "Please set the $EDITOR or $VISUAL environment variable" +msgstr "$ எடிட்டர் அல்லது $ விசுவல் சூழல் மாறியை அமைக்கவும்" + +#: home-manager/home-manager:618 +msgid "Cannot run build in read-only directory" +msgstr "படிக்க மட்டும் கோப்பகத்தில் கட்டமைக்க முடியாது" + +#: home-manager/home-manager:699 +msgid "No generation with ID %s" +msgstr "ஐடி %s கொண்ட தலைமுறை இல்லை" + +#: home-manager/home-manager:701 +msgid "Cannot remove the current generation %s" +msgstr "தற்போதைய தலைமுறை %s ஐ அகற்ற முடியாது" + +#: home-manager/home-manager:703 +msgid "Removing generation %s" +msgstr "தலைமுறை %s நீக்குதல்" + +#: home-manager/home-manager:724 +msgid "No generations to expire" +msgstr "காலாவதியாகும் தலைமுறைகள் இல்லை" + +#: home-manager/home-manager:735 +msgid "No home-manager packages seem to be installed." +msgstr "வீட்டு மேலாளர் தொகுப்புகள் எதுவும் நிறுவப்படவில்லை." + +#: home-manager/home-manager:820 +msgid "Unknown argument %s" +msgstr "தெரியாத உரையாடல் %s" + +#: home-manager/home-manager:845 +msgid "This will remove Home Manager from your system." +msgstr "இது உங்கள் கணினியிலிருந்து வீட்டு மேலாளரை அகற்றும்." + +#: home-manager/home-manager:848 +msgid "This is a dry run, nothing will actually be uninstalled." +msgstr "இது உலர்ந்த ரன், உண்மையில் எதுவும் நிறுவல் நீக்கப்படாது." + +#: home-manager/home-manager:852 +msgid "Really uninstall Home Manager?" +msgstr "உண்மையில் வீட்டு மேலாளரை நிறுவல் நீக்கவா?" + +#: home-manager/home-manager:858 +msgid "Switching to empty Home Manager configuration..." +msgstr "வெற்று வீட்டு மேலாளர் உள்ளமைவுக்கு மாறுதல் ..." + +#: home-manager/home-manager:873 +msgid "Yay!" +msgstr "ஆம்!" + +#: home-manager/home-manager:878 +msgid "Home Manager is uninstalled but your home.nix is left untouched." +msgstr "" +"வீட்டு மேலாளர் நிறுவல் நீக்கப்பட்டார், ஆனால் உங்கள் வீடு. நிக்ச் தீண்டப்படாமல் விடப்பட்டுள்ளது." + +#: home-manager/home-manager:1101 +msgid "expire-generations expects one argument, got %d." +msgstr "காலாவதியாகும் ஒரு வாதத்தை எதிர்பார்க்கிறது, %d கிடைத்தது." + +#: home-manager/home-manager:1123 +msgid "Unknown command: %s" +msgstr "தெரியாத கட்டளை: %s" + +#: home-manager/install.nix:18 +msgid "This derivation is not buildable, please run it using nix-shell." +msgstr "" +"இந்த வழித்தோன்றல் கட்டமைக்கப்படவில்லை, தயவுசெய்து அதை நிக்ச்-செல் பயன்படுத்தி இயக்கவும்." diff --git a/home-manager/po/th.po b/home-manager/po/th.po index 174b1c0a8..fa94a460d 100644 --- a/home-manager/po/th.po +++ b/home-manager/po/th.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: Home Manager\n" "Report-Msgid-Bugs-To: https://github.com/nix-community/home-manager/issues\n" -"POT-Creation-Date: 2024-04-17 23:19+0200\n" +"POT-Creation-Date: 2025-01-03 09:09+0100\n" "PO-Revision-Date: 2023-09-19 06:27+0000\n" "Last-Translator: Kamontat Chantrachirathumrong \n" @@ -25,36 +25,36 @@ msgstr "" msgid "%s: missing argument for %s" msgstr "" -#: home-manager/home-manager:64 +#: home-manager/home-manager:69 msgid "No configuration file found at %s" msgstr "ไม่พบการตั้งค่าที่ %s" #. translators: The first '%s' specifier will be replaced by either #. 'home.nix' or 'flake.nix'. -#: home-manager/home-manager:81 home-manager/home-manager:85 -#: home-manager/home-manager:184 +#: home-manager/home-manager:86 home-manager/home-manager:90 +#: home-manager/home-manager:189 msgid "" "Keeping your Home Manager %s in %s is deprecated,\n" "please move it to %s" msgstr "" -#: home-manager/home-manager:92 +#: home-manager/home-manager:97 msgid "No configuration file found. Please create one at %s" msgstr "" -#: home-manager/home-manager:107 +#: home-manager/home-manager:112 msgid "Home Manager not found at %s." msgstr "" #. translators: This message will be seen by very few users that likely are familiar with English. So feel free to leave this untranslated. -#: home-manager/home-manager:115 +#: home-manager/home-manager:120 msgid "" "The fallback Home Manager path %s has been deprecated and a file/directory " "was found there." msgstr "" #. translators: This message will be seen by very few users that likely are familiar with English. So feel free to leave this untranslated. -#: home-manager/home-manager:118 +#: home-manager/home-manager:123 msgid "" "To remove this warning, do one of the following.\n" "\n" @@ -75,42 +75,42 @@ msgid "" " $ rm -r \"%s\"" msgstr "" -#: home-manager/home-manager:146 +#: home-manager/home-manager:151 msgid "Sanity checking Nix" msgstr "" -#: home-manager/home-manager:166 +#: home-manager/home-manager:171 msgid "Could not find suitable profile directory, tried %s and %s" msgstr "" #. translators: Here "flake" is a noun that refers to the Nix Flakes feature. -#: home-manager/home-manager:221 +#: home-manager/home-manager:226 msgid "Can't inspect options of a flake configuration" msgstr "" -#: home-manager/home-manager:296 home-manager/home-manager:319 -#: home-manager/home-manager:1051 +#: home-manager/home-manager:301 home-manager/home-manager:324 +#: home-manager/home-manager:1061 msgid "%s: unknown option '%s'" msgstr "" -#: home-manager/home-manager:301 home-manager/home-manager:1052 +#: home-manager/home-manager:306 home-manager/home-manager:1062 msgid "Run '%s --help' for usage help" msgstr "" -#: home-manager/home-manager:327 home-manager/home-manager:431 +#: home-manager/home-manager:332 home-manager/home-manager:437 msgid "The file %s already exists, leaving it unchanged..." msgstr "" -#: home-manager/home-manager:329 home-manager/home-manager:433 +#: home-manager/home-manager:334 home-manager/home-manager:439 msgid "Creating %s..." msgstr "" -#: home-manager/home-manager:475 +#: home-manager/home-manager:481 msgid "Creating initial Home Manager generation..." msgstr "" #. translators: The "%s" specifier will be replaced by a file path. -#: home-manager/home-manager:480 +#: home-manager/home-manager:486 msgid "" "All done! The home-manager tool should now be installed and you can edit\n" "\n" @@ -121,7 +121,7 @@ msgid "" msgstr "" #. translators: The "%s" specifier will be replaced by a URL. -#: home-manager/home-manager:485 +#: home-manager/home-manager:491 msgid "" "Uh oh, the installation failed! Please create an issue at\n" "\n" @@ -131,11 +131,11 @@ msgid "" msgstr "" #. translators: Here "flake" is a noun that refers to the Nix Flakes feature. -#: home-manager/home-manager:496 +#: home-manager/home-manager:502 msgid "Can't instantiate a flake configuration" msgstr "" -#: home-manager/home-manager:572 +#: home-manager/home-manager:578 msgid "" "There is %d unread and relevant news item.\n" "Read it by running the command \"%s news\"." @@ -145,72 +145,72 @@ msgid_plural "" msgstr[0] "" msgstr[1] "" -#: home-manager/home-manager:586 +#: home-manager/home-manager:592 msgid "Unknown \"news.display\" setting \"%s\"." msgstr "" -#: home-manager/home-manager:594 +#: home-manager/home-manager:600 #, sh-format msgid "Please set the $EDITOR or $VISUAL environment variable" msgstr "" -#: home-manager/home-manager:612 +#: home-manager/home-manager:618 msgid "Cannot run build in read-only directory" msgstr "" -#: home-manager/home-manager:693 +#: home-manager/home-manager:699 msgid "No generation with ID %s" msgstr "" -#: home-manager/home-manager:695 +#: home-manager/home-manager:701 msgid "Cannot remove the current generation %s" msgstr "" -#: home-manager/home-manager:697 +#: home-manager/home-manager:703 msgid "Removing generation %s" msgstr "" -#: home-manager/home-manager:718 +#: home-manager/home-manager:724 msgid "No generations to expire" msgstr "" -#: home-manager/home-manager:729 +#: home-manager/home-manager:735 msgid "No home-manager packages seem to be installed." msgstr "" -#: home-manager/home-manager:811 +#: home-manager/home-manager:820 msgid "Unknown argument %s" msgstr "" -#: home-manager/home-manager:835 +#: home-manager/home-manager:845 msgid "This will remove Home Manager from your system." msgstr "" -#: home-manager/home-manager:838 +#: home-manager/home-manager:848 msgid "This is a dry run, nothing will actually be uninstalled." msgstr "" -#: home-manager/home-manager:842 +#: home-manager/home-manager:852 msgid "Really uninstall Home Manager?" msgstr "" -#: home-manager/home-manager:848 +#: home-manager/home-manager:858 msgid "Switching to empty Home Manager configuration..." msgstr "" -#: home-manager/home-manager:863 +#: home-manager/home-manager:873 msgid "Yay!" msgstr "" -#: home-manager/home-manager:868 +#: home-manager/home-manager:878 msgid "Home Manager is uninstalled but your home.nix is left untouched." msgstr "" -#: home-manager/home-manager:1091 +#: home-manager/home-manager:1101 msgid "expire-generations expects one argument, got %d." msgstr "" -#: home-manager/home-manager:1113 +#: home-manager/home-manager:1123 msgid "Unknown command: %s" msgstr "" diff --git a/home-manager/po/tok.po b/home-manager/po/tok.po new file mode 100644 index 000000000..3def9a8e6 --- /dev/null +++ b/home-manager/po/tok.po @@ -0,0 +1,216 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR Home Manager contributors +# This file is distributed under the same license as the Home Manager package. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: Home Manager\n" +"Report-Msgid-Bugs-To: https://github.com/nix-community/home-manager/issues\n" +"POT-Creation-Date: 2025-01-03 09:09+0100\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: tok\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#. translators: For example: "home-manager: missing argument for --cores" +#: home-manager/home-manager:16 +msgid "%s: missing argument for %s" +msgstr "" + +#: home-manager/home-manager:69 +msgid "No configuration file found at %s" +msgstr "" + +#. translators: The first '%s' specifier will be replaced by either +#. 'home.nix' or 'flake.nix'. +#: home-manager/home-manager:86 home-manager/home-manager:90 +#: home-manager/home-manager:189 +msgid "" +"Keeping your Home Manager %s in %s is deprecated,\n" +"please move it to %s" +msgstr "" + +#: home-manager/home-manager:97 +msgid "No configuration file found. Please create one at %s" +msgstr "" + +#: home-manager/home-manager:112 +msgid "Home Manager not found at %s." +msgstr "" + +#. translators: This message will be seen by very few users that likely are familiar with English. So feel free to leave this untranslated. +#: home-manager/home-manager:120 +msgid "" +"The fallback Home Manager path %s has been deprecated and a file/directory " +"was found there." +msgstr "" + +#. translators: This message will be seen by very few users that likely are familiar with English. So feel free to leave this untranslated. +#: home-manager/home-manager:123 +msgid "" +"To remove this warning, do one of the following.\n" +"\n" +"1. Explicitly tell Home Manager to use the path, for example by adding\n" +"\n" +" { programs.home-manager.path = \"%s\"; }\n" +"\n" +" to your configuration.\n" +"\n" +" If you import Home Manager directly, you can use the `path` parameter\n" +"\n" +" pkgs.callPackage /path/to/home-manager-package { path = \"%s\"; }\n" +"\n" +" when calling the Home Manager package.\n" +"\n" +"2. Remove the deprecated path.\n" +"\n" +" $ rm -r \"%s\"" +msgstr "" + +#: home-manager/home-manager:151 +msgid "Sanity checking Nix" +msgstr "" + +#: home-manager/home-manager:171 +msgid "Could not find suitable profile directory, tried %s and %s" +msgstr "" + +#. translators: Here "flake" is a noun that refers to the Nix Flakes feature. +#: home-manager/home-manager:226 +msgid "Can't inspect options of a flake configuration" +msgstr "" + +#: home-manager/home-manager:301 home-manager/home-manager:324 +#: home-manager/home-manager:1061 +msgid "%s: unknown option '%s'" +msgstr "" + +#: home-manager/home-manager:306 home-manager/home-manager:1062 +msgid "Run '%s --help' for usage help" +msgstr "" + +#: home-manager/home-manager:332 home-manager/home-manager:437 +msgid "The file %s already exists, leaving it unchanged..." +msgstr "" + +#: home-manager/home-manager:334 home-manager/home-manager:439 +msgid "Creating %s..." +msgstr "" + +#: home-manager/home-manager:481 +msgid "Creating initial Home Manager generation..." +msgstr "" + +#. translators: The "%s" specifier will be replaced by a file path. +#: home-manager/home-manager:486 +msgid "" +"All done! The home-manager tool should now be installed and you can edit\n" +"\n" +" %s\n" +"\n" +"to configure Home Manager. Run 'man home-configuration.nix' to\n" +"see all available options." +msgstr "" + +#. translators: The "%s" specifier will be replaced by a URL. +#: home-manager/home-manager:491 +msgid "" +"Uh oh, the installation failed! Please create an issue at\n" +"\n" +" %s\n" +"\n" +"if the error seems to be the fault of Home Manager." +msgstr "" + +#. translators: Here "flake" is a noun that refers to the Nix Flakes feature. +#: home-manager/home-manager:502 +msgid "Can't instantiate a flake configuration" +msgstr "" + +#: home-manager/home-manager:578 +msgid "" +"There is %d unread and relevant news item.\n" +"Read it by running the command \"%s news\"." +msgid_plural "" +"There are %d unread and relevant news items.\n" +"Read them by running the command \"%s news\"." +msgstr[0] "" +msgstr[1] "" + +#: home-manager/home-manager:592 +msgid "Unknown \"news.display\" setting \"%s\"." +msgstr "" + +#: home-manager/home-manager:600 +#, sh-format +msgid "Please set the $EDITOR or $VISUAL environment variable" +msgstr "" + +#: home-manager/home-manager:618 +msgid "Cannot run build in read-only directory" +msgstr "" + +#: home-manager/home-manager:699 +msgid "No generation with ID %s" +msgstr "" + +#: home-manager/home-manager:701 +msgid "Cannot remove the current generation %s" +msgstr "" + +#: home-manager/home-manager:703 +msgid "Removing generation %s" +msgstr "" + +#: home-manager/home-manager:724 +msgid "No generations to expire" +msgstr "" + +#: home-manager/home-manager:735 +msgid "No home-manager packages seem to be installed." +msgstr "" + +#: home-manager/home-manager:820 +msgid "Unknown argument %s" +msgstr "" + +#: home-manager/home-manager:845 +msgid "This will remove Home Manager from your system." +msgstr "" + +#: home-manager/home-manager:848 +msgid "This is a dry run, nothing will actually be uninstalled." +msgstr "" + +#: home-manager/home-manager:852 +msgid "Really uninstall Home Manager?" +msgstr "" + +#: home-manager/home-manager:858 +msgid "Switching to empty Home Manager configuration..." +msgstr "" + +#: home-manager/home-manager:873 +msgid "Yay!" +msgstr "" + +#: home-manager/home-manager:878 +msgid "Home Manager is uninstalled but your home.nix is left untouched." +msgstr "" + +#: home-manager/home-manager:1101 +msgid "expire-generations expects one argument, got %d." +msgstr "" + +#: home-manager/home-manager:1123 +msgid "Unknown command: %s" +msgstr "" + +#: home-manager/install.nix:18 +msgid "This derivation is not buildable, please run it using nix-shell." +msgstr "" diff --git a/home-manager/po/tr.po b/home-manager/po/tr.po index 66c89e608..b728b5882 100644 --- a/home-manager/po/tr.po +++ b/home-manager/po/tr.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: Home Manager\n" "Report-Msgid-Bugs-To: https://github.com/nix-community/home-manager/issues\n" -"POT-Creation-Date: 2024-04-17 23:19+0200\n" +"POT-Creation-Date: 2025-01-03 09:09+0100\n" "PO-Revision-Date: 2024-04-19 17:07+0000\n" "Last-Translator: Oğuz Ersen \n" "Language-Team: Turkish \n" +"POT-Creation-Date: 2025-01-03 09:09+0100\n" +"PO-Revision-Date: 2024-11-18 15:00+0000\n" +"Last-Translator: wadsaek \n" "Language-Team: Ukrainian \n" "Language: uk\n" @@ -18,21 +18,21 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && " "n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" -"X-Generator: Weblate 5.4\n" +"X-Generator: Weblate 5.9-dev\n" #. translators: For example: "home-manager: missing argument for --cores" #: home-manager/home-manager:16 msgid "%s: missing argument for %s" -msgstr "" +msgstr "%s: відсутній аргумент для %s" -#: home-manager/home-manager:64 +#: home-manager/home-manager:69 msgid "No configuration file found at %s" msgstr "Файл конфігурації не знайдено в %s" #. translators: The first '%s' specifier will be replaced by either #. 'home.nix' or 'flake.nix'. -#: home-manager/home-manager:81 home-manager/home-manager:85 -#: home-manager/home-manager:184 +#: home-manager/home-manager:86 home-manager/home-manager:90 +#: home-manager/home-manager:189 msgid "" "Keeping your Home Manager %s in %s is deprecated,\n" "please move it to %s" @@ -40,16 +40,16 @@ msgstr "" "Збереження вашого Home Manager %s у %s є застарілим,\n" "будь ласка, перемістіть його до %s" -#: home-manager/home-manager:92 +#: home-manager/home-manager:97 msgid "No configuration file found. Please create one at %s" msgstr "Файл конфігурації не знайдено. Будь ласка, створіть його в %s" -#: home-manager/home-manager:107 +#: home-manager/home-manager:112 msgid "Home Manager not found at %s." msgstr "Home Manager не знайдено на %s." #. translators: This message will be seen by very few users that likely are familiar with English. So feel free to leave this untranslated. -#: home-manager/home-manager:115 +#: home-manager/home-manager:120 msgid "" "The fallback Home Manager path %s has been deprecated and a file/directory " "was found there." @@ -57,7 +57,7 @@ msgstr "" "Резервний шлях до Home Manager %s застарів, і там було знайдено файл/каталог." #. translators: This message will be seen by very few users that likely are familiar with English. So feel free to leave this untranslated. -#: home-manager/home-manager:118 +#: home-manager/home-manager:123 msgid "" "To remove this warning, do one of the following.\n" "\n" @@ -96,42 +96,42 @@ msgstr "" "\n" " $ rm -r \"%s\"" -#: home-manager/home-manager:146 +#: home-manager/home-manager:151 msgid "Sanity checking Nix" msgstr "Перевірка адекватності Nix" -#: home-manager/home-manager:166 +#: home-manager/home-manager:171 msgid "Could not find suitable profile directory, tried %s and %s" msgstr "Не вдалося знайти відповідний каталог профілю, спробував %s і %s" #. translators: Here "flake" is a noun that refers to the Nix Flakes feature. -#: home-manager/home-manager:221 +#: home-manager/home-manager:226 msgid "Can't inspect options of a flake configuration" msgstr "Неможливо перевірити параметри flake-конфігурації" -#: home-manager/home-manager:296 home-manager/home-manager:319 -#: home-manager/home-manager:1051 +#: home-manager/home-manager:301 home-manager/home-manager:324 +#: home-manager/home-manager:1061 msgid "%s: unknown option '%s'" msgstr "%s: невідомий параметр '%s'" -#: home-manager/home-manager:301 home-manager/home-manager:1052 +#: home-manager/home-manager:306 home-manager/home-manager:1062 msgid "Run '%s --help' for usage help" msgstr "Запустіть '%s --help' для отримання довідки про використання" -#: home-manager/home-manager:327 home-manager/home-manager:431 +#: home-manager/home-manager:332 home-manager/home-manager:437 msgid "The file %s already exists, leaving it unchanged..." msgstr "Файл %s вже існує, залишаючи його незмінним..." -#: home-manager/home-manager:329 home-manager/home-manager:433 +#: home-manager/home-manager:334 home-manager/home-manager:439 msgid "Creating %s..." msgstr "Створення %s..." -#: home-manager/home-manager:475 +#: home-manager/home-manager:481 msgid "Creating initial Home Manager generation..." msgstr "Створення початкової генерації Home Manager..." #. translators: The "%s" specifier will be replaced by a file path. -#: home-manager/home-manager:480 +#: home-manager/home-manager:486 msgid "" "All done! The home-manager tool should now be installed and you can edit\n" "\n" @@ -149,7 +149,7 @@ msgstr "" "переглянути всі доступні варіанти." #. translators: The "%s" specifier will be replaced by a URL. -#: home-manager/home-manager:485 +#: home-manager/home-manager:491 msgid "" "Uh oh, the installation failed! Please create an issue at\n" "\n" @@ -164,11 +164,11 @@ msgstr "" "якщо здається, що помилка сталася через Home Manager." #. translators: Here "flake" is a noun that refers to the Nix Flakes feature. -#: home-manager/home-manager:496 +#: home-manager/home-manager:502 msgid "Can't instantiate a flake configuration" msgstr "Не вдається створити екземпляр flake-конфігурації" -#: home-manager/home-manager:572 +#: home-manager/home-manager:578 msgid "" "There is %d unread and relevant news item.\n" "Read it by running the command \"%s news\"." @@ -185,72 +185,72 @@ msgstr[2] "" "Є %d непрочитаних і ревалентних новин.\n" "Прочитайте їх, виконавши команду \"%s news\"." -#: home-manager/home-manager:586 +#: home-manager/home-manager:592 msgid "Unknown \"news.display\" setting \"%s\"." msgstr "Невідоме налаштування \"news.display\" \"%s\"." -#: home-manager/home-manager:594 +#: home-manager/home-manager:600 #, sh-format msgid "Please set the $EDITOR or $VISUAL environment variable" msgstr "Будь ласка, встановіть змінну оточення $EDITOR або $VISUAL" -#: home-manager/home-manager:612 +#: home-manager/home-manager:618 msgid "Cannot run build in read-only directory" msgstr "Неможливо запустити збірку в каталозі, доступному лише для читання" -#: home-manager/home-manager:693 +#: home-manager/home-manager:699 msgid "No generation with ID %s" msgstr "Немає генерації з ID %s" -#: home-manager/home-manager:695 +#: home-manager/home-manager:701 msgid "Cannot remove the current generation %s" msgstr "Не вдається видалити поточну генерацію %s" -#: home-manager/home-manager:697 +#: home-manager/home-manager:703 msgid "Removing generation %s" msgstr "Видалення генерації %s" -#: home-manager/home-manager:718 +#: home-manager/home-manager:724 msgid "No generations to expire" msgstr "Немає генерацій, термін дії яких закінчується" -#: home-manager/home-manager:729 +#: home-manager/home-manager:735 msgid "No home-manager packages seem to be installed." msgstr "Здається, не встановлено жодних пакунків home-manager." -#: home-manager/home-manager:811 +#: home-manager/home-manager:820 msgid "Unknown argument %s" msgstr "Невідомий аргумент %s" -#: home-manager/home-manager:835 +#: home-manager/home-manager:845 msgid "This will remove Home Manager from your system." msgstr "Це призведе до видалення Home Manager з вашої системи." -#: home-manager/home-manager:838 +#: home-manager/home-manager:848 msgid "This is a dry run, nothing will actually be uninstalled." msgstr "Це пробний запуск, насправді нічого не буде видалено." -#: home-manager/home-manager:842 +#: home-manager/home-manager:852 msgid "Really uninstall Home Manager?" msgstr "Дійсно видаліть Home Manager?" -#: home-manager/home-manager:848 +#: home-manager/home-manager:858 msgid "Switching to empty Home Manager configuration..." msgstr "Перехід до порожньої конфігурації Home Manager..." -#: home-manager/home-manager:863 +#: home-manager/home-manager:873 msgid "Yay!" msgstr "Ура!" -#: home-manager/home-manager:868 +#: home-manager/home-manager:878 msgid "Home Manager is uninstalled but your home.nix is left untouched." msgstr "Home Manager буде видалено, але ваш home.nix залишиться недоторканим." -#: home-manager/home-manager:1091 +#: home-manager/home-manager:1101 msgid "expire-generations expects one argument, got %d." msgstr "expire-generation очікує один аргумент, отримав %d." -#: home-manager/home-manager:1113 +#: home-manager/home-manager:1123 msgid "Unknown command: %s" msgstr "Невідома команда: %s" diff --git a/home-manager/po/vi.po b/home-manager/po/vi.po index 749de0218..a21467c37 100644 --- a/home-manager/po/vi.po +++ b/home-manager/po/vi.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: Home Manager\n" "Report-Msgid-Bugs-To: https://github.com/nix-community/home-manager/issues\n" -"POT-Creation-Date: 2024-04-17 23:19+0200\n" +"POT-Creation-Date: 2025-01-03 09:09+0100\n" "PO-Revision-Date: 2024-08-01 04:09+0000\n" "Last-Translator: goatastronaut0212 \n" "Language-Team: Vietnamese \n" "Language-Team: Chinese (Simplified) \n" -"Language-Team: Chinese (Traditional) \n" +"POT-Creation-Date: 2025-01-03 09:09+0100\n" +"PO-Revision-Date: 2025-03-07 18:58+0000\n" +"Last-Translator: 807 \n" +"Language-Team: Chinese (Traditional Han script) \n" "Language: zh_Hant\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Weblate 5.4\n" +"X-Generator: Weblate 5.10.3-dev\n" #. translators: For example: "home-manager: missing argument for --cores" #: home-manager/home-manager:16 msgid "%s: missing argument for %s" -msgstr "" +msgstr "%s: 缺少參數 %s" -#: home-manager/home-manager:64 +#: home-manager/home-manager:69 msgid "No configuration file found at %s" msgstr "未在 %s 處找到配置檔案" #. translators: The first '%s' specifier will be replaced by either #. 'home.nix' or 'flake.nix'. -#: home-manager/home-manager:81 home-manager/home-manager:85 -#: home-manager/home-manager:184 +#: home-manager/home-manager:86 home-manager/home-manager:90 +#: home-manager/home-manager:189 msgid "" "Keeping your Home Manager %s in %s is deprecated,\n" "please move it to %s" msgstr "" +"保持你的 Home Manager 在 %s 中,%s 已被拋棄,\n" +"請將它移動到 %s" -#: home-manager/home-manager:92 +#: home-manager/home-manager:97 msgid "No configuration file found. Please create one at %s" msgstr "未找到配置檔案。請在 %s 處建立一份" -#: home-manager/home-manager:107 +#: home-manager/home-manager:112 msgid "Home Manager not found at %s." -msgstr "" +msgstr "在 %s 中找不到 Home Manager。" #. translators: This message will be seen by very few users that likely are familiar with English. So feel free to leave this untranslated. -#: home-manager/home-manager:115 +#: home-manager/home-manager:120 msgid "" "The fallback Home Manager path %s has been deprecated and a file/directory " "was found there." -msgstr "" +msgstr "備用的 Home Manager 路徑 %s 已被拋棄,但一個檔案/資料夾在這被找到。" #. translators: This message will be seen by very few users that likely are familiar with English. So feel free to leave this untranslated. -#: home-manager/home-manager:118 +#: home-manager/home-manager:123 msgid "" "To remove this warning, do one of the following.\n" "\n" @@ -73,43 +75,60 @@ msgid "" "\n" " $ rm -r \"%s\"" msgstr "" +"要消除這個警告,請做以下其中一步。\n" +"\n" +"1. 告訴Home Manager去使用路徑,例如加入\n" +"\n" +" { programs.home-manager.path = \"%s\"; }\n" +"\n" +" 到你的配置中。\n" +"\n" +" 如果你想要直接引入Home Manager, 請你使用 `path` 參數r\n" +"\n" +" pkgs.callPackage /path/to/home-manager-package { path = \"%s\"; }\n" +"\n" +" 當呼叫 Home Manager 模組。\n" +"\n" +"2. 刪除無效的路徑\n" +"\n" +" $ rm -r \"%s\"" -#: home-manager/home-manager:146 +#: home-manager/home-manager:151 msgid "Sanity checking Nix" msgstr "正在進行 Nix 完整性檢查" -#: home-manager/home-manager:166 +#: home-manager/home-manager:171 msgid "Could not find suitable profile directory, tried %s and %s" -msgstr "" +msgstr "找不到合適的 profile 目錄,已經嘗試 %s 和 %s" #. translators: Here "flake" is a noun that refers to the Nix Flakes feature. -#: home-manager/home-manager:221 +#: home-manager/home-manager:226 msgid "Can't inspect options of a flake configuration" msgstr "無法檢查 flake 配置中的選項" -#: home-manager/home-manager:296 home-manager/home-manager:319 -#: home-manager/home-manager:1051 +#: home-manager/home-manager:301 home-manager/home-manager:324 +#: home-manager/home-manager:1061 msgid "%s: unknown option '%s'" msgstr "%s:未知選項 ‘%s’" -#: home-manager/home-manager:301 home-manager/home-manager:1052 +#: home-manager/home-manager:306 home-manager/home-manager:1062 msgid "Run '%s --help' for usage help" msgstr "執行 ‘%s --help’ 獲取用法幫助" -#: home-manager/home-manager:327 home-manager/home-manager:431 +#: home-manager/home-manager:332 home-manager/home-manager:437 msgid "The file %s already exists, leaving it unchanged..." -msgstr "" +msgstr "檔案 %s 已經存在,不更改它..." -#: home-manager/home-manager:329 home-manager/home-manager:433 +#: home-manager/home-manager:334 home-manager/home-manager:439 msgid "Creating %s..." -msgstr "" +msgstr "創建 %s 中..." -#: home-manager/home-manager:475 +#: home-manager/home-manager:481 msgid "Creating initial Home Manager generation..." msgstr "正在建立初始 Home Manager 世代 ..." #. translators: The "%s" specifier will be replaced by a file path. -#: home-manager/home-manager:480 +#: home-manager/home-manager:486 msgid "" "All done! The home-manager tool should now be installed and you can edit\n" "\n" @@ -126,7 +145,7 @@ msgstr "" "來檢視所有可用選項。" #. translators: The "%s" specifier will be replaced by a URL. -#: home-manager/home-manager:485 +#: home-manager/home-manager:491 msgid "" "Uh oh, the installation failed! Please create an issue at\n" "\n" @@ -141,11 +160,11 @@ msgstr "" "處建立 Issue 告知我們。" #. translators: Here "flake" is a noun that refers to the Nix Flakes feature. -#: home-manager/home-manager:496 +#: home-manager/home-manager:502 msgid "Can't instantiate a flake configuration" msgstr "無法建立 flake 配置例項" -#: home-manager/home-manager:572 +#: home-manager/home-manager:578 msgid "" "There is %d unread and relevant news item.\n" "Read it by running the command \"%s news\"." @@ -156,72 +175,72 @@ msgstr[0] "" "有 %d 條未讀的相關新聞或訊息。\n" "可執行 “%s news” 命令進行閱讀。" -#: home-manager/home-manager:586 +#: home-manager/home-manager:592 msgid "Unknown \"news.display\" setting \"%s\"." msgstr "未知的 “news.display” 設定項 “%s”。" -#: home-manager/home-manager:594 +#: home-manager/home-manager:600 #, sh-format msgid "Please set the $EDITOR or $VISUAL environment variable" -msgstr "" +msgstr "請設定 $EDITOR 或 $VISUAL 環境變數" -#: home-manager/home-manager:612 +#: home-manager/home-manager:618 msgid "Cannot run build in read-only directory" -msgstr "無法在只讀目錄中執行構建" +msgstr "無法在唯讀目錄中執行構建" -#: home-manager/home-manager:693 +#: home-manager/home-manager:699 msgid "No generation with ID %s" msgstr "沒有 ID 為 %s 的世代" -#: home-manager/home-manager:695 +#: home-manager/home-manager:701 msgid "Cannot remove the current generation %s" msgstr "無法移除當前世代 %s" -#: home-manager/home-manager:697 +#: home-manager/home-manager:703 msgid "Removing generation %s" msgstr "正在移除世代 %s" -#: home-manager/home-manager:718 +#: home-manager/home-manager:724 msgid "No generations to expire" msgstr "沒有即將過期的世代" -#: home-manager/home-manager:729 +#: home-manager/home-manager:735 msgid "No home-manager packages seem to be installed." msgstr "似乎沒有安裝 home-manager 軟體包。" -#: home-manager/home-manager:811 +#: home-manager/home-manager:820 msgid "Unknown argument %s" msgstr "未知引數 %s" -#: home-manager/home-manager:835 +#: home-manager/home-manager:845 msgid "This will remove Home Manager from your system." msgstr "這將會從系統中移除 Home Manager。" -#: home-manager/home-manager:838 +#: home-manager/home-manager:848 msgid "This is a dry run, nothing will actually be uninstalled." msgstr "這是試執行結果,沒有實際解除安裝任何軟體包。" -#: home-manager/home-manager:842 +#: home-manager/home-manager:852 msgid "Really uninstall Home Manager?" msgstr "確定要解除安裝 Home Manager 嗎?" -#: home-manager/home-manager:848 +#: home-manager/home-manager:858 msgid "Switching to empty Home Manager configuration..." msgstr "正在切換至空的 Home Manager 配置 ..." -#: home-manager/home-manager:863 +#: home-manager/home-manager:873 msgid "Yay!" msgstr "好耶!" -#: home-manager/home-manager:868 +#: home-manager/home-manager:878 msgid "Home Manager is uninstalled but your home.nix is left untouched." msgstr "Home Manager 已解除安裝,但未改動您的 home.nix 配置檔案。" -#: home-manager/home-manager:1091 +#: home-manager/home-manager:1101 msgid "expire-generations expects one argument, got %d." msgstr "expire-generations 須要一個引數,但獲取到了 %d 個。" -#: home-manager/home-manager:1113 +#: home-manager/home-manager:1123 msgid "Unknown command: %s" msgstr "未知命令:%s" diff --git a/lib/default.nix b/lib/default.nix new file mode 100644 index 000000000..5d0eb5f41 --- /dev/null +++ b/lib/default.nix @@ -0,0 +1,49 @@ +{ lib }: { + hm = (import ../modules/lib/stdlib-extended.nix lib).hm; + homeManagerConfiguration = { modules ? [ ], pkgs, lib ? pkgs.lib + , extraSpecialArgs ? { }, check ? true + # Deprecated: + , configuration ? null, extraModules ? null, stateVersion ? null + , username ? null, homeDirectory ? null, system ? null }@args: + let + msgForRemovedArg = '' + The 'homeManagerConfiguration' arguments + + - 'configuration', + - 'username', + - 'homeDirectory' + - 'stateVersion', + - 'extraModules', and + - 'system' + + have been removed. Instead use the arguments 'pkgs' and + 'modules'. See the 22.11 release notes for more: https://nix-community.github.io/home-manager/release-notes.xhtml#sec-release-22.11-highlights + ''; + + throwForRemovedArgs = v: + let + used = builtins.filter (n: (args.${n} or null) != null) [ + "configuration" + "username" + "homeDirectory" + "stateVersion" + "extraModules" + "system" + ]; + msg = msgForRemovedArg + '' + + + Deprecated args passed: '' + builtins.concatStringsSep " " used; + in lib.throwIf (used != [ ]) msg v; + + in throwForRemovedArgs (import ../modules { + inherit pkgs lib check extraSpecialArgs; + configuration = { ... }: { + imports = modules ++ [{ programs.home-manager.path = "${../.}"; }]; + nixpkgs = { + config = lib.mkDefault pkgs.config; + inherit (pkgs) overlays; + }; + }; + }); +} diff --git a/modules/accounts/calendar.nix b/modules/accounts/calendar.nix index bfbc3e124..d71d4dff3 100644 --- a/modules/accounts/calendar.nix +++ b/modules/accounts/calendar.nix @@ -1,8 +1,6 @@ -{ config, lib, pkgs, ... }: - -with lib; - +{ config, lib, ... }: let + inherit (lib) mkOption types; cfg = config.accounts.calendar; @@ -12,7 +10,8 @@ let path = mkOption { type = types.str; default = "${cfg.basePath}/${name}"; - defaultText = "‹accounts.calendar.basePath›/‹name›"; + defaultText = + lib.literalExpression "‹accounts.calendar.basePath›/‹name›"; description = "The path of the storage."; }; @@ -69,7 +68,7 @@ let }; }; - calendarOpts = { name, config, ... }: { + calendarOpts = { name, ... }: { options = { name = mkOption { type = types.str; @@ -124,7 +123,7 @@ in { type = types.str; example = ".calendar"; apply = p: - if hasPrefix "/" p then p else "${config.home.homeDirectory}/${p}"; + if lib.hasPrefix "/" p then p else "${config.home.homeDirectory}/${p}"; description = '' The base directory in which to save calendars. May be a relative path, in which case it is relative the home @@ -143,15 +142,15 @@ in { description = "List of calendars."; }; }; - config = mkIf (cfg.accounts != { }) { + config = lib.mkIf (cfg.accounts != { }) { assertions = let - primaries = - catAttrs "name" (filter (a: a.primary) (attrValues cfg.accounts)); + primaries = lib.catAttrs "name" + (lib.filter (a: a.primary) (lib.attrValues cfg.accounts)); in [{ - assertion = length primaries <= 1; + assertion = lib.length primaries <= 1; message = "Must have at most one primary calendar account but found " - + toString (length primaries) + ", namely " - + concatStringsSep ", " primaries; + + toString (lib.length primaries) + ", namely " + + lib.concatStringsSep ", " primaries; }]; }; } diff --git a/modules/accounts/contacts.nix b/modules/accounts/contacts.nix index 272594b18..b5d93f21f 100644 --- a/modules/accounts/contacts.nix +++ b/modules/accounts/contacts.nix @@ -1,8 +1,7 @@ -{ config, lib, pkgs, ... }: - -with lib; +{ config, lib, ... }: let + inherit (lib) mkOption types; cfg = config.accounts.contact; @@ -12,7 +11,8 @@ let path = mkOption { type = types.str; default = "${cfg.basePath}/${name}"; - defaultText = "‹accounts.contact.basePath›/‹name›"; + defaultText = + lib.literalExpression "‹accounts.contact.basePath›/‹name›"; description = "The path of the storage."; }; @@ -77,7 +77,7 @@ let }; }; - contactOpts = { name, config, ... }: { + contactOpts = { name, ... }: { options = { name = mkOption { type = types.str; @@ -113,7 +113,7 @@ in { basePath = mkOption { type = types.str; apply = p: - if hasPrefix "/" p then p else "${config.home.homeDirectory}/${p}"; + if lib.hasPrefix "/" p then p else "${config.home.homeDirectory}/${p}"; description = '' The base directory in which to save contacts. May be a relative path, in which case it is relative the home diff --git a/modules/accounts/email.nix b/modules/accounts/email.nix index f3996195d..2395f7e39 100644 --- a/modules/accounts/email.nix +++ b/modules/accounts/email.nix @@ -1,8 +1,7 @@ -{ config, lib, pkgs, ... }: - -with lib; +{ config, lib, ... }: let + inherit (lib) mkDefault mkIf mkOption types; cfg = config.accounts.email; @@ -49,7 +48,7 @@ let default = '' -- ''; - example = literalExpression '' + example = lib.literalExpression '' ~*~*~*~*~*~*~*~*~*~*~*~ ''; description = '' @@ -60,7 +59,7 @@ let command = mkOption { type = with types; nullOr path; default = null; - example = literalExpression '' + example = lib.literalExpression '' pkgs.writeScript "signature" "echo This is my signature" ''; description = "A command that generates a signature."; @@ -247,6 +246,7 @@ let "fastmail.com" "yandex.com" "outlook.office365.com" + "migadu.com" ]; default = "plain"; description = '' @@ -267,10 +267,26 @@ let }; aliases = mkOption { - type = types.listOf (types.strMatching ".*@.*"); + description = "Alternative identities of this account."; default = [ ]; example = [ "webmaster@example.org" "admin@example.org" ]; - description = "Alternative email addresses of this account."; + type = types.listOf (types.oneOf [ + (types.strMatching ".*@.*") + (types.submodule { + options = { + realName = mkOption { + type = types.str; + example = "Jane Doe"; + description = "Name displayed when sending mails."; + }; + address = mkOption { + type = types.strMatching ".*@.*"; + example = "jane.doe@example.org"; + description = "The email address of this identity."; + }; + }; + }) + ]); }; realName = mkOption { @@ -291,7 +307,7 @@ let passwordCommand = mkOption { type = types.nullOr (types.either types.str (types.listOf types.str)); default = null; - apply = p: if isString p then splitString " " p else p; + apply = p: if lib.isString p then lib.splitString " " p else p; example = "secret-tool lookup email me@example.org"; description = '' A command, which when run writes the account password on @@ -390,10 +406,10 @@ let }; }; - config = mkMerge [ + config = lib.mkMerge [ { name = name; - maildir = mkOptionDefault { path = "${name}"; }; + maildir = lib.mkOptionDefault { path = "${name}"; }; } (mkIf (config.flavor == "yandex.com") { @@ -450,6 +466,20 @@ let }; }) + (mkIf (config.flavor == "migadu.com") { + userName = mkDefault config.address; + + imap = { + host = "imap.migadu.com"; + port = 993; + }; + + smtp = { + host = "smtp.migadu.com"; + port = 465; + }; + }) + (mkIf (config.flavor == "gmail.com") { userName = mkDefault config.address; @@ -495,7 +525,7 @@ in { default = "${config.home.homeDirectory}/Maildir"; defaultText = "Maildir"; apply = p: - if hasPrefix "/" p then p else "${config.home.homeDirectory}/${p}"; + if lib.hasPrefix "/" p then p else "${config.home.homeDirectory}/${p}"; description = '' The base directory for account maildir directories. May be a relative path (e.g. the user setting this value as "MyMaildir"), @@ -514,13 +544,14 @@ in { config = mkIf (cfg.accounts != { }) { assertions = [ (let - primaries = - catAttrs "name" (filter (a: a.primary) (attrValues cfg.accounts)); + primaries = lib.catAttrs "name" + (lib.filter (a: a.primary) (lib.attrValues cfg.accounts)); in { - assertion = length primaries == 1; + assertion = lib.length primaries == 1; message = "Must have exactly one primary mail account but found " - + toString (length primaries) + optionalString (length primaries > 1) - (", namely " + concatStringsSep ", " primaries); + + toString (lib.length primaries) + + lib.optionalString (lib.length primaries > 1) + (", namely " + lib.concatStringsSep ", " primaries); }) ]; }; diff --git a/modules/config/home-cursor.nix b/modules/config/home-cursor.nix index cb9a2ab28..ee8edbbb6 100644 --- a/modules/config/home-cursor.nix +++ b/modules/config/home-cursor.nix @@ -1,13 +1,17 @@ { config, options, lib, pkgs, ... }: -with lib; - let + inherit (lib) + mkEnableOption mkOption mkIf mkMerge mkDefault mkAliasOptionModule types + literalExpression escapeShellArg hm getAttrFromPath any optional; cfg = config.home.pointerCursor; + opts = options.home.pointerCursor; pointerCursorModule = types.submodule { options = { + enable = mkEnableOption "cursor config generation"; + package = mkOption { type = types.package; example = literalExpression "pkgs.vanilla-dmz"; @@ -45,6 +49,30 @@ let gtk config generation for {option}`home.pointerCursor` ''; }; + + dotIcons = { + enable = mkEnableOption '' + `.icons` config generation for {option}`home.pointerCursor` + '' // { + default = true; + }; + }; + + hyprcursor = { + enable = mkEnableOption "hyprcursor config generation"; + + size = mkOption { + type = types.nullOr types.int; + example = 32; + default = null; + description = "The cursor size for hyprcursor."; + }; + }; + + sway = { + enable = mkEnableOption + "sway config generation for {option}`home.pointerCursor`"; + }; }; }; @@ -67,7 +95,7 @@ let }; in { - meta.maintainers = [ maintainers.league ]; + meta.maintainers = [ lib.maintainers.league ]; imports = [ (mkAliasOptionModule [ "xsession" "pointerCursor" "package" ] [ @@ -91,17 +119,6 @@ in { "x11" "defaultCursor" ]) - - ({ ... }: { - warnings = optional (any (x: - getAttrFromPath - ([ "xsession" "pointerCursor" ] ++ [ x ] ++ [ "isDefined" ]) - options) [ "package" "name" "size" "defaultCursor" ]) '' - The option `xsession.pointerCursor` has been merged into `home.pointerCursor` and will be removed - in the future. Please change to set `home.pointerCursor` directly and enable `home.pointerCursor.x11.enable` - to generate x11 specific cursor configurations. You can refer to the documentation for more details. - ''; - }) ]; options = { @@ -109,7 +126,7 @@ in { type = types.nullOr pointerCursorModule; default = null; description = '' - Cursor configuration. Set to `null` to disable. + Cursor configuration. Top-level options declared under this submodule are backend independent options. Options declared under namespaces such as `x11` @@ -128,55 +145,107 @@ in { }; }; - config = mkIf (cfg != null) (mkMerge [ + config = let + # Check if enable option was explicitly defined by the user + enableDefined = any (x: x ? enable) opts.definitions; + + # Determine if cursor configuration should be enabled + enable = if enableDefined then cfg.enable else cfg != null; + in mkMerge [ + (mkIf enable (mkMerge [ + { + assertions = [ + (hm.assertions.assertPlatform "home.pointerCursor" pkgs + lib.platforms.linux) + ]; + + home.packages = [ cfg.package defaultIndexThemePackage ]; + + home.sessionVariables = { + XCURSOR_SIZE = mkDefault cfg.size; + XCURSOR_THEME = mkDefault cfg.name; + }; + + # Set directory to look for cursors in, needed for some applications + # that are unable to find cursors otherwise. See: + # https://github.com/nix-community/home-manager/issues/2812 + # https://wiki.archlinux.org/title/Cursor_themes#Environment_variable + home.sessionSearchVariables.XCURSOR_PATH = + [ "${config.home.profileDirectory}/share/icons" ]; + + # Add cursor icon link to $XDG_DATA_HOME/icons as well for redundancy. + xdg.dataFile."icons/default/index.theme".source = + "${defaultIndexThemePackage}/share/icons/default/index.theme"; + xdg.dataFile."icons/${cfg.name}".source = + "${cfg.package}/share/icons/${cfg.name}"; + } + + (mkIf cfg.dotIcons.enable { + # Add symlink of cursor icon directory to $HOME/.icons, needed for + # backwards compatibility with some applications. See: + # https://specifications.freedesktop.org/icon-theme-spec/latest/ar01s03.html + home.file.".icons/default/index.theme".source = + "${defaultIndexThemePackage}/share/icons/default/index.theme"; + home.file.".icons/${cfg.name}".source = + "${cfg.package}/share/icons/${cfg.name}"; + }) + + (mkIf cfg.x11.enable { + xsession.profileExtra = '' + ${pkgs.xorg.xsetroot}/bin/xsetroot -xcf ${cursorPath} ${ + toString cfg.size + } + ''; + + xresources.properties = { + "Xcursor.theme" = cfg.name; + "Xcursor.size" = cfg.size; + }; + }) + + (mkIf cfg.gtk.enable { + gtk.cursorTheme = mkDefault { inherit (cfg) package name size; }; + }) + + (mkIf cfg.hyprcursor.enable { + home.sessionVariables = { + HYPRCURSOR_THEME = cfg.name; + HYPRCURSOR_SIZE = if cfg.hyprcursor.size != null then + cfg.hyprcursor.size + else + cfg.size; + }; + }) + + (mkIf cfg.sway.enable { + wayland.windowManager.sway = { + config = { + seat = { + "*" = { + xcursor_theme = + "${cfg.name} ${toString config.gtk.cursorTheme.size}"; + }; + }; + }; + }; + }) + ])) + { - assertions = [ - (hm.assertions.assertPlatform "home.pointerCursor" pkgs platforms.linux) - ]; + warnings = (optional (any (x: + getAttrFromPath + ([ "xsession" "pointerCursor" ] ++ [ x ] ++ [ "isDefined" ]) + options) [ "package" "name" "size" "defaultCursor" ]) '' + The option `xsession.pointerCursor` has been merged into `home.pointerCursor` and will be removed + in the future. Please change to set `home.pointerCursor` directly and enable `home.pointerCursor.x11.enable` + to generate x11 specific cursor configurations. You can refer to the documentation for more details. + '') ++ (optional (opts.highestPrio != (lib.mkOptionDefault { }).priority + && cfg == null) '' + Setting home.pointerCursor to null is deprecated. + Please update your configuration to explicitly set: - home.packages = [ cfg.package defaultIndexThemePackage ]; - - # Set directory to look for cursors in, needed for some applications - # that are unable to find cursors otherwise. See: - # https://github.com/nix-community/home-manager/issues/2812 - # https://wiki.archlinux.org/title/Cursor_themes#Environment_variable - home.sessionVariables = { - XCURSOR_PATH = mkDefault ("$XCURSOR_PATH\${XCURSOR_PATH:+:}" - + "${config.home.profileDirectory}/share/icons"); - XCURSOR_SIZE = mkDefault cfg.size; - XCURSOR_THEME = mkDefault cfg.name; - }; - - # Add symlink of cursor icon directory to $HOME/.icons, needed for - # backwards compatibility with some applications. See: - # https://specifications.freedesktop.org/icon-theme-spec/latest/ar01s03.html - home.file.".icons/default/index.theme".source = - "${defaultIndexThemePackage}/share/icons/default/index.theme"; - home.file.".icons/${cfg.name}".source = - "${cfg.package}/share/icons/${cfg.name}"; - - # Add cursor icon link to $XDG_DATA_HOME/icons as well for redundancy. - xdg.dataFile."icons/default/index.theme".source = - "${defaultIndexThemePackage}/share/icons/default/index.theme"; - xdg.dataFile."icons/${cfg.name}".source = - "${cfg.package}/share/icons/${cfg.name}"; + home.pointerCursor.enable = false; + ''); } - - (mkIf cfg.x11.enable { - xsession.initExtra = '' - ${pkgs.xorg.xsetroot}/bin/xsetroot -xcf ${cursorPath} ${ - toString cfg.size - } - ''; - - xresources.properties = { - "Xcursor.theme" = cfg.name; - "Xcursor.size" = cfg.size; - }; - }) - - (mkIf cfg.gtk.enable { - gtk.cursorTheme = mkDefault { inherit (cfg) package name size; }; - }) - ]); + ]; } diff --git a/modules/config/i18n.nix b/modules/config/i18n.nix index 2efb53d62..409227236 100644 --- a/modules/config/i18n.nix +++ b/modules/config/i18n.nix @@ -17,8 +17,6 @@ { lib, pkgs, config, ... }: -with lib; - let inherit (config.i18n) glibcLocales; @@ -27,19 +25,19 @@ let archivePath = "${glibcLocales}/lib/locale/locale-archive"; # lookup the version of glibcLocales and set the appropriate environment vars - localeVars = if versionAtLeast version "2.27" then { + localeVars = if lib.versionAtLeast version "2.27" then { LOCALE_ARCHIVE_2_27 = archivePath; - } else if versionAtLeast version "2.11" then { + } else if lib.versionAtLeast version "2.11" then { LOCALE_ARCHIVE_2_11 = archivePath; } else { }; in { - meta.maintainers = with maintainers; [ midchildan ]; + meta.maintainers = with lib.maintainers; [ midchildan ]; options = { - i18n.glibcLocales = mkOption { - type = types.path; + i18n.glibcLocales = lib.mkOption { + type = lib.types.path; description = '' Customized `glibcLocales` package providing the `LOCALE_ARCHIVE_*` environment variable. @@ -50,7 +48,7 @@ in { will be set to {var}`i18n.glibcLocales` from the system configuration. ''; - example = literalExpression '' + example = lib.literalExpression '' pkgs.glibcLocales.override { allLocales = false; locales = [ "en_US.UTF-8/UTF-8" ]; @@ -58,11 +56,11 @@ in { ''; # NB. See nixos/default.nix for NixOS default. default = pkgs.glibcLocales; - defaultText = literalExpression "pkgs.glibcLocales"; + defaultText = lib.literalExpression "pkgs.glibcLocales"; }; }; - config = mkIf pkgs.stdenv.hostPlatform.isLinux { + config = lib.mkIf pkgs.stdenv.hostPlatform.isLinux { # For shell sessions. home.sessionVariables = localeVars; diff --git a/modules/default.nix b/modules/default.nix index 6c54148ab..05d2a504c 100644 --- a/modules/default.nix +++ b/modules/default.nix @@ -5,16 +5,14 @@ # Extra arguments passed to specialArgs. , extraSpecialArgs ? { } }: -with lib; - let collectFailed = cfg: - map (x: x.message) (filter (x: !x.assertion) cfg.assertions); + map (x: x.message) (lib.filter (x: !x.assertion) cfg.assertions); showWarnings = res: let f = w: x: builtins.trace "warning: ${w}" x; - in fold f res res.config.warnings; + in lib.fold f res res.config.warnings; extendedLib = import ./lib/stdlib-extended.nix lib; @@ -32,7 +30,7 @@ let moduleChecks = raw: showWarnings (let failed = collectFailed raw.config; - failedStr = concatStringsSep "\n" (map (x: "- ${x}") failed); + failedStr = lib.concatStringsSep "\n" (map (x: "- ${x}") failed); in if failed == [ ] then raw else @@ -52,8 +50,8 @@ let activation-script = module.config.home.activationPackage; newsDisplay = rawModule.config.news.display; - newsEntries = sort (a: b: a.time > b.time) - (filter (a: a.condition) rawModule.config.news.entries); + newsEntries = lib.sort (a: b: a.time > b.time) + (lib.filter (a: a.condition) rawModule.config.news.entries); inherit (module._module.args) pkgs; diff --git a/modules/files.nix b/modules/files.nix index 59e9c2578..d359979db 100644 --- a/modules/files.nix +++ b/modules/files.nix @@ -1,10 +1,8 @@ { pkgs, config, lib, ... }: -with lib; - let - cfg = filterAttrs (n: f: f.enable) config.home.file; + cfg = lib.filterAttrs (n: f: f.enable) config.home.file; homeDirectory = config.home.homeDirectory; @@ -25,14 +23,14 @@ in { options = { - home.file = mkOption { + home.file = lib.mkOption { description = "Attribute set of files to link into the user home."; default = {}; type = fileType "home.file" "{env}`HOME`" homeDirectory; }; - home-files = mkOption { - type = types.package; + home-files = lib.mkOption { + type = lib.types.package; internal = true; description = "Package to contain all home files"; }; @@ -42,11 +40,11 @@ in assertions = [( let dups = - attrNames - (filterAttrs (n: v: v > 1) - (foldAttrs (acc: v: acc + v) 0 - (mapAttrsToList (n: v: { ${v.target} = 1; }) cfg))); - dupsStr = concatStringsSep ", " dups; + lib.attrNames + (lib.filterAttrs (n: v: v > 1) + (lib.foldAttrs (acc: v: acc + v) 0 + (lib.mapAttrsToList (n: v: { ${v.target} = 1; }) cfg))); + dupsStr = lib.concatStringsSep ", " dups; in { assertion = dups == []; message = '' @@ -64,22 +62,22 @@ in lib.file.mkOutOfStoreSymlink = path: let pathStr = toString path; - name = hm.strings.storeFileName (baseNameOf pathStr); + name = lib.hm.strings.storeFileName (baseNameOf pathStr); in - pkgs.runCommandLocal name {} ''ln -s ${escapeShellArg pathStr} $out''; + pkgs.runCommandLocal name {} ''ln -s ${lib.escapeShellArg pathStr} $out''; # This verifies that the links we are about to create will not # overwrite an existing file. - home.activation.checkLinkTargets = hm.dag.entryBefore ["writeBoundary"] ( + home.activation.checkLinkTargets = lib.hm.dag.entryBefore ["writeBoundary"] ( let # Paths that should be forcibly overwritten by Home Manager. # Caveat emptor! forcedPaths = - concatMapStringsSep " " (p: ''"$HOME"/${escapeShellArg p}'') - (mapAttrsToList (n: v: v.target) - (filterAttrs (n: v: v.force) cfg)); + lib.concatMapStringsSep " " (p: ''"$HOME"/${lib.escapeShellArg p}'') + (lib.mapAttrsToList (n: v: v.target) + (lib.filterAttrs (n: v: v.force) cfg)); - storeDir = escapeShellArg builtins.storeDir; + storeDir = lib.escapeShellArg builtins.storeDir; check = pkgs.substituteAll { src = ./files/check-link-targets.sh; @@ -105,10 +103,7 @@ in # 1. Remove files from the old generation that are not in the new # generation. # - # 2. Switch over the Home Manager gcroot and current profile - # links. - # - # 3. Symlink files from the new generation into $HOME. + # 2. Symlink files from the new generation into $HOME. # # This order is needed to ensure that we always know which links # belong to which generation. Specifically, if we're moving from @@ -121,7 +116,7 @@ in # and a failure during the intermediate state FA ∩ FB will not # result in lost links because this set of links are in both the # source and target generation. - home.activation.linkGeneration = hm.dag.entryAfter ["writeBoundary"] ( + home.activation.linkGeneration = lib.hm.dag.entryAfter ["writeBoundary"] ( let link = pkgs.writeShellScript "link" '' ${config.lib.bash.initHomeManagerLib} @@ -154,7 +149,7 @@ in # A symbolic link whose target path matches this pattern will be # considered part of a Home Manager generation. - homeFilePattern="$(readlink -e ${escapeShellArg builtins.storeDir})/*-home-manager-files/*" + homeFilePattern="$(readlink -e ${lib.escapeShellArg builtins.storeDir})/*-home-manager-files/*" newGenFiles="$1" shift 1 @@ -215,35 +210,13 @@ in } cleanOldGen - - if [[ ! -v oldGenPath || "$oldGenPath" != "$newGenPath" ]] ; then - _i "Creating profile generation %s" $newGenNum - if [[ -e "$genProfilePath"/manifest.json ]] ; then - # Remove all packages from "$genProfilePath" - # `nix profile remove '.*' --profile "$genProfilePath"` was not working, so here is a workaround: - nix profile list --profile "$genProfilePath" \ - | cut -d ' ' -f 4 \ - | xargs -rt $DRY_RUN_CMD nix profile remove $VERBOSE_ARG --profile "$genProfilePath" - run nix profile install $VERBOSE_ARG --profile "$genProfilePath" "$newGenPath" - else - run nix-env $VERBOSE_ARG --profile "$genProfilePath" --set "$newGenPath" - fi - - run --quiet nix-store --realise "$newGenPath" --add-root "$newGenGcPath" --indirect - if [[ -e "$legacyGenGcPath" ]]; then - run rm $VERBOSE_ARG "$legacyGenGcPath" - fi - else - _i "No change so reusing latest profile generation %s" "$oldGenNum" - fi - linkNewGen '' ); - home.activation.checkFilesChanged = hm.dag.entryBefore ["linkGeneration"] ( + home.activation.checkFilesChanged = lib.hm.dag.entryBefore ["linkGeneration"] ( let - homeDirArg = escapeShellArg homeDirectory; + homeDirArg = lib.escapeShellArg homeDirectory; in '' function _cmp() { if [[ -d $1 && -d $2 ]]; then @@ -253,31 +226,31 @@ in fi } declare -A changedFiles - '' + concatMapStrings (v: + '' + lib.concatMapStrings (v: let - sourceArg = escapeShellArg (sourceStorePath v); - targetArg = escapeShellArg v.target; + sourceArg = lib.escapeShellArg (sourceStorePath v); + targetArg = lib.escapeShellArg v.target; in '' _cmp ${sourceArg} ${homeDirArg}/${targetArg} \ && changedFiles[${targetArg}]=0 \ || changedFiles[${targetArg}]=1 - '') (filter (v: v.onChange != "") (attrValues cfg)) + '') (lib.filter (v: v.onChange != "") (lib.attrValues cfg)) + '' unset -f _cmp '' ); - home.activation.onFilesChange = hm.dag.entryAfter ["linkGeneration"] ( - concatMapStrings (v: '' - if (( ''${changedFiles[${escapeShellArg v.target}]} == 1 )); then + home.activation.onFilesChange = lib.hm.dag.entryAfter ["linkGeneration"] ( + lib.concatMapStrings (v: '' + if (( ''${changedFiles[${lib.escapeShellArg v.target}]} == 1 )); then if [[ -v DRY_RUN || -v VERBOSE ]]; then - echo "Running onChange hook for" ${escapeShellArg v.target} + echo "Running onChange hook for" ${lib.escapeShellArg v.target} fi if [[ ! -v DRY_RUN ]]; then ${v.onChange} fi fi - '') (filter (v: v.onChange != "") (attrValues cfg)) + '') (lib.filter (v: v.onChange != "") (lib.attrValues cfg)) ); # Symlink directories and files that have the right execute bit. @@ -349,10 +322,10 @@ in fi fi } - '' + concatStrings ( - mapAttrsToList (n: v: '' + '' + lib.concatStrings ( + lib.mapAttrsToList (n: v: '' insertFile ${ - escapeShellArgs [ + lib.escapeShellArgs [ (sourceStorePath v) v.target (if v.executable == null diff --git a/modules/home-environment.nix b/modules/home-environment.nix index 59497ec4a..9d792ca31 100644 --- a/modules/home-environment.nix +++ b/modules/home-environment.nix @@ -1,8 +1,7 @@ { config, lib, pkgs, ... }: -with lib; - let + inherit (lib) literalExpression mkOption types; inherit (config.home) stateVersion; @@ -114,7 +113,7 @@ let layout = mkOption { type = with types; nullOr str; default = - if versionAtLeast config.home.stateVersion "19.09" + if lib.versionAtLeast config.home.stateVersion "19.09" then null else "us"; defaultText = literalExpression "null"; @@ -148,7 +147,7 @@ let variant = mkOption { type = with types; nullOr str; default = - if versionAtLeast config.home.stateVersion "19.09" + if lib.versionAtLeast config.home.stateVersion "19.09" then null else ""; defaultText = literalExpression "null"; @@ -167,10 +166,10 @@ let in { - meta.maintainers = [ maintainers.rycee ]; + meta.maintainers = [ lib.maintainers.rycee ]; imports = [ - (mkRemovedOptionModule [ "home" "sessionVariableSetter" ] '' + (lib.mkRemovedOptionModule [ "home" "sessionVariableSetter" ] '' Session variables are now always set through the shell. This is done automatically if the shell configuration is managed by Home Manager. If not, then you must source the @@ -223,7 +222,7 @@ in home.keyboard = mkOption { type = types.nullOr keyboardSubModule; - default = if versionAtLeast stateVersion "21.11" then null else { }; + default = if lib.versionAtLeast stateVersion "21.11" then null else { }; defaultText = literalExpression '' "{ }" for state version < 21.11, "null" for state version ≥ 21.11 @@ -280,8 +279,9 @@ in }; ``` may not work as expected. If you need to reference another - session variable, then do so inside Nix instead. The above - example then becomes + session variable (even if it is declared by using other options + like [](#opt-xdg.configHome)), then do so inside Nix instead. + The above example then becomes ```nix home.sessionVariables = { FOO = "Hello"; @@ -309,7 +309,7 @@ in ".git/safe/../../bin" ]; description = '' - Extra directories to add to {env}`PATH`. + Extra directories to prepend to {env}`PATH`. These directories are added to the {env}`PATH` variable in a double-quoted context, so expressions like `$HOME` are @@ -319,6 +319,27 @@ in ''; }; + home.sessionSearchVariables = mkOption { + default = { }; + type = with types; attrsOf (listOf str); + example = { + MANPATH = [ + "$HOME/.npm-packages/man" + "\${xdg.configHome}/.local/share/man" + ]; + }; + description = '' + Extra directories to prepend to arbitrary PATH-like + environment variables (e.g.: {env}`MANPATH`). The values + will be concatenated by `:`. + These directories are added to the environment variable in a + double-quoted context, so expressions like `$HOME` are + expanded by the shell. However, since expressions like `~` or + `*` are escaped, they will end up in the environment + verbatim. + ''; + }; + home.sessionVariablesExtra = mkOption { type = types.lines; default = ""; @@ -354,7 +375,7 @@ in home.emptyActivationPath = mkOption { internal = true; type = types.bool; - default = versionAtLeast stateVersion "22.11"; + default = lib.versionAtLeast stateVersion "22.11"; defaultText = literalExpression '' false for state version < 22.11, true for state version ≥ 22.11 @@ -369,7 +390,7 @@ in }; home.activation = mkOption { - type = hm.types.dagOf types.str; + type = lib.hm.types.dagOf types.str; default = {}; example = literalExpression '' { @@ -474,7 +495,7 @@ in ''; }; - home.preferXdgDirectories = mkEnableOption "" // { + home.preferXdgDirectories = lib.mkEnableOption "" // { description = '' Whether to make programs use XDG directories whenever supported. ''; @@ -501,7 +522,7 @@ in config.home.enableNixpkgsReleaseCheck && hmRelease != nixpkgsRelease; in - optional releaseMismatch '' + lib.optional releaseMismatch '' You are using Home Manager version ${hmRelease} and @@ -519,11 +540,11 @@ in ''; home.username = - mkIf (versionOlder config.home.stateVersion "20.09") - (mkDefault (builtins.getEnv "USER")); + lib.mkIf (lib.versionOlder config.home.stateVersion "20.09") + (lib.mkDefault (builtins.getEnv "USER")); home.homeDirectory = - mkIf (versionOlder config.home.stateVersion "20.09") - (mkDefault (builtins.getEnv "HOME")); + lib.mkIf (lib.versionOlder config.home.stateVersion "20.09") + (lib.mkDefault (builtins.getEnv "HOME")); home.profileDirectory = if config.submoduleSupport.enable @@ -539,7 +560,7 @@ in home.sessionVariables = let - maybeSet = n: v: optionalAttrs (v != null) { ${n} = v; }; + maybeSet = n: v: lib.optionalAttrs (v != null) { ${n} = v; }; in (maybeSet "LANG" cfg.language.base) // @@ -575,16 +596,31 @@ in export __HM_SESS_VARS_SOURCED=1 ${config.lib.shell.exportAll cfg.sessionVariables} - '' + lib.optionalString (cfg.sessionPath != [ ]) '' - export PATH="$PATH''${PATH:+:}${concatStringsSep ":" cfg.sessionPath}" - '' + cfg.sessionVariablesExtra; + '' + lib.concatStringsSep "\n" + (lib.mapAttrsToList + (env: values: config.lib.shell.export + env + (config.lib.shell.prependToVar ":" env values)) + cfg.sessionSearchVariables) + "\n" + + cfg.sessionVariablesExtra; }; + home.sessionSearchVariables.PATH = + lib.mkIf (cfg.sessionPath != [ ]) cfg.sessionPath; + home.packages = [ config.home.sessionVariablesPackage ]; - # A dummy entry acting as a boundary between the activation - # script's "check" and the "write" phases. - home.activation.writeBoundary = hm.dag.entryAnywhere ""; + # The entry acting as a boundary between the activation script's "check" and + # the "write" phases. This is where we commit to attempting to actually + # activate the configuration. + home.activation.writeBoundary = lib.hm.dag.entryAnywhere '' + if [[ ! -v oldGenPath || "$oldGenPath" != "$newGenPath" ]] ; then + _i "Creating new profile generation" + run nix-env $VERBOSE_ARG --profile "$genProfilePath" --set "$newGenPath" + else + _i "No change so reusing latest profile generation" + fi + ''; # Install packages to the user environment. # @@ -601,7 +637,7 @@ in # In case the user has moved from a user-install of Home Manager # to a submodule managed one we attempt to uninstall the # `home-manager-path` package if it is installed. - home.activation.installPackages = hm.dag.entryAfter ["writeBoundary"] ( + home.activation.installPackages = lib.hm.dag.entryAfter ["writeBoundary"] ( if config.submoduleSupport.externalPackageInstall then '' @@ -667,10 +703,10 @@ in _iNote "Activating %s" "${res.name}" ${res.data} ''; - sortedCommands = hm.dag.topoSort cfg.activation; + sortedCommands = lib.hm.dag.topoSort cfg.activation; activationCmds = if sortedCommands ? result then - concatStringsSep "\n" (map mkCmd sortedCommands.result) + lib.concatStringsSep "\n" (map mkCmd sortedCommands.result) else abort ("Dependency cycle in activation script: " + builtins.toJSON sortedCommands); @@ -699,7 +735,7 @@ in else ":$(${pkgs.coreutils}/bin/dirname $(${pkgs.coreutils}/bin/readlink -m $(type -p nix-env)))" ) - + optionalString (!cfg.emptyActivationPath) "\${PATH:+:}$PATH"; + + lib.optionalString (!cfg.emptyActivationPath) "\${PATH:+:}$PATH"; activationScript = pkgs.writeShellScript "activation-script" '' set -eu @@ -713,11 +749,24 @@ in ${builtins.readFile ./lib-bash/activation-init.sh} if [[ ! -v SKIP_SANITY_CHECKS ]]; then - checkUsername ${escapeShellArg config.home.username} - checkHomeDirectory ${escapeShellArg config.home.homeDirectory} + checkUsername ${lib.escapeShellArg config.home.username} + checkHomeDirectory ${lib.escapeShellArg config.home.homeDirectory} fi + # Create a temporary GC root to prevent collection during activation. + trap 'run rm -f $VERBOSE_ARG "$newGenGcPath"' EXIT + run --silence nix-store --realise "$newGenPath" --add-root "$newGenGcPath" + ${activationCmds} + + ${lib.optionalString (!config.uninstall) '' + # Create the "current generation" GC root. + run --silence nix-store --realise "$newGenPath" --add-root "$currentGenGcPath" + + if [[ -e "$legacyGenGcPath" ]]; then + run rm $VERBOSE_ARG "$legacyGenGcPath" + fi + ''} ''; in pkgs.runCommand diff --git a/modules/i18n/input-method/default.nix b/modules/i18n/input-method/default.nix index 5e3a89b33..d6a1beb8e 100644 --- a/modules/i18n/input-method/default.nix +++ b/modules/i18n/input-method/default.nix @@ -1,6 +1,5 @@ { config, pkgs, lib, ... }: -with lib; let cfg = config.i18n.inputMethod; @@ -26,9 +25,9 @@ in { options.i18n = { inputMethod = { - enabled = mkOption { - type = types.nullOr - (types.enum [ "fcitx" "fcitx5" "nabi" "uim" "hime" "kime" ]); + enabled = lib.mkOption { + type = lib.types.nullOr + (lib.types.enum [ "fcitx" "fcitx5" "nabi" "uim" "hime" "kime" ]); default = null; example = "fcitx5"; description = '' @@ -61,9 +60,9 @@ in { ''; }; - package = mkOption { + package = lib.mkOption { internal = true; - type = types.nullOr types.path; + type = lib.types.nullOr lib.types.path; default = null; description = '' The input method method package. @@ -72,9 +71,10 @@ in { }; }; - config = mkIf (cfg.enabled != null) { + config = lib.mkIf (cfg.enabled != null) { assertions = [ - (hm.assertions.assertPlatform "i18n.inputMethod" pkgs platforms.linux) + (lib.hm.assertions.assertPlatform "i18n.inputMethod" pkgs + lib.platforms.linux) { assertion = cfg.enabled != "fcitx"; message = "fcitx has been removed, please use fcitx5 instead"; @@ -84,5 +84,5 @@ in { home.packages = [ cfg.package gtk2Cache gtk3Cache ]; }; - meta.maintainers = with lib; [ hm.maintainers.kranzes ]; + meta.maintainers = [ lib.hm.maintainers.kranzes ]; } diff --git a/modules/i18n/input-method/fcitx5.nix b/modules/i18n/input-method/fcitx5.nix index 3c2d1c191..be239b30f 100644 --- a/modules/i18n/input-method/fcitx5.nix +++ b/modules/i18n/input-method/fcitx5.nix @@ -1,42 +1,61 @@ { config, pkgs, lib, ... }: -with lib; - let im = config.i18n.inputMethod; cfg = im.fcitx5; - fcitx5Package = - pkgs.libsForQt5.fcitx5-with-addons.override { inherit (cfg) addons; }; + fcitx5Package = cfg.fcitx5-with-addons.override { inherit (cfg) addons; }; in { options = { i18n.inputMethod.fcitx5 = { - addons = mkOption { - type = with types; listOf package; + fcitx5-with-addons = lib.mkOption { + type = lib.types.package; + default = pkgs.libsForQt5.fcitx5-with-addons; + example = lib.literalExpression "pkgs.kdePackages.fcitx5-with-addons"; + description = '' + The fcitx5 package to use. + ''; + }; + addons = lib.mkOption { + type = with lib.types; listOf package; default = [ ]; - example = literalExpression "with pkgs; [ fcitx5-rime ]"; + example = lib.literalExpression "with pkgs; [ fcitx5-rime ]"; description = '' Enabled Fcitx5 addons. ''; }; + + waylandFrontend = lib.mkOption { + type = lib.types.bool; + default = false; + description = '' + Use the Wayland input method frontend. + See [Using Fcitx 5 on Wayland](https://fcitx-im.org/wiki/Using_Fcitx_5_on_Wayland). + ''; + }; }; }; - config = mkIf (im.enabled == "fcitx5") { + config = lib.mkIf (im.enabled == "fcitx5") { i18n.inputMethod.package = fcitx5Package; - home.sessionVariables = { - GLFW_IM_MODULE = "ibus"; # IME support in kitty - GTK_IM_MODULE = "fcitx"; - QT_IM_MODULE = "fcitx"; - XMODIFIERS = "@im=fcitx"; - QT_PLUGIN_PATH = - "$QT_PLUGIN_PATH\${QT_PLUGIN_PATH:+:}${fcitx5Package}/${pkgs.qt6.qtbase.qtPluginPrefix}"; + home = { + sessionVariables = { + GLFW_IM_MODULE = "ibus"; # IME support in kitty + XMODIFIERS = "@im=fcitx"; + } // lib.optionalAttrs (!cfg.waylandFrontend) { + GTK_IM_MODULE = "fcitx"; + QT_IM_MODULE = "fcitx"; + }; + + sessionSearchVariables.QT_PLUGIN_PATH = + [ "${fcitx5Package}/${pkgs.qt6.qtbase.qtPluginPrefix}" ]; }; systemd.user.services.fcitx5-daemon = { Unit = { Description = "Fcitx5 input method editor"; PartOf = [ "graphical-session.target" ]; + After = [ "graphical-session.target" ]; }; Service.ExecStart = "${fcitx5Package}/bin/fcitx5"; Install.WantedBy = [ "graphical-session.target" ]; diff --git a/modules/i18n/input-method/hime.nix b/modules/i18n/input-method/hime.nix index 7b5700a9d..2d6f4d500 100644 --- a/modules/i18n/input-method/hime.nix +++ b/modules/i18n/input-method/hime.nix @@ -1,7 +1,7 @@ { config, pkgs, lib, ... }: -with lib; { - config = mkIf (config.i18n.inputMethod.enabled == "hime") { +{ + config = lib.mkIf (config.i18n.inputMethod.enabled == "hime") { i18n.inputMethod.package = pkgs.hime; home.sessionVariables = { diff --git a/modules/i18n/input-method/nabi.nix b/modules/i18n/input-method/nabi.nix index 01f9f7911..a060f4800 100644 --- a/modules/i18n/input-method/nabi.nix +++ b/modules/i18n/input-method/nabi.nix @@ -1,7 +1,7 @@ { config, pkgs, lib, ... }: -with lib; { - config = mkIf (config.i18n.inputMethod.enabled == "nabi") { +{ + config = lib.mkIf (config.i18n.inputMethod.enabled == "nabi") { i18n.inputMethod.package = pkgs.nabi; home.sessionVariables = { diff --git a/modules/i18n/input-method/uim.nix b/modules/i18n/input-method/uim.nix index e7890352c..8dcfe3238 100644 --- a/modules/i18n/input-method/uim.nix +++ b/modules/i18n/input-method/uim.nix @@ -1,14 +1,13 @@ { config, pkgs, lib, ... }: -with lib; - let cfg = config.i18n.inputMethod.uim; in { options = { i18n.inputMethod.uim = { - toolbar = mkOption { - type = types.enum [ "gtk" "gtk3" "gtk-systray" "gtk3-systray" "qt4" ]; + toolbar = lib.mkOption { + type = + lib.types.enum [ "gtk" "gtk3" "gtk-systray" "gtk3-systray" "qt4" ]; default = "gtk"; example = "gtk-systray"; description = '' @@ -19,7 +18,7 @@ in { }; - config = mkIf (config.i18n.inputMethod.enabled == "uim") { + config = lib.mkIf (config.i18n.inputMethod.enabled == "uim") { i18n.inputMethod.package = pkgs.uim; home.sessionVariables = { diff --git a/modules/launchd/launchd.nix b/modules/launchd/launchd.nix index 9c9b54452..98024c584 100644 --- a/modules/launchd/launchd.nix +++ b/modules/launchd/launchd.nix @@ -25,9 +25,11 @@ { config, lib, ... }: -with lib; +let + inherit (lib) types mkOption; # added by Home Manager -{ + launchdTypes = import ./types.nix { inherit config lib; }; +in { freeformType = with types; attrsOf anything; # added by Home Manager options = { @@ -118,7 +120,7 @@ with lib; }; LimitLoadToSessionType = mkOption { - type = types.nullOr types.str; + type = types.nullOr (types.oneOf [ types.str (types.listOf types.str) ]); default = null; description = '' This configuration file only applies to sessions of the type specified. This key is used in concert @@ -369,60 +371,26 @@ with lib; StartCalendarInterval = mkOption { default = null; - example = { + example = [{ Hour = 2; Minute = 30; - }; + }]; description = '' - This optional key causes the job to be started every calendar interval as specified. Missing arguments - are considered to be wildcard. The semantics are much like `crontab(5)`. Unlike cron which skips job - invocations when the computer is asleep, launchd will start the job the next time the computer wakes + This optional key causes the job to be started every calendar interval as specified. The semantics are + much like {manpage}`crontab(5)`: Missing attributes are considered to be wildcard. Unlike cron which skips + job invocations when the computer is asleep, launchd will start the job the next time the computer wakes up. If multiple intervals transpire before the computer is woken, those events will be coalesced into - one event upon wake from sleep. + one event upon waking from sleep. + + ::: {.important} + The list must not be empty and must not contain duplicate entries (attrsets which compare equally). + ::: + + ::: {.caution} + Since missing attrs become wildcards, an empty attrset effectively means "every minute". + ::: ''; - type = types.nullOr (types.listOf (types.submodule { - options = { - Minute = mkOption { - type = types.nullOr types.int; - default = null; - description = '' - The minute on which this job will be run. - ''; - }; - - Hour = mkOption { - type = types.nullOr types.int; - default = null; - description = '' - The hour on which this job will be run. - ''; - }; - - Day = mkOption { - type = types.nullOr types.int; - default = null; - description = '' - The day on which this job will be run. - ''; - }; - - Weekday = mkOption { - type = types.nullOr types.int; - default = null; - description = '' - The weekday on which this job will be run (0 and 7 are Sunday). - ''; - }; - - Month = mkOption { - type = types.nullOr types.int; - default = null; - description = '' - The month on which this job will be run. - ''; - }; - }; - })); + type = types.nullOr launchdTypes.StartCalendarInterval; }; StandardInPath = mkOption { @@ -669,22 +637,22 @@ with lib; resource limits based on what kind of job it is. If left unspecified, the system will apply light resource limits to the job, throttling its CPU usage and I/O bandwidth. The following are valid values: - Background - : Background jobs are generally processes that do work that was not directly requested by the user. - The resource limits applied to Background jobs are intended to prevent them from disrupting the - user experience. + Background + : Background jobs are generally processes that do work that was not directly requested by the user. + The resource limits applied to Background jobs are intended to prevent them from disrupting the + user experience. - Standard - : Standard jobs are equivalent to no ProcessType being set. + Standard + : Standard jobs are equivalent to no ProcessType being set. - Adaptive - : Adaptive jobs move between the Background and Interactive classifications based on activity over - XPC connections. See {manpage}`xpc_transaction_begin(3)` for details. + Adaptive + : Adaptive jobs move between the Background and Interactive classifications based on activity over + XPC connections. See `xpc_transaction_begin(3)` for details. - Interactive - : Interactive jobs run with the same resource limitations as apps, that is to say, none. Interactive - jobs are critical to maintaining a responsive user experience, and this key should only be - used if an app's ability to be responsive depends on it, and cannot be made Adaptive. + Interactive + : Interactive jobs run with the same resource limitations as apps, that is to say, none. Interactive + jobs are critical to maintaining a responsive user experience, and this key should only be + used if an app's ability to be responsive depends on it, and cannot be made Adaptive. ''; }; @@ -706,6 +674,15 @@ with lib; ''; }; + LowPriorityBackgroundIO = mkOption { + type = types.nullOr types.bool; + default = null; + description = '' + This optional key specifies whether the kernel should consider this daemon to be low priority when + doing file system I/O when the process is throttled with the Darwin-background classification. + ''; + }; + LaunchOnlyOnce = mkOption { type = types.nullOr types.bool; default = null; @@ -717,7 +694,7 @@ with lib; MachServices = mkOption { default = null; - example = { ResetAtClose = true; }; + example = { "org.nixos.service" = { ResetAtClose = true; }; }; description = '' This optional key is used to specify Mach services to be registered with the Mach bootstrap sub-system. Each key in this dictionary should be the name of service to be advertised. The value of the key must @@ -726,31 +703,32 @@ with lib; Finally, for the job itself, the values will be replaced with Mach ports at the time of check-in with launchd. ''; - type = types.nullOr (types.submodule { - options = { - ResetAtClose = mkOption { - type = types.nullOr types.bool; - default = null; - description = '' - If this boolean is false, the port is recycled, thus leaving clients to remain oblivious to the - demand nature of job. If the value is set to true, clients receive port death notifications when - the job lets go of the receive right. The port will be recreated atomically with respect to bootstrap_look_up() - calls, so that clients can trust that after receiving a port death notification, - the new port will have already been recreated. Setting the value to true should be done with - care. Not all clients may be able to handle this behavior. The default value is false. - ''; - }; + type = types.nullOr (types.attrsOf (types.either types.bool + (types.submodule { + options = { + ResetAtClose = mkOption { + type = types.nullOr types.bool; + default = null; + description = '' + If this boolean is false, the port is recycled, thus leaving clients to remain oblivious to the + demand nature of job. If the value is set to true, clients receive port death notifications when + the job lets go of the receive right. The port will be recreated atomically with respect to bootstrap_look_up() + calls, so that clients can trust that after receiving a port death notification, + the new port will have already been recreated. Setting the value to true should be done with + care. Not all clients may be able to handle this behavior. The default value is false. + ''; + }; - HideUntilCheckIn = mkOption { - type = types.nullOr types.bool; - default = null; - description = '' - Reserve the name in the namespace, but cause bootstrap_look_up() to fail until the job has - checked in with launchd. - ''; + HideUntilCheckIn = mkOption { + type = types.nullOr types.bool; + default = null; + description = '' + Reserve the name in the namespace, but cause bootstrap_look_up() to fail until the job has + checked in with launchd. + ''; + }; }; - }; - }); + }))); }; LaunchEvents = mkOption { @@ -778,6 +756,26 @@ with lib; }; }; + ServiceIPC = mkOption { + type = types.nullOr types.bool; + default = null; + description = '' + This optional key specifies whether the job participates in advanced + communication with launchd. The default is false. This flag is + incompatible with the inetdCompatibility key. + ''; + }; + + SessionCreate = mkOption { + type = types.nullOr types.bool; + default = null; + description = '' + This key specifies that the job should be spawned into a new security + audit session rather than the default session for the context is belongs + to. See auditon(2) for details. + ''; + }; + Sockets = mkOption { default = null; description = '' diff --git a/modules/launchd/types.nix b/modules/launchd/types.nix new file mode 100644 index 000000000..fadf46cb5 --- /dev/null +++ b/modules/launchd/types.nix @@ -0,0 +1,121 @@ +# launchd option type from nix-darwin +# +# Original code from https://github.com/LnL7/nix-darwin/commit/861af0fc94df9454f4e92d6892f75588763164bb + +{ lib, ... }: + +let + inherit (lib) imap1 types mkOption showOption mergeDefinitions; + inherit (builtins) map filter length deepSeq throw toString concatLists; + inherit (lib.options) showDefs; + wildcardText = lib.literalMD "`*`"; + + /* * + A type of list which does not allow duplicate elements. The base/inner + list type to use (e.g. `types.listOf` or `types.nonEmptyListOf`) is passed + via argument `listType`, which must be the final type and not a function. + + NOTE: The extra check for duplicates is quadratic and strict, so use this + type sparingly and only: + + * when needed, and + * when the list is expected to be recursively short (e.g. < 10 elements) + and shallow (i.e. strict evaluation of the list won't take too long) + + The implementation of this function is similar to that of + `types.nonEmptyListOf`. + */ + types'.uniqueList = listType: + listType // { + description = "unique ${ + types.optionDescriptionPhrase (class: class == "noun") listType + }"; + substSubModules = m: types'.uniqueList (listType.substSubModules m); + # This has been taken from the implementation of `types.listOf`, but has + # been modified to throw on duplicates. This check cannot be done in the + # `check` fn as this check is deep/strict, and because `check` runs + # prior to merging. + merge = loc: defs: + let + # Each element of `dupes` is a list. When there are duplicates, + # later lists will be duplicates of earlier lists, so just throw on + # the first set of duplicates found so that we don't have duplicate + # error msgs. + checked = filter (li: + if length li > 1 then + throw '' + The option `${ + showOption loc + }' contains duplicate entries after merging: + ${showDefs li}'' + else + false) dupes; + dupes = + map (def: filter (def': def'.value == def.value) merged) merged; + merged = filter (x: x ? value) (concatLists (imap1 (n: def: + imap1 (m: el: + let + inherit (def) file; + loc' = loc + ++ [ "[definition ${toString n}-entry ${toString m}]" ]; + in (mergeDefinitions loc' listType.nestedTypes.elemType [{ + inherit file; + value = el; + }]).optionalValue // { + inherit loc' file; + }) def.value) defs)); + in deepSeq checked (map (x: x.value) merged); + }; +in { + StartCalendarInterval = let + CalendarIntervalEntry = types.submodule { + options = { + Minute = mkOption { + type = types.nullOr (types.ints.between 0 59); + default = null; + defaultText = wildcardText; + description = '' + The minute on which this job will be run. + ''; + }; + + Hour = mkOption { + type = types.nullOr (types.ints.between 0 23); + default = null; + defaultText = wildcardText; + description = '' + The hour on which this job will be run. + ''; + }; + + Day = mkOption { + type = types.nullOr (types.ints.between 1 31); + default = null; + defaultText = wildcardText; + description = '' + The day on which this job will be run. + ''; + }; + + Weekday = mkOption { + type = types.nullOr (types.ints.between 0 7); + default = null; + defaultText = wildcardText; + description = '' + The weekday on which this job will be run (0 and 7 are Sunday). + ''; + }; + + Month = mkOption { + type = types.nullOr (types.ints.between 1 12); + default = null; + defaultText = wildcardText; + description = '' + The month on which this job will be run. + ''; + }; + }; + }; + in types.either CalendarIntervalEntry + (types'.uniqueList (types.nonEmptyListOf CalendarIntervalEntry)); +} diff --git a/modules/lib-bash/activation-init.sh b/modules/lib-bash/activation-init.sh index 91111e5d0..b16d8741b 100755 --- a/modules/lib-bash/activation-init.sh +++ b/modules/lib-bash/activation-init.sh @@ -59,34 +59,13 @@ function setupVars() { declare -gr hmDataPath="${XDG_DATA_HOME:-$HOME/.local/share}/home-manager" declare -gr genProfilePath="$profilesDir/home-manager" declare -gr newGenPath="@GENERATION_DIR@"; - declare -gr newGenGcPath="$hmGcrootsDir/current-home" + declare -gr newGenGcPath="$hmGcrootsDir/new-home" + declare -gr currentGenGcPath="$hmGcrootsDir/current-home" declare -gr legacyGenGcPath="$globalGcrootsDir/current-home" - declare greatestGenNum - greatestGenNum=$( \ - nix-env --list-generations --profile "$genProfilePath" \ - | tail -1 \ - | sed -E 's/ *([[:digit:]]+) .*/\1/') - - if [[ -n $greatestGenNum ]] ; then - declare -gr oldGenNum=$greatestGenNum - declare -gr newGenNum=$((oldGenNum + 1)) - else - declare -gr newGenNum=1 - fi - - if [[ -e $genProfilePath ]] ; then + if [[ -e $currentGenGcPath ]] ; then declare -g oldGenPath - oldGenPath="$(readlink -e "$genProfilePath")" - fi - - _iVerbose "Sanity checking oldGenNum and oldGenPath" - if [[ -v oldGenNum && ! -v oldGenPath - || ! -v oldGenNum && -v oldGenPath ]]; then - _i $'The previous generation number and path are in conflict! These\nmust be either both empty or both set but are now set to\n\n \'%s\' and \'%s\'\n\nIf you don\'t mind losing previous profile generations then\nthe easiest solution is probably to run\n\n rm %s/home-manager*\n rm %s/current-home\n\nand trying home-manager switch again. Good luck!' \ - "${oldGenNum:-}" "${oldGenPath:-}" \ - "$profilesDir" "$hmGcrootsDir" - exit 1 + oldGenPath="$(readlink -e "$currentGenGcPath")" fi } @@ -181,15 +160,13 @@ if [[ -v VERBOSE ]]; then fi _iVerbose "Activation variables:" -if [[ -v oldGenNum ]] ; then - verboseEcho " oldGenNum=$oldGenNum" +if [[ -v oldGenPath ]] ; then verboseEcho " oldGenPath=$oldGenPath" else - verboseEcho " oldGenNum undefined (first run?)" verboseEcho " oldGenPath undefined (first run?)" fi verboseEcho " newGenPath=$newGenPath" -verboseEcho " newGenNum=$newGenNum" verboseEcho " genProfilePath=$genProfilePath" verboseEcho " newGenGcPath=$newGenGcPath" +verboseEcho " currentGenGcPath=$currentGenGcPath" verboseEcho " legacyGenGcPath=$legacyGenGcPath" diff --git a/modules/lib/default.nix b/modules/lib/default.nix index 5d732a83f..8014c625e 100644 --- a/modules/lib/default.nix +++ b/modules/lib/default.nix @@ -14,4 +14,5 @@ rec { shell = import ./shell.nix { inherit lib; }; zsh = import ./zsh.nix { inherit lib; }; + nushell = import ./nushell.nix { inherit lib; }; } diff --git a/modules/lib/file-type.nix b/modules/lib/file-type.nix index 3fb51fd56..48ff00f1b 100644 --- a/modules/lib/file-type.nix +++ b/modules/lib/file-type.nix @@ -99,7 +99,6 @@ in { force = mkOption { type = types.bool; default = false; - visible = false; description = '' Whether the target path should be unconditionally replaced by the managed file source. Warning, this will silently diff --git a/modules/lib/maintainers.nix b/modules/lib/maintainers.nix index 70f480d06..e70fcce1d 100644 --- a/modules/lib/maintainers.nix +++ b/modules/lib/maintainers.nix @@ -5,8 +5,13 @@ # are expected to be follow the same format as described in [1]. # # [1] https://github.com/NixOS/nixpkgs/blob/fca0d6e093c82b31103dc0dacc48da2a9b06e24b/maintainers/maintainer-list.nix#LC1 - { + aabccd021 = { + name = "Muhamad Abdurahman"; + email = "aabccd021@gmail.com"; + github = "aabccd021"; + githubId = 33031950; + }; abayomi185 = { name = "Yomi"; email = "yomi+nix@yomitosh.com"; @@ -37,6 +42,12 @@ github = "Avimitin"; githubId = 30021675; }; + bamhm182 = { + name = "bamhm182"; + email = "bamhm182@gmail.com"; + github = "bamhm182"; + githubId = 920269; + }; blmhemu = { name = "blmhemu"; email = "19410501+blmhemu@users.noreply.github.com"; @@ -67,11 +78,11 @@ github = "considerate"; githubId = 217918; }; - cvoges12 = { - name = "Clayton Voges"; - email = "38054771+cvoges12@users.noreply.github.com"; - github = "cvoges12"; - githubId = 38054771; + damidoug = { + email = "contact@damidoug.dev"; + github = "damidoug"; + githubId = 75175586; + name = "Douglas Damiano"; }; danjujan = { name = "Jan Schmitz"; @@ -101,6 +112,12 @@ github = "diniamo"; githubId = 55629891; }; + dsoverlord = { + name = "Kirill Zakharov"; + email = "dsoverlord@vk.com"; + github = "dsoverlord"; + githubId = 78819443; + }; dwagenk = { email = "dwagenk@mailbox.org"; github = "dwagenk"; @@ -282,6 +299,16 @@ github = "NitroSniper"; githubId = 44097331; }; + n-hass = { + name = "Nicholas Hassan"; + email = "nick@hassan.host"; + github = "n-hass"; + githubId = 72363381; + keys = [{ + longkeyid = "rsa4096/0xFC95AB946A781EE7"; + fingerprint = "FDEE 6116 DBA7 8840 7323 4466 A371 5973 2728 A6A6"; + }]; + }; seylerius = { email = "sable@seyleri.us"; name = "Sable Seyler"; @@ -343,6 +370,11 @@ githubId = 12465195; name = "Bruno BELANYI"; }; + libewa = { + email = "libewa-git@icloud.com"; + github = "libewa"; + githubId = 67926131; + }; malvo = { email = "malte@malvo.org"; github = "malte-v"; @@ -421,12 +453,6 @@ github = "nurelin"; githubId = 5276274; }; - omernaveedxyz = { - name = "Omer Naveed"; - email = "omer@omernaveed.dev"; - github = "omernaveedxyz"; - githubId = 112912585; - }; otavio = { email = "otavio.salvador@ossystems.com.br"; github = "otavio"; @@ -463,6 +489,12 @@ github = "mainrs"; githubId = 5113257; }; + mikilio = { + name = "mikilio"; + email = "official.mikilio+dev@gmail.com"; + github = "mikilio"; + githubId = 86004375; + }; kmaasrud = { name = "Knut Magnus Aasrud"; email = "km@aasrud.com"; @@ -535,6 +567,13 @@ githubId = 1545895; name = "Nicola Squartini"; }; + timon-schelling = { + name = "Timon Schelling"; + email = "me@timon.zip"; + github = "timon-schelling"; + githubId = 36821505; + matrix = "@timon:beeper.com"; + }; toastal = { email = "toastal+nix@posteo.net"; matrix = "@toastal:matrix.org"; @@ -563,6 +602,11 @@ github = "pedorich-n"; githubId = 15573098; }; + PopeRigby = { + name = "PopeRigby"; + github = "poperigby"; + githubId = 20866468; + }; liyangau = { name = "Li Yang"; email = "d@aufomm.com"; @@ -593,6 +637,12 @@ github = "zorrobert"; githubId = 118135271; }; + joygnu = { + name = "joygnu"; + email = "contact@joygnu.org"; + github = "joygnu"; + githubId = 152063003; + }; callumio = { name = "Callum Leslie"; email = "git+nix@cleslie.uk"; @@ -601,4 +651,44 @@ keys = [{ fingerprint = "BC82 4BB5 1656 D144 285E A0EC D382 C4AF EECE AA90"; }]; }; + ALameLlama = { + name = "Nicholas Ciechanowski"; + email = "NicholasACiechanowski@gmail.com"; + github = "ALameLlama"; + githubId = 55490546; + }; + ckgxrg = { + name = "ckgxrg"; + email = "ckgxrg@ckgxrg.io"; + github = "ckgxrg-salt"; + githubId = 165614491; + }; + HPsaucii = { + name = "Holly Powell"; + email = "me@hpsaucii.dev"; + github = "HPsaucii"; + githubId = 126502193; + keys = [{ + longkeyid = "rsa4096/0xEDB2C634166AE6AD"; + fingerprint = "AD32 73D4 5E0E 9478 E826 543F EDB2 C634 166A E6AD"; + }]; + }; + folliehiyuki = { + name = "Hoang Nguyen"; + email = "folliekazetani@protonmail.com"; + github = "folliehiyuki"; + githubId = 67634026; + }; + "3ulalia" = { + name = "Eulalia del Sol"; + email = "3ulalia@proton.me"; + github = "3ulalia"; + githubId = "179992797"; + }; + ipsavitsky = { + name = "Ilya Savitsky"; + email = "ipsavitsky234@gmail.com"; + github = "ipsavitsky"; + githubId = 33558632; + }; } diff --git a/modules/lib/nushell.nix b/modules/lib/nushell.nix new file mode 100644 index 000000000..5ef5ad36d --- /dev/null +++ b/modules/lib/nushell.nix @@ -0,0 +1,66 @@ +{ lib }: rec { + mkNushellInline = expr: lib.setType "nushell-inline" { inherit expr; }; + + isNushellInline = lib.isType "nushell-inline"; + + toNushell = { indent ? "", multiline ? true, asBindings ? false, }@args: + v: + let + innerIndent = "${indent} "; + introSpace = if multiline then '' + + ${innerIndent}'' else + " "; + outroSpace = if multiline then '' + + ${indent}'' else + " "; + innerArgs = args // { + indent = if asBindings then indent else innerIndent; + asBindings = false; + }; + concatItems = lib.concatStringsSep introSpace; + + generatedBindings = assert lib.assertMsg (badVarNames == [ ]) + "Bad Nushell variable names: ${ + lib.generators.toPretty { } badVarNames + }"; + lib.concatStrings (lib.mapAttrsToList (key: value: '' + ${indent}let ${key} = ${toNushell innerArgs value} + '') v); + + isBadVarName = name: + # Extracted from https://github.com/nushell/nushell/blob/ebc7b80c23f777f70c5053cca428226b3fe00d30/crates/nu-parser/src/parser.rs#L33 + # Variables with numeric or even empty names are allowed. The only requisite is not containing any of the following characters + let invalidVariableCharacters = ".[({+-*^/=!<>&|"; + in lib.match "^[$]?[^${lib.escapeRegex invalidVariableCharacters}]+$" + name == null; + badVarNames = lib.filter isBadVarName (builtins.attrNames v); + in if asBindings then + generatedBindings + else if v == null then + "null" + else if lib.isInt v || lib.isFloat v || lib.isString v || lib.isBool v then + lib.strings.toJSON v + else if lib.isList v then + (if v == [ ] then + "[]" + else + "[${introSpace}${ + concatItems (map (value: "${toNushell innerArgs value}") v) + }${outroSpace}]") + else if lib.isAttrs v then + (if isNushellInline v then + "(${v.expr})" + else if v == { } then + "{}" + else if lib.isDerivation v then + toString v + else + "{${introSpace}${ + concatItems (lib.mapAttrsToList (key: value: + "${lib.strings.toJSON key}: ${toNushell innerArgs value}") v) + }${outroSpace}}") + else + abort "nushell.toNushell: type ${lib.typeOf v} is unsupported"; +} diff --git a/modules/lib/shell.nix b/modules/lib/shell.nix index 5e5743f51..04f9135cf 100644 --- a/modules/lib/shell.nix +++ b/modules/lib/shell.nix @@ -1,6 +1,30 @@ { lib }: -rec { +let + + mkShellIntegrationOption = name: + { config, baseName ? name, extraDescription ? "" }: + let attrName = "enable${baseName}Integration"; + in lib.mkOption { + default = config.home.shell.${attrName}; + defaultText = lib.literalMD "[](#opt-home.shell.${attrName})"; + example = false; + description = "Whether to enable ${name} integration.${ + lib.optionalString (extraDescription != "") + ("\n\n" + extraDescription) + }"; + type = lib.types.bool; + }; + +in rec { + # Produces a Bourne shell like statement that prepend new values to + # an possibly existing variable, using sep(arator). + # Example: + # prependToVar ":" "PATH" [ "$HOME/bin" "$HOME/.local/bin" ] + # => "$HOME/bin:$HOME/.local/bin:${PATH:+:}\$PATH" + prependToVar = sep: n: v: + "${lib.concatStringsSep sep v}\${${n}:+${sep}}\$${n}"; + # Produces a Bourne shell like variable export statement. export = n: v: ''export ${n}="${toString v}"''; @@ -8,4 +32,10 @@ rec { # assignment, this function produces a string containing an export # statement for each set entry. exportAll = vars: lib.concatStringsSep "\n" (lib.mapAttrsToList export vars); + + mkBashIntegrationOption = mkShellIntegrationOption "Bash"; + mkFishIntegrationOption = mkShellIntegrationOption "Fish"; + mkIonIntegrationOption = mkShellIntegrationOption "Ion"; + mkNushellIntegrationOption = mkShellIntegrationOption "Nushell"; + mkZshIntegrationOption = mkShellIntegrationOption "Zsh"; } diff --git a/modules/lib/types.nix b/modules/lib/types.nix index 056d3165b..14d1c2192 100644 --- a/modules/lib/types.nix +++ b/modules/lib/types.nix @@ -107,4 +107,27 @@ in rec { mergeDefaultOption loc defs; }; + nushellValue = let + valueType = types.nullOr (types.oneOf [ + (lib.mkOptionType { + name = "nushell"; + description = "Nushell inline value"; + descriptionClass = "name"; + check = lib.isType "nushell-inline"; + }) + types.bool + types.int + types.float + types.str + types.path + (types.attrsOf valueType // { + description = "attribute set of Nushell values"; + descriptionClass = "name"; + }) + (types.listOf valueType // { + description = "list of Nushell values"; + descriptionClass = "name"; + }) + ]); + in valueType; } diff --git a/modules/manual.nix b/modules/manual.nix index 23963c3c0..02a5c2c77 100644 --- a/modules/manual.nix +++ b/modules/manual.nix @@ -1,7 +1,5 @@ { config, lib, pkgs, ... }: -with lib; - let cfg = config.manual; @@ -13,8 +11,8 @@ let in { options = { - manual.html.enable = mkOption { - type = types.bool; + manual.html.enable = lib.mkOption { + type = lib.types.bool; default = false; description = '' Whether to install the HTML manual. This also installs the @@ -23,8 +21,8 @@ in { ''; }; - manual.manpages.enable = mkOption { - type = types.bool; + manual.manpages.enable = lib.mkOption { + type = lib.types.bool; default = true; example = false; description = '' @@ -37,8 +35,8 @@ in { ''; }; - manual.json.enable = mkOption { - type = types.bool; + manual.json.enable = lib.mkOption { + type = lib.types.bool; default = false; example = true; description = '' @@ -52,10 +50,10 @@ in { }; config = { - home.packages = mkMerge [ - (mkIf cfg.html.enable [ docs.manual.html docs.manual.htmlOpenTool ]) - (mkIf cfg.manpages.enable [ docs.manPages ]) - (mkIf cfg.json.enable [ docs.options.json ]) + home.packages = lib.mkMerge [ + (lib.mkIf cfg.html.enable [ docs.manual.html docs.manual.htmlOpenTool ]) + (lib.mkIf cfg.manpages.enable [ docs.manPages ]) + (lib.mkIf cfg.json.enable [ docs.options.json ]) ]; }; diff --git a/modules/misc/dconf.nix b/modules/misc/dconf.nix index b4863a139..39eceb42e 100644 --- a/modules/misc/dconf.nix +++ b/modules/misc/dconf.nix @@ -1,29 +1,29 @@ { config, lib, pkgs, ... }: -with lib; - let + inherit (lib) types; cfg = config.dconf; - toDconfIni = generators.toINI { mkKeyValue = mkIniKeyValue; }; + toDconfIni = lib.generators.toINI { mkKeyValue = mkIniKeyValue; }; - mkIniKeyValue = key: value: "${key}=${toString (hm.gvariant.mkValue value)}"; + mkIniKeyValue = key: value: + "${key}=${toString (lib.hm.gvariant.mkValue value)}"; # The dconf keys managed by this configuration. We store this as part of the # generation state to be able to reset keys that become unmanaged during # switch. stateDconfKeys = pkgs.writeText "dconf-keys.json" (builtins.toJSON - (concatLists (mapAttrsToList - (dir: entries: mapAttrsToList (key: _: "/${dir}/${key}") entries) + (lib.concatLists (lib.mapAttrsToList + (dir: entries: lib.mapAttrsToList (key: _: "/${dir}/${key}") entries) cfg.settings))); in { - meta.maintainers = [ maintainers.rycee ]; + meta.maintainers = [ lib.maintainers.rycee ]; options = { dconf = { - enable = mkOption { + enable = lib.mkOption { type = types.bool; # While technically dconf on darwin could work, our activation step # requires dbus, which only *lightly* supports Darwin in general, and @@ -43,10 +43,10 @@ in { ''; }; - settings = mkOption { - type = with types; attrsOf (attrsOf hm.types.gvariant); + settings = lib.mkOption { + type = with types; attrsOf (attrsOf lib.hm.types.gvariant); default = { }; - example = literalExpression '' + example = lib.literalExpression '' { "org/gnome/calculator" = { button-mode = "programming"; @@ -75,7 +75,7 @@ in { }; }; - config = mkIf (cfg.enable && cfg.settings != { }) { + config = lib.mkIf (cfg.enable && cfg.settings != { }) { # Make sure the dconf directory exists. xdg.configFile."dconf/.keep".source = builtins.toFile "keep" ""; @@ -84,53 +84,54 @@ in { ln -s ${stateDconfKeys} $out/state/${stateDconfKeys.name} ''; - home.activation.dconfSettings = hm.dag.entryAfter [ "installPackages" ] (let - iniFile = pkgs.writeText "hm-dconf.ini" (toDconfIni cfg.settings); + home.activation.dconfSettings = lib.hm.dag.entryAfter [ "installPackages" ] + (let + iniFile = pkgs.writeText "hm-dconf.ini" (toDconfIni cfg.settings); - statePath = "state/${stateDconfKeys.name}"; + statePath = "state/${stateDconfKeys.name}"; - cleanup = pkgs.writeShellScript "dconf-cleanup" '' - set -euo pipefail + cleanup = pkgs.writeShellScript "dconf-cleanup" '' + set -euo pipefail - ${config.lib.bash.initHomeManagerLib} + ${config.lib.bash.initHomeManagerLib} - PATH=${makeBinPath [ pkgs.dconf pkgs.jq ]}''${PATH:+:}$PATH + PATH=${lib.makeBinPath [ pkgs.dconf pkgs.jq ]}''${PATH:+:}$PATH - oldState="$1" - newState="$2" + oldState="$1" + newState="$2" - # Can't do cleanup if we don't know the old state. - if [[ ! -f $oldState ]]; then - exit 0 + # Can't do cleanup if we don't know the old state. + if [[ ! -f $oldState ]]; then + exit 0 + fi + + # Reset all keys that are present in the old generation but not the new + # one. + jq -r -n \ + --slurpfile old "$oldState" \ + --slurpfile new "$newState" \ + '($old[] - $new[])[]' \ + | while read -r key; do + verboseEcho "Resetting dconf key \"$key\"" + run $DCONF_DBUS_RUN_SESSION dconf reset "$key" + done + ''; + in '' + if [[ -v DBUS_SESSION_BUS_ADDRESS ]]; then + export DCONF_DBUS_RUN_SESSION="" + else + export DCONF_DBUS_RUN_SESSION="${pkgs.dbus}/bin/dbus-run-session --dbus-daemon=${pkgs.dbus}/bin/dbus-daemon" fi - # Reset all keys that are present in the old generation but not the new - # one. - jq -r -n \ - --slurpfile old "$oldState" \ - --slurpfile new "$newState" \ - '($old[] - $new[])[]' \ - | while read -r key; do - verboseEcho "Resetting dconf key \"$key\"" - run $DCONF_DBUS_RUN_SESSION dconf reset "$key" - done - ''; - in '' - if [[ -v DBUS_SESSION_BUS_ADDRESS ]]; then - export DCONF_DBUS_RUN_SESSION="" - else - export DCONF_DBUS_RUN_SESSION="${pkgs.dbus}/bin/dbus-run-session --dbus-daemon=${pkgs.dbus}/bin/dbus-daemon" - fi + if [[ -v oldGenPath ]]; then + ${cleanup} \ + "$oldGenPath/${statePath}" \ + "$newGenPath/${statePath}" + fi - if [[ -v oldGenPath ]]; then - ${cleanup} \ - "$oldGenPath/${statePath}" \ - "$newGenPath/${statePath}" - fi + run $DCONF_DBUS_RUN_SESSION ${pkgs.dconf}/bin/dconf load / < ${iniFile} - run $DCONF_DBUS_RUN_SESSION ${pkgs.dconf}/bin/dconf load / < ${iniFile} - - unset DCONF_DBUS_RUN_SESSION - ''); + unset DCONF_DBUS_RUN_SESSION + ''); }; } diff --git a/modules/misc/debug.nix b/modules/misc/debug.nix index fc0d8946a..eb9d85655 100644 --- a/modules/misc/debug.nix +++ b/modules/misc/debug.nix @@ -1,10 +1,8 @@ -{ config, pkgs, lib, ... }: - -with lib; +{ config, lib, ... }: { options.home = { - enableDebugInfo = mkEnableOption "" // { + enableDebugInfo = lib.mkEnableOption "" // { description = '' Some Nix packages provide debug symbols for {command}`gdb` in the `debug` output. @@ -15,12 +13,11 @@ with lib; }; }; - config = mkIf config.home.enableDebugInfo { + config = lib.mkIf config.home.enableDebugInfo { home.extraOutputsToInstall = [ "debug" ]; - home.sessionVariables = { - NIX_DEBUG_INFO_DIRS = - "$NIX_DEBUG_INFO_DIRS\${NIX_DEBUG_INFO_DIRS:+:}${config.home.profileDirectory}/lib/debug"; + home.sessionSearchVariables = { + NIX_DEBUG_INFO_DIRS = [ "${config.home.profileDirectory}/lib/debug" ]; }; }; } diff --git a/modules/misc/editorconfig.nix b/modules/misc/editorconfig.nix index a6dfb570a..56505850a 100644 --- a/modules/misc/editorconfig.nix +++ b/modules/misc/editorconfig.nix @@ -1,7 +1,5 @@ { config, lib, pkgs, ... }: -with lib; - let cfg = config.editorconfig; @@ -9,12 +7,12 @@ let iniFormat = pkgs.formats.ini { }; in { - meta.maintainers = with maintainers; [ loicreynier ]; + meta.maintainers = with lib.maintainers; [ loicreynier ]; options.editorconfig = { - enable = mkEnableOption "EditorConfig home configuration file"; + enable = lib.mkEnableOption "EditorConfig home configuration file"; - settings = mkOption { + settings = lib.mkOption { type = iniFormat.type; default = { }; description = '' @@ -23,7 +21,7 @@ in { it must not be added here. See for documentation. ''; - example = literalExpression '' + example = lib.literalExpression '' { "*" = { charset = "utf-8"; @@ -39,9 +37,9 @@ in { }; }; - config = mkIf (cfg.enable && cfg.settings != { }) { + config = lib.mkIf (cfg.enable && cfg.settings != { }) { home.file.".editorconfig".text = let - renderedSettings = generators.toINIWithGlobalSection { } { + renderedSettings = lib.generators.toINIWithGlobalSection { } { globalSection = { root = true; }; sections = cfg.settings; }; diff --git a/modules/misc/fontconfig.nix b/modules/misc/fontconfig.nix index 9bc6ac47b..09906a440 100644 --- a/modules/misc/fontconfig.nix +++ b/modules/misc/fontconfig.nix @@ -4,8 +4,6 @@ { config, lib, pkgs, ... }: -with lib; - let cfg = config.fonts.fontconfig; @@ -13,10 +11,10 @@ let profileDirectory = config.home.profileDirectory; in { - meta.maintainers = [ maintainers.rycee ]; + meta.maintainers = [ lib.maintainers.rycee ]; imports = [ - (mkRenamedOptionModule [ "fonts" "fontconfig" "enableProfileFonts" ] [ + (lib.mkRenamedOptionModule [ "fonts" "fontconfig" "enableProfileFonts" ] [ "fonts" "fontconfig" "enable" @@ -25,8 +23,8 @@ in { options = { fonts.fontconfig = { - enable = mkOption { - type = types.bool; + enable = lib.mkOption { + type = lib.types.bool; default = false; description = '' Whether to enable fontconfig configuration. This will, for @@ -38,8 +36,8 @@ in { }; defaultFonts = { - monospace = mkOption { - type = with types; listOf str; + monospace = lib.mkOption { + type = with lib.types; listOf str; default = [ ]; description = '' Per-user default monospace font(s). Multiple fonts may be listed in @@ -47,8 +45,8 @@ in { ''; }; - sansSerif = mkOption { - type = with types; listOf str; + sansSerif = lib.mkOption { + type = with lib.types; listOf str; default = [ ]; description = '' Per-user default sans serif font(s). Multiple fonts may be listed @@ -56,8 +54,8 @@ in { ''; }; - serif = mkOption { - type = with types; listOf str; + serif = lib.mkOption { + type = with lib.types; listOf str; default = [ ]; description = '' Per-user default serif font(s). Multiple fonts may be listed in @@ -65,8 +63,8 @@ in { ''; }; - emoji = mkOption { - type = with types; listOf str; + emoji = lib.mkOption { + type = with lib.types; listOf str; default = [ ]; description = '' Per-user default emoji font(s). Multiple fonts may be listed in @@ -83,7 +81,7 @@ in { }; }; - config = mkIf cfg.enable { + config = lib.mkIf cfg.enable { home.packages = [ # Make sure that buildEnv creates a real directory path so that we avoid # trying to write to a read-only location. @@ -105,7 +103,7 @@ in { EOF - ${getBin pkgs.fontconfig}/bin/fc-cache -f + ${lib.getBin pkgs.fontconfig}/bin/fc-cache -f rm -f $out/lib/fontconfig/cache/CACHEDIR.TAG rmdir --ignore-fail-on-non-empty -p $out/lib/fontconfig/cache @@ -147,12 +145,12 @@ in { "fontconfig/conf.d/52-hm-default-fonts.conf".text = let genDefault = fonts: name: - optionalString (fonts != [ ]) '' + lib.optionalString (fonts != [ ]) '' ${name} ${ - concatStringsSep "" (map (font: '' + lib.concatStringsSep "" (map (font: '' ${font} '') fonts) } diff --git a/modules/misc/gtk.nix b/modules/misc/gtk.nix index e1ae250fd..f6ee95a19 100644 --- a/modules/misc/gtk.nix +++ b/modules/misc/gtk.nix @@ -1,29 +1,30 @@ -{ config, lib, pkgs, ... }: - -with lib; +{ config, lib, ... }: let + inherit (lib) literalExpression mkOption optionalAttrs types; cfg = config.gtk; cfg2 = config.gtk.gtk2; cfg3 = config.gtk.gtk3; cfg4 = config.gtk.gtk4; - toGtk3Ini = generators.toINI { + toGtk3Ini = lib.generators.toINI { mkKeyValue = key: value: - let value' = if isBool value then boolToString value else toString value; - in "${escape [ "=" ] key}=${value'}"; + let + value' = + if lib.isBool value then lib.boolToString value else toString value; + in "${lib.escape [ "=" ] key}=${value'}"; }; formatGtk2Option = n: v: let - v' = if isBool v then - boolToString value - else if isString v then + v' = if lib.isBool v then + lib.boolToString lib.value + else if lib.isString v then ''"${v}"'' else toString v; - in "${escape [ "=" ] n} = ${v'}"; + in "${lib.escape [ "=" ] n} = ${v'}"; themeType = types.submodule { options = { @@ -53,7 +54,7 @@ let package = mkOption { type = types.nullOr types.package; default = null; - example = literalExpression "pkgs.gnome.adwaita-icon-theme"; + example = literalExpression "pkgs.adwaita-icon-theme"; description = '' Package providing the icon theme. This package will be installed to your profile. If `null` then the theme @@ -100,20 +101,20 @@ let }; in { - meta.maintainers = [ maintainers.rycee ]; + meta.maintainers = [ lib.maintainers.rycee ]; imports = [ - (mkRemovedOptionModule [ "gtk" "gtk3" "waylandSupport" ] '' + (lib.mkRemovedOptionModule [ "gtk" "gtk3" "waylandSupport" ] '' This options is not longer needed and can be removed. '') ]; options = { gtk = { - enable = mkEnableOption "GTK 2/3 configuration"; + enable = lib.mkEnableOption "GTK 2/3 configuration"; font = mkOption { - type = types.nullOr hm.types.fontType; + type = types.nullOr lib.hm.types.fontType; default = null; description = '' The font to use in GTK+ 2/3 applications. @@ -219,7 +220,7 @@ in { }; }; - config = mkIf cfg.enable (let + config = lib.mkIf cfg.enable (let gtkIni = optionalAttrs (cfg.font != null) { gtk-font-name = let fontSize = if cfg.font.size != null then cfg.font.size else 10; @@ -258,18 +259,17 @@ in { }; optionalPackage = opt: - optional (opt != null && opt.package != null) opt.package; + lib.optional (opt != null && opt.package != null) opt.package; in { - home.packages = concatMap optionalPackage [ + home.packages = lib.concatMap optionalPackage [ cfg.font cfg.theme cfg.iconTheme cfg.cursorTheme ]; - home.file.${cfg2.configLocation}.text = - concatMapStrings (l: l + "\n") (mapAttrsToList formatGtk2Option gtkIni) - + cfg2.extraConfig + "\n"; + home.file.${cfg2.configLocation}.text = lib.concatMapStrings (l: l + "\n") + (lib.mapAttrsToList formatGtk2Option gtkIni) + cfg2.extraConfig + "\n"; home.sessionVariables.GTK2_RC_FILES = cfg2.configLocation; @@ -277,16 +277,17 @@ in { toGtk3Ini { Settings = gtkIni // cfg3.extraConfig; }; xdg.configFile."gtk-3.0/gtk.css" = - mkIf (cfg3.extraCss != "") { text = cfg3.extraCss; }; + lib.mkIf (cfg3.extraCss != "") { text = cfg3.extraCss; }; - xdg.configFile."gtk-3.0/bookmarks" = mkIf (cfg3.bookmarks != [ ]) { - text = concatMapStrings (l: l + "\n") cfg3.bookmarks; + xdg.configFile."gtk-3.0/bookmarks" = lib.mkIf (cfg3.bookmarks != [ ]) { + text = lib.concatMapStrings (l: l + "\n") cfg3.bookmarks; }; xdg.configFile."gtk-4.0/settings.ini".text = toGtk3Ini { Settings = gtkIni // cfg4.extraConfig; }; - xdg.configFile."gtk-4.0/gtk.css" = mkIf (gtk4Css != "") { text = gtk4Css; }; + xdg.configFile."gtk-4.0/gtk.css" = + lib.mkIf (gtk4Css != "") { text = gtk4Css; }; dconf.settings."org/gnome/desktop/interface" = dconfIni; }); diff --git a/modules/misc/mozilla-messaging-hosts.nix b/modules/misc/mozilla-messaging-hosts.nix new file mode 100644 index 000000000..09a4188f1 --- /dev/null +++ b/modules/misc/mozilla-messaging-hosts.nix @@ -0,0 +1,92 @@ +{ config, lib, pkgs, ... }: + +let + inherit (pkgs.stdenv) isDarwin; + + cfg = config.mozilla; + + defaultPaths = [ + # Link a .keep file to keep the directory around + (pkgs.writeTextDir "lib/mozilla/native-messaging-hosts/.keep" "") + ]; + + thunderbirdNativeMessagingHostsPath = if isDarwin then + "Library/Mozilla/NativeMessagingHosts" + else + ".mozilla/native-messaging-hosts"; + + firefoxNativeMessagingHostsPath = if isDarwin then + "Library/Application Support/Mozilla/NativeMessagingHosts" + else + ".mozilla/native-messaging-hosts"; +in { + meta.maintainers = with lib.maintainers; [ + booxter + rycee + lib.hm.maintainers.bricked + ]; + + options.mozilla = { + firefoxNativeMessagingHosts = lib.mkOption { + internal = true; + type = with lib.types; listOf package; + default = [ ]; + description = '' + List of Firefox native messaging hosts to configure. + ''; + }; + + thunderbirdNativeMessagingHosts = lib.mkOption { + internal = true; + type = with lib.types; listOf package; + default = [ ]; + description = '' + List of Thunderbird native messaging hosts to configure. + ''; + }; + }; + + config = lib.mkIf (cfg.firefoxNativeMessagingHosts != [ ] + || cfg.thunderbirdNativeMessagingHosts != [ ]) { + home.file = if isDarwin then + let + firefoxNativeMessagingHostsJoined = pkgs.symlinkJoin { + name = "ff-native-messaging-hosts"; + paths = defaultPaths ++ cfg.firefoxNativeMessagingHosts; + }; + thunderbirdNativeMessagingHostsJoined = pkgs.symlinkJoin { + name = "th-native-messaging-hosts"; + paths = defaultPaths ++ cfg.thunderbirdNativeMessagingHosts; + }; + in { + "${thunderbirdNativeMessagingHostsPath}" = + lib.mkIf (cfg.thunderbirdNativeMessagingHosts != [ ]) { + source = + "${thunderbirdNativeMessagingHostsJoined}/lib/mozilla/native-messaging-hosts"; + recursive = true; + }; + + "${firefoxNativeMessagingHostsPath}" = + lib.mkIf (cfg.firefoxNativeMessagingHosts != [ ]) { + source = + "${firefoxNativeMessagingHostsJoined}/lib/mozilla/native-messaging-hosts"; + recursive = true; + }; + } + else + let + nativeMessagingHostsJoined = pkgs.symlinkJoin { + name = "mozilla-native-messaging-hosts"; + # on Linux, the directory is shared between Firefox and Thunderbird; merge both into one + paths = defaultPaths ++ cfg.firefoxNativeMessagingHosts + ++ cfg.thunderbirdNativeMessagingHosts; + }; + in { + "${firefoxNativeMessagingHostsPath}" = { + source = + "${nativeMessagingHostsJoined}/lib/mozilla/native-messaging-hosts"; + recursive = true; + }; + }; + }; +} diff --git a/modules/misc/news.nix b/modules/misc/news.nix index f8786de2f..a3fb800f0 100644 --- a/modules/misc/news.nix +++ b/modules/misc/news.nix @@ -1,6 +1,8 @@ -{ config, lib, options, pkgs, ... }: -with lib; +{ config, lib, pkgs, ... }: + let + inherit (lib) mkOption types; + cfg = config.news; hostPlatform = pkgs.stdenv.hostPlatform; @@ -39,10 +41,12 @@ let }; }; - config = { id = mkDefault (builtins.hashString "sha256" config.message); }; + config = { + id = lib.mkDefault (builtins.hashString "sha256" config.message); + }; }); in { - meta.maintainers = [ maintainers.rycee ]; + meta.maintainers = [ lib.maintainers.rycee ]; options = { news = { @@ -1653,6 +1657,23 @@ in { ''; } + { + time = "2024-05-21T20:22:57+00:00"; + condition = config.programs.git.signing != { }; + message = '' + The Git module now supports signing via SSH and X.509 keys, in addition to OpenPGP/GnuPG, + via the `programs.git.signing.format` option. + + The format defaults to `openpgp` for now, due to backwards compatibility reasons — this is + not guaranteed to last! GPG users should manually set `programs.git.signing.format` to + `openpgp` as soon as possible. + + Accordingly, `programs.git.signing.gpgPath` has been renamed to the more generic option + `programs.git.signing.signer` as not everyone uses GPG. + Please migrate to the new option to suppress the generated warning. + ''; + } + { time = "2024-05-25T14:36:03+00:00"; message = '' @@ -1700,6 +1721,16 @@ in { ''; } + { + time = "2024-08-18T11:42:08+00:00"; + message = '' + A new module is available: 'programs.lapce'. + + Lightning-fast and Powerful Code Editor written in Rust. + See https://lapce.dev/ for more. + ''; + } + { time = "2024-09-13T08:58:17+00:00"; condition = hostPlatform.isLinux; @@ -1748,6 +1779,367 @@ in { add `-w` to your assignment of `services.swayidle.extraArgs`. ''; } + + { + time = "2024-10-09T06:16:23+00:00"; + condition = hostPlatform.isLinux; + message = '' + A new module is available: 'services.snixembed'. + + snixembed proxies StatusNotifierItems as XEmbedded systemtray-spec + icons. This is useful for some tools in some environments, e.g., Safe + Eyes in i3, lxde or mate. + ''; + } + + { + time = "2024-10-11T08:23:19+00:00"; + message = '' + A new module is available: 'programs.vifm'. + + Vifm is a curses based Vim-like file manager extended with some useful + ideas from mutt. + ''; + } + + { + time = "2024-10-17T13:07:55+00:00"; + message = '' + A new module is available: 'programs.zed-editor'. + + Zed is a fast text editor for macOS and Linux. + See https://zed.dev for more. + ''; + } + + { + time = "2024-10-18T14:01:07+00:00"; + message = '' + A new module is available: 'programs.cmus'. + + cmus is a small, fast and powerful console music player. + ''; + } + + { + time = "2024-10-20T07:53:54+00:00"; + condition = hostPlatform.isLinux; + message = '' + A new module is available: 'programs.nh'. + + nh is yet another Nix CLI helper. Adding functionality on top of the + existing solutions, like nixos-rebuild, home-manager cli or nix + itself. + ''; + } + + { + time = "2024-10-25T08:18:30+00:00"; + condition = hostPlatform.isLinux; + message = '' + A new module is available: 'nixGL'. + + NixGL solve the "OpenGL" problem with nix. The 'nixGL' module provides + integration of NixGL into Home Manager. See the "GPU on non-NixOS + systems" section in the Home Manager manual for more. + ''; + } + + { + time = "2024-11-01T19:44:59+00:00"; + condition = hostPlatform.isLinux; + message = '' + A new module is available: 'services.podman'. + + Podman is a daemonless container engine that lets you manage + containers, pods, and images. + + This Home Manager module allows you to define containers that will run + as systemd services. + ''; + } + + { + time = "2024-12-01T19:17:40+00:00"; + message = '' + A new module is available: 'programs.nix-your-shell'. + + nix-your-shell is a wrapper for `nix develop` or `nix-shell` to retain + the same shell inside the new environment. + ''; + } + + { + time = "2024-12-01T19:34:04+00:00"; + message = '' + A new module is available: 'programs.kubecolor'. + + Kubecolor is a kubectl wrapper used to add colors to your kubectl + output. + ''; + } + + { + time = "2024-12-04T20:00:00+00:00"; + condition = let + sCfg = config.programs.starship; + fCfg = config.programs.fish; + in sCfg.enable && sCfg.enableFishIntegration && fCfg.enable; + message = '' + A new option 'programs.starship.enableInteractive' is available for + the Fish shell that only enables starship if the shell is interactive. + + Some plugins require this to be set to 'false' to function correctly. + ''; + } + { + time = "2024-12-08T17:22:13+00:00"; + condition = let + usingMbsync = lib.any (a: a.mbsync.enable) + (lib.attrValues config.accounts.email.accounts); + in usingMbsync; + message = '' + isync/mbsync 1.5.0 has changed several things. + + isync gained support for using $XDG_CONFIG_HOME, and now places + its config file in '$XDG_CONFIG_HOME/isyncrc'. + + isync changed the configuration options SSLType and SSLVersion to + TLSType and TLSVersion respectively. + + All instances of + 'accounts.email.accounts..mbsync.extraConfig.account' + that use 'SSLType' or 'SSLVersion' should be replaced with 'TLSType' + or 'TLSVersion', respectively. + + TLSType options are unchanged. + + TLSVersions has a new syntax, requiring a change to the Nix syntax. + Old Syntax: SSLVersions = [ "TLSv1.3" "TLSv1.2" ]; + New Syntax: TLSVersions = [ "+1.3" "+1.2" "-1.1" ]; + NOTE: The minus symbol means to NOT use that particular TLS version. + ''; + } + + { + time = "2024-12-10T22:20:10+00:00"; + condition = config.programs.nushell.enable; + message = '' + The module 'programs.nushell' can now manage the Nushell plugin + registry with the option 'programs.nushell.plugins'. + ''; + } + + { + time = "2024-12-21T17:07:49+00:00"; + message = '' + A new module is available: 'programs.pay-respects'. + + Pay Respects is a shell command suggestions tool and command-not-found + and thefuck replacement written in Rust. + ''; + } + + { + time = "2024-12-22T08:24:29+00:00"; + condition = hostPlatform.isLinux; + message = '' + A new module is available: 'programs.cavalier'. + + Cavalier is a GUI wrapper around the Cava audio visualizer. + ''; + } + + { + time = "2025-01-01T15:31:15+00:00"; + condition = hostPlatform.isLinux; + message = '' + The 'systemd.user.startServices' option now defaults to 'true', + meaning that services will automatically be restarted as needed when + activating a configuration. + + Further, the "legacy" alternative has been removed and will now result + in an evaluation error if used. + + The "suggest" alternative will remain for a while longer but may also + 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. + ''; + } + + { + time = "2025-01-04T15:00:00+00:00"; + condition = hostPlatform.isLinux; + message = '' + A new module is available: 'wayland.windowManager.wayfire'. + + Wayfire is a 3D Wayland compositor, inspired by Compiz and based on + wlroots. It aims to create a customizable, extendable and lightweight + environment without sacrificing its appearance. + + This Home Manager module allows you to configure both wayfire itself, + as well as wf-shell. + ''; + } + + { + time = "2025-01-21T17:28:13+00:00"; + condition = with config.programs.yazi; enable && enableFishIntegration; + message = '' + Yazi's fish shell integration wrapper now calls the 'yazi' executable + directly, ignoring any shell aliases with the same name. + + Your configuration may break if you rely on the wrapper calling a + 'yazi' alias. + ''; + } + + { + time = "2025-01-29T17:34:53+00:00"; + condition = config.programs.firefox.enable; + message = '' + The Firefox module now provides a + 'programs.firefox.profiles..preConfig' option. + + It allows extra preferences to be added to 'user.js' before the + options specified in 'programs.firefox.profiles..settings', so + that they can be overwritten. + ''; + } + + { + time = "2025-01-29T19:11:20+00:00"; + condition = hostPlatform.isDarwin; + message = '' + A new module is available: 'programs.aerospace'. + + AeroSpace is an i3-like tiling window manager for macOS. + See https://github.com/nikitabobko/AeroSpace for more. + ''; + } + + { + time = "2025-01-30T09:18:55+00:00"; + condition = hostPlatform.isLinux; + message = '' + A new module is available: 'services.linux-wallpaperengine'. + + Reproduce the background functionality of Wallpaper Engine on Linux + systems. + ''; + } + + { + time = "2025-02-07T22:31:45+00:00"; + message = '' + All 'programs..enableIntegration' values now default + to the new 'home.shell.enableIntegration' options, which + inherit from the new the 'home.shell.enableShellIntegration' option. + + The following inconsistent default values change from 'false' to + 'true': + + - programs.zellij.enableBashIntegration + - programs.zellij.enableFishIntegration + - programs.zellij.enableZshIntegration + ''; + } + + { + time = "2025-02-11T15:25:26+00:00"; + message = '' + A new module is available: 'programs.git-worktree-switcher'. + + git-worktree-switcher allows you to quickly switch git worktrees. + It includes shell completions for Bash, Fish and Zsh. + See https://github.com/mateusauler/git-worktree-switcher for more. + ''; + } + + { + time = "2025-02-20T18:39:31+00:00"; + condition = hostPlatform.isLinux; + message = '' + A new module is available: 'programs.swayimg'. + + swayimg is a fully customizable and lightweight image viewer for + Wayland based display servers. + See https://github.com/artemsen/swayimg for more. + ''; + } + + { + time = "2025-02-16T17:00:00+00:00"; + message = '' + A new module is available: 'services.wluma'. + + Wluma is a tool for Wayland compositors to automatically adjust + screen brightness based on the screen contents and amount of ambient light around you. + ''; + } + + { + time = "2025-02-21T16:53:20+00:00"; + message = '' + A new module is available: 'programs.earthly'. + + Earthly is a build configuration framework utilizing buildkit and + Dockerfile-like syntax for fast builds and simplicity. + ''; + } + + { + time = "2025-02-22T16:53:20+00:00"; + message = '' + A new module is available: 'programs.jqp'. + + A TUI playground for experimenting with `jq`. + ''; + } + + { + time = "2025-02-22T16:46:56+00:00"; + condition = hostPlatform.isLinux; + message = '' + A new module is available: 'services.wpaperd'. + + This replaces the existing module, 'programs.wpaperd', and adds a + systemd service to ensure its execution. + ''; + } + + { + time = "2025-01-26T16:40:00+00:00"; + message = '' + A new module is available: 'programs.mods' + + mods is a command line AI tool that is highly configurable and allows + querying AI models hosted locally or by other services (OpenAI, + Cohere, Groq). + ''; + } + + { + time = "2025-03-11T02:34:43+00:00"; + condition = config.programs.zsh.enable; + message = '' + A new module is available: 'programs.zsh.initContent'. + + initContent option allows you to set the content of the zshrc file, + you can use `lib.mkOrder` to specify the order of the content you want to insert. + ''; + } ]; }; } diff --git a/modules/misc/nixgl.nix b/modules/misc/nixgl.nix new file mode 100644 index 000000000..541314723 --- /dev/null +++ b/modules/misc/nixgl.nix @@ -0,0 +1,304 @@ +{ config, lib, pkgs, ... }: + +let + cfg = config.nixGL; + wrapperListMarkdown = with builtins; + foldl' (list: name: + list + '' + - ${name} + '') "" (attrNames config.lib.nixGL.wrappers); +in { + meta.maintainers = [ lib.maintainers.smona ]; + + options.nixGL = { + packages = lib.mkOption { + type = with lib.types; nullOr attrs; + default = null; + example = lib.literalExpression "inputs.nixGL.packages"; + description = '' + The nixGL package set containing GPU library wrappers. This can be used + to provide OpenGL and Vulkan access to applications on non-NixOS systems + by using `(config.lib.nixGL.wrap )` for the default wrapper, or + `(config.lib.nixGL.wrappers. )` for any available + wrapper. + + The wrapper functions are always available. If this option is empty (the + default), they are a no-op. This is useful on NixOS where the wrappers + are unnecessary. + + Note that using any Nvidia wrapper requires building the configuration + with the `--impure` option. + ''; + }; + + defaultWrapper = lib.mkOption { + type = lib.types.enum (builtins.attrNames config.lib.nixGL.wrappers); + default = "mesa"; + description = '' + The package wrapper function available for use as `(config.lib.nixGL.wrap + )`. Intended to start programs on the main GPU. + + Wrapper functions can be found under `config.lib.nixGL.wrappers`. They + can be used directly, however, setting this option provides a convenient + shorthand. + + The following wrappers are available: + ${wrapperListMarkdown} + ''; + }; + + offloadWrapper = lib.mkOption { + type = lib.types.enum (builtins.attrNames config.lib.nixGL.wrappers); + default = "mesaPrime"; + description = '' + The package wrapper function available for use as + `(config.lib.nixGL.wrapOffload )`. Intended to start programs + on the secondary GPU. + + Wrapper functions can be found under `config.lib.nixGL.wrappers`. They + can be used directly, however, setting this option provides a convenient + shorthand. + + The following wrappers are available: + ${wrapperListMarkdown} + ''; + }; + + prime.card = lib.mkOption { + type = lib.types.str; + default = "1"; + example = "pci-0000_06_00_0"; + description = '' + Selects the non-default graphics card used for PRIME render offloading. + The value can be: + + - a number, selecting the n-th non-default GPU; + - a PCI bus id in the form `pci-XXX_YY_ZZ_U`; + - a PCI id in the form `vendor_id:device_id` + + For more information, consult the Mesa documentation on the `DRI_PRIME` + environment variable. + ''; + }; + + prime.nvidiaProvider = lib.mkOption { + type = with lib.types; nullOr str; + default = null; + example = "NVIDIA-G0"; + description = '' + If this option is set, it overrides the offload provider for Nvidia + PRIME offloading. Consult the proprietary Nvidia driver documentation + on the `__NV_PRIME_RENDER_OFFLOAD_PROVIDER` environment variable. + ''; + }; + + prime.installScript = lib.mkOption { + type = with lib.types; nullOr (enum [ "mesa" "nvidia" ]); + default = null; + example = "mesa"; + description = '' + If this option is set, the wrapper script `prime-offload` is installed + into the environment. It allows starting programs on the secondary GPU + selected by the `nixGL.prime.card` option. This makes sense when the + program is not already using one of nixGL PRIME wrappers, or for + programs not installed from Nixpkgs. + + This option can be set to either "mesa" or "nvidia", making the script + use one or the other graphics library. + ''; + }; + + installScripts = lib.mkOption { + type = with lib.types; + nullOr (listOf (enum (builtins.attrNames config.lib.nixGL.wrappers))); + default = null; + example = [ "mesa" "mesaPrime" ]; + description = '' + For each wrapper `wrp` named in the provided list, a wrapper script + named `nixGLWrp` is installed into the environment. These scripts are + useful for running programs not installed via Home Manager. + + The following wrappers are available: + ${wrapperListMarkdown} + ''; + }; + + vulkan.enable = lib.mkOption { + type = lib.types.bool; + default = false; + example = true; + description = '' + Whether to enable Vulkan in nixGL wrappers. + + This is disabled by default bacause Vulkan brings in several libraries + that can cause symbol version conflicts in wrapped programs. Your + mileage may vary. + ''; + }; + }; + + config = let + findWrapperPackage = packageAttr: + # NixGL has wrapper packages in different places depending on how you + # access it. We want HM configuration to be the same, regardless of how + # NixGL is imported. + # + # First, let's see if we have a flake. + if builtins.hasAttr pkgs.system cfg.packages then + cfg.packages.${pkgs.system}.${packageAttr} + else + # Next, let's see if we have a channel. + if builtins.hasAttr packageAttr cfg.packages then + cfg.packages.${packageAttr} + else + # Lastly, with channels, some wrappers are grouped under "auto". + if builtins.hasAttr "auto" cfg.packages then + cfg.packages.auto.${packageAttr} + else + throw "Incompatible NixGL package layout"; + + getWrapperExe = vendor: + let + glPackage = findWrapperPackage "nixGL${vendor}"; + glExe = lib.getExe glPackage; + vulkanPackage = findWrapperPackage "nixVulkan${vendor}"; + vulkanExe = if cfg.vulkan.enable then lib.getExe vulkanPackage else ""; + in "${glExe} ${vulkanExe}"; + + mesaOffloadEnv = { "DRI_PRIME" = "${cfg.prime.card}"; }; + + nvOffloadEnv = { + "DRI_PRIME" = "${cfg.prime.card}"; + "__NV_PRIME_RENDER_OFFLOAD" = "1"; + "__GLX_VENDOR_LIBRARY_NAME" = "nvidia"; + "__VK_LAYER_NV_optimus" = "NVIDIA_only"; + } // (let provider = cfg.prime.nvidiaProvider; + in if !isNull provider then { + "__NV_PRIME_RENDER_OFFLOAD_PROVIDER" = "${provider}"; + } else + { }); + + makePackageWrapper = vendor: environment: pkg: + if builtins.isNull cfg.packages then + pkg + else + # Wrap the package's binaries with nixGL, while preserving the rest of + # the outputs and derivation attributes. + (pkg.overrideAttrs (old: { + name = "nixGL-${pkg.name}"; + + # Make sure this is false for the wrapper derivation, so nix doesn't expect + # a new debug output to be produced. We won't be producing any debug info + # for the original package. + separateDebugInfo = false; + nativeBuildInputs = old.nativeBuildInputs or [ ] + ++ [ pkgs.makeWrapper ]; + buildCommand = let + # We need an intermediate wrapper package because makeWrapper + # requires a single executable as the wrapper. + combinedWrapperPkg = + pkgs.writeShellScriptBin "nixGLCombinedWrapper-${vendor}" '' + exec ${getWrapperExe vendor} "$@" + ''; + in '' + set -eo pipefail + + ${ # Heavily inspired by https://stackoverflow.com/a/68523368/6259505 + lib.concatStringsSep "\n" (map (outputName: '' + echo "Copying output ${outputName}" + set -x + cp -rs --no-preserve=mode "${ + pkg.${outputName} + }" "''$${outputName}" + set +x + '') (old.outputs or [ "out" ]))} + + rm -rf $out/bin/* + shopt -s nullglob # Prevent loop from running if no files + for file in ${pkg.out}/bin/*; do + local prog="$(basename "$file")" + makeWrapper \ + "${lib.getExe combinedWrapperPkg}" \ + "$out/bin/$prog" \ + --argv0 "$prog" \ + --add-flags "$file" \ + ${ + lib.concatStringsSep " " (lib.attrsets.mapAttrsToList + (var: val: "--set '${var}' '${val}'") environment) + } + done + + # If .desktop files refer to the old package, replace the references + for dsk in "$out/share/applications"/*.desktop ; do + if ! grep -q "${pkg.out}" "$dsk"; then + continue + fi + src="$(readlink "$dsk")" + rm "$dsk" + sed "s|${pkg.out}|$out|g" "$src" > "$dsk" + done + + shopt -u nullglob # Revert nullglob back to its normal default state + ''; + })) // { + # When the nixGL-wrapped package is given to a HM module, the module + # might want to override the package arguments, but our wrapper + # wouldn't know what to do with them. So, we rewrite the override + # function to instead forward the arguments to the package's own + # override function. + override = args: + makePackageWrapper vendor environment (pkg.override args); + }; + + wrappers = { + mesa = makePackageWrapper "Intel" { }; + mesaPrime = makePackageWrapper "Intel" mesaOffloadEnv; + nvidia = makePackageWrapper "Nvidia" { }; + nvidiaPrime = makePackageWrapper "Nvidia" nvOffloadEnv; + }; + in { + lib.nixGL.wrap = wrappers.${cfg.defaultWrapper}; + lib.nixGL.wrapOffload = wrappers.${cfg.offloadWrapper}; + lib.nixGL.wrappers = wrappers; + + home.packages = let + wantsPrimeWrapper = (!isNull cfg.prime.installScript); + wantsWrapper = wrapper: + (!isNull cfg.packages) && (!isNull cfg.installScripts) + && (builtins.elem wrapper cfg.installScripts); + envVarsAsScript = environment: + lib.concatStringsSep "\n" + (lib.attrsets.mapAttrsToList (var: val: "export ${var}=${val}") + environment); + in [ + (lib.mkIf wantsPrimeWrapper (pkgs.writeShellScriptBin "prime-offload" '' + ${if cfg.prime.installScript == "mesa" then + (envVarsAsScript mesaOffloadEnv) + else + (envVarsAsScript nvOffloadEnv)} + exec "$@" + '')) + + (lib.mkIf (wantsWrapper "mesa") (pkgs.writeShellScriptBin "nixGLMesa" '' + exec ${getWrapperExe "Intel"} "$@" + '')) + + (lib.mkIf (wantsWrapper "mesaPrime") + (pkgs.writeShellScriptBin "nixGLMesaPrime" '' + ${envVarsAsScript mesaOffloadEnv} + exec ${getWrapperExe "Intel"} "$@" + '')) + + (lib.mkIf (wantsWrapper "nvidia") + (pkgs.writeShellScriptBin "nixGLNvidia" '' + exec ${getWrapperExe "Nvidia"} "$@" + '')) + + (lib.mkIf (wantsWrapper "nvidia") + (pkgs.writeShellScriptBin "nixGLNvidiaPrime" '' + ${envVarsAsScript nvOffloadEnv} + exec ${getWrapperExe "Nvidia"} "$@" + '')) + ]; + }; +} diff --git a/modules/misc/nixpkgs-disabled.nix b/modules/misc/nixpkgs-disabled.nix index ab0f35df7..b7e143d97 100644 --- a/modules/misc/nixpkgs-disabled.nix +++ b/modules/misc/nixpkgs-disabled.nix @@ -1,7 +1,5 @@ { config, lib, pkgs, ... }: -with lib; - let cfg = config.nixpkgs; @@ -17,28 +15,28 @@ let let lhs = optCall lhs_ { inherit pkgs; }; rhs = optCall rhs_ { inherit pkgs; }; - in lhs // rhs // optionalAttrs (lhs ? packageOverrides) { + in lhs // rhs // lib.optionalAttrs (lhs ? packageOverrides) { packageOverrides = pkgs: optCall lhs.packageOverrides pkgs - // optCall (attrByPath [ "packageOverrides" ] ({ }) rhs) pkgs; - } // optionalAttrs (lhs ? perlPackageOverrides) { + // optCall (lib.attrByPath [ "packageOverrides" ] { } rhs) pkgs; + } // lib.optionalAttrs (lhs ? perlPackageOverrides) { perlPackageOverrides = pkgs: optCall lhs.perlPackageOverrides pkgs - // optCall (attrByPath [ "perlPackageOverrides" ] ({ }) rhs) pkgs; + // optCall (lib.attrByPath [ "perlPackageOverrides" ] { } rhs) pkgs; }; # Copied from nixpkgs.nix. - configType = mkOptionType { + configType = lib.mkOptionType { name = "nixpkgs-config"; description = "nixpkgs config"; check = x: let traceXIfNot = c: if c x then true else lib.traceSeqN 1 x false; in traceXIfNot isConfig; - merge = args: fold (def: mergeConfig def.value) { }; + merge = args: lib.fold (def: mergeConfig def.value) { }; }; # Copied from nixpkgs.nix. - overlayType = mkOptionType { + overlayType = lib.mkOptionType { name = "nixpkgs-overlay"; description = "nixpkgs overlay"; check = builtins.isFunction; @@ -46,28 +44,36 @@ let }; in { - meta.maintainers = with maintainers; [ thiagokokada ]; + meta.maintainers = with lib.maintainers; [ thiagokokada ]; options.nixpkgs = { - config = mkOption { + config = lib.mkOption { default = null; - type = types.nullOr configType; + type = lib.types.nullOr configType; visible = false; }; - overlays = mkOption { + overlays = lib.mkOption { default = null; - type = types.nullOr (types.listOf overlayType); + type = lib.types.nullOr (lib.types.listOf overlayType); visible = false; }; }; config = { - assertions = [{ - assertion = cfg.config == null || cfg.overlays == null; - message = '' - `nixpkgs` options are disabled when `home-manager.useGlobalPkgs` is enabled. - ''; - }]; + assertions = [ + # TODO: Re-enable assertion after 25.05 (&&) + { + assertion = cfg.config == null || cfg.overlays == null; + message = '' + `nixpkgs` options are disabled when `home-manager.useGlobalPkgs` is enabled. + ''; + } + ]; + + warnings = lib.optional ((cfg.config != null) || (cfg.overlays != null)) '' + You have set either `nixpkgs.config` or `nixpkgs.overlays` while using `home-manager.useGlobalPkgs`. + This will soon not be possible. Please remove all `nixpkgs` options when using `home-manager.useGlobalPkgs`. + ''; }; } diff --git a/modules/misc/nixpkgs.nix b/modules/misc/nixpkgs.nix index efbbba96c..b21e97db9 100644 --- a/modules/misc/nixpkgs.nix +++ b/modules/misc/nixpkgs.nix @@ -2,8 +2,6 @@ { config, lib, pkgs, pkgsPath, ... }: -with lib; - let isConfig = x: builtins.isAttrs x || builtins.isFunction x; @@ -14,40 +12,40 @@ let let lhs = optCall lhs_ { inherit pkgs; }; rhs = optCall rhs_ { inherit pkgs; }; - in lhs // rhs // optionalAttrs (lhs ? packageOverrides) { + in lhs // rhs // lib.optionalAttrs (lhs ? packageOverrides) { packageOverrides = pkgs: optCall lhs.packageOverrides pkgs - // optCall (attrByPath [ "packageOverrides" ] ({ }) rhs) pkgs; - } // optionalAttrs (lhs ? perlPackageOverrides) { + // optCall (lib.attrByPath [ "packageOverrides" ] { } rhs) pkgs; + } // lib.optionalAttrs (lhs ? perlPackageOverrides) { perlPackageOverrides = pkgs: optCall lhs.perlPackageOverrides pkgs - // optCall (attrByPath [ "perlPackageOverrides" ] ({ }) rhs) pkgs; + // optCall (lib.attrByPath [ "perlPackageOverrides" ] { } rhs) pkgs; }; - configType = mkOptionType { + configType = lib.mkOptionType { name = "nixpkgs-config"; description = "nixpkgs config"; check = x: let traceXIfNot = c: if c x then true else lib.traceSeqN 1 x false; in traceXIfNot isConfig; - merge = args: fold (def: mergeConfig def.value) { }; + merge = args: lib.fold (def: mergeConfig def.value) { }; }; - overlayType = mkOptionType { + overlayType = lib.mkOptionType { name = "nixpkgs-overlay"; description = "nixpkgs overlay"; - check = builtins.isFunction; + check = lib.isFunction; merge = lib.mergeOneOption; }; - _pkgs = import pkgsPath (filterAttrs (n: v: v != null) config.nixpkgs); + _pkgs = import pkgsPath (lib.filterAttrs (n: v: v != null) config.nixpkgs); in { options.nixpkgs = { - config = mkOption { + config = lib.mkOption { default = null; example = { allowBroken = true; }; - type = types.nullOr configType; + type = lib.types.nullOr configType; description = '' The configuration of the Nix Packages collection. (For details, see the Nixpkgs documentation.) It allows you to set @@ -72,9 +70,9 @@ in { ''; }; - overlays = mkOption { + overlays = lib.mkOption { default = null; - example = literalExpression '' + example = lib.literalExpression '' [ (final: prev: { openssh = prev.openssh.override { @@ -85,7 +83,7 @@ in { }) ] ''; - type = types.nullOr (types.listOf overlayType); + type = lib.types.nullOr (lib.types.listOf overlayType); description = '' List of overlays to use with the Nix Packages collection. (For details, see the Nixpkgs documentation.) It allows you to @@ -105,8 +103,8 @@ in { ''; }; - system = mkOption { - type = types.str; + system = lib.mkOption { + type = lib.types.str; example = "i686-linux"; internal = true; description = '' @@ -123,7 +121,7 @@ in { _module.args = { # We use a no-op override to make sure that the option can be merged without evaluating # `_pkgs`, see https://github.com/nix-community/home-manager/pull/993 - pkgs = mkOverride modules.defaultOverridePriority _pkgs; + pkgs = lib.mkOverride lib.modules.defaultOverridePriority _pkgs; pkgs_i686 = if _pkgs.stdenv.isLinux && _pkgs.stdenv.hostPlatform.isx86 then _pkgs.pkgsi686Linux diff --git a/modules/misc/numlock.nix b/modules/misc/numlock.nix index 88032417f..e453a0951 100644 --- a/modules/misc/numlock.nix +++ b/modules/misc/numlock.nix @@ -1,25 +1,24 @@ { config, lib, pkgs, ... }: -with lib; - let cfg = config.xsession.numlock; in { - meta.maintainers = [ maintainers.evanjs ]; + meta.maintainers = [ lib.maintainers.evanjs ]; - options = { xsession.numlock.enable = mkEnableOption "Num Lock"; }; + options = { xsession.numlock.enable = lib.mkEnableOption "Num Lock"; }; - config = mkIf cfg.enable { + config = lib.mkIf cfg.enable { assertions = [ - (hm.assertions.assertPlatform "xsession.numlock" pkgs platforms.linux) + (lib.hm.assertions.assertPlatform "xsession.numlock" pkgs + lib.platforms.linux) ]; systemd.user.services.numlockx = { Unit = { Description = "NumLockX"; - After = [ "graphical-session-pre.target" ]; + After = [ "graphical-session.target" ]; PartOf = [ "graphical-session.target" ]; }; diff --git a/modules/misc/pam.nix b/modules/misc/pam.nix index 22a5daf0d..bf0af355f 100644 --- a/modules/misc/pam.nix +++ b/modules/misc/pam.nix @@ -1,18 +1,16 @@ -{ config, lib, pkgs, ... }: - -with lib; +{ config, lib, ... }: let cfg = config.pam; in { - meta.maintainers = with maintainers; [ rycee veehaitch ]; + meta.maintainers = with lib.maintainers; [ rycee veehaitch ]; options = { - pam.sessionVariables = mkOption { + pam.sessionVariables = lib.mkOption { default = { }; - type = types.attrs; + type = lib.types.attrs; example = { EDITOR = "vim"; }; description = '' Environment variables that will be set for the PAM session. @@ -25,10 +23,10 @@ in { }; pam.yubico.authorizedYubiKeys = { - ids = mkOption { - type = with types; + ids = lib.mkOption { + type = with lib.types; let - yubiKeyId = addCheck str (s: stringLength s == 12) // { + yubiKeyId = addCheck str (s: lib.stringLength s == 12) // { name = "yubiKeyId"; description = "string of length 12"; }; @@ -41,8 +39,8 @@ in { ''; }; - path = mkOption { - type = types.str; + path = lib.mkOption { + type = lib.types.str; default = ".yubico/authorized_yubikeys"; description = '' File path to write the authorized YubiKeys, @@ -52,16 +50,16 @@ in { }; }; - config = mkMerge [ - (mkIf (cfg.sessionVariables != { }) { - home.file.".pam_environment".text = concatStringsSep "\n" - (mapAttrsToList (n: v: ''${n} OVERRIDE="${toString v}"'') + config = lib.mkMerge [ + (lib.mkIf (cfg.sessionVariables != { }) { + home.file.".pam_environment".text = lib.concatStringsSep "\n" + (lib.mapAttrsToList (n: v: ''${n} OVERRIDE="${toString v}"'') cfg.sessionVariables) + "\n"; }) - (mkIf (cfg.yubico.authorizedYubiKeys.ids != [ ]) { + (lib.mkIf (cfg.yubico.authorizedYubiKeys.ids != [ ]) { home.file.${cfg.yubico.authorizedYubiKeys.path}.text = - concatStringsSep ":" + lib.concatStringsSep ":" ([ config.home.username ] ++ cfg.yubico.authorizedYubiKeys.ids); }) ]; diff --git a/modules/misc/qt.nix b/modules/misc/qt.nix index a36bd5673..41cd660fc 100644 --- a/modules/misc/qt.nix +++ b/modules/misc/qt.nix @@ -8,7 +8,16 @@ let gnome = [ qgnomeplatform qgnomeplatform-qt6 ]; adwaita = [ qadwaitadecorations qadwaitadecorations-qt6 ]; gtk = [ libsForQt5.qtstyleplugins qt6Packages.qt6gtk2 ]; - kde = [ libsForQt5.plasma-integration libsForQt5.systemsettings ]; + kde = [ + libsForQt5.kio + libsForQt5.plasma-integration + libsForQt5.systemsettings + ]; + kde6 = [ + kdePackages.kio + kdePackages.plasma-integration + kdePackages.systemsettings + ]; lxqt = [ lxqt.lxqt-qtplugin lxqt.lxqt-config ]; qtct = [ libsForQt5.qt5ct qt6Packages.qt6ct ]; }; @@ -17,6 +26,7 @@ let styleNames = { gtk = "gtk2"; qtct = "qt5ct"; + kde6 = "kde"; }; # Maps known lowercase style names to style packages. Non-exhaustive. @@ -71,6 +81,8 @@ in { [ "libsForQt5" "qt5ct" ] [ "libsForQt5" "qtstyleplugins" ] [ "libsForQt5" "systemsettings" ] + [ "kdePackages" "plasma-integration" ] + [ "kdePackages" "systemsettings" ] [ "lxqt" "lxqt-config" ] [ "lxqt" "lxqt-qtplugin" ] [ "qt6Packages" "qt6ct" ] @@ -110,7 +122,10 @@ in { applications `kde` - : Use Qt settings from Plasma + : Use Qt settings from Plasma 5 + + `kde6` + : Use Qt settings from Plasma 6 ''; }; package = lib.mkOption { @@ -127,8 +142,8 @@ in { }; in lib.mkOption { type = with lib.types; - nullOr - (either (enum [ "gtk" "gtk3" "gnome" "adwaita" "lxqt" "qtct" "kde" ]) + nullOr (either + (enum [ "gtk" "gtk3" "gnome" "adwaita" "lxqt" "qtct" "kde" "kde6" ]) (lib.types.submodule { options = newOption; })); default = null; description = '' @@ -214,13 +229,10 @@ in { inherit (config.home) profileDirectory; qtVersions = with pkgs; [ qt5 qt6 ]; makeQtPath = prefix: - lib.concatStringsSep ":" (map (qt: "${profileDirectory}/${qt.qtbase.${prefix}}") qtVersions); in { - QT_PLUGIN_PATH = "$QT_PLUGIN_PATH\${QT_PLUGIN_PATH:+:}" - + (makeQtPath "qtPluginPrefix"); - QML2_IMPORT_PATH = "$QML2_IMPORT_PATH\${QML2_IMPORT_PATH:+:}" - + (makeQtPath "qtQmlPrefix"); + QT_PLUGIN_PATH = makeQtPath "qtPluginPrefix"; + QML2_IMPORT_PATH = makeQtPath "qtQmlPrefix"; }; in lib.mkIf cfg.enable { @@ -244,19 +256,14 @@ in { home = { sessionVariables = envVars; - # home.sessionVariables does not support setting the same environment - # variable to different values. - # Since some other modules may set the QT_PLUGIN_PATH or QML2_IMPORT_PATH - # to their own value, e.g.: fcitx5, we avoid conflicts by setting - # the values in home.sessionVariablesExtra instead. - sessionVariablesExtra = '' - export QT_PLUGIN_PATH=${envVarsExtra.QT_PLUGIN_PATH} - export QML2_IMPORT_PATH=${envVarsExtra.QML2_IMPORT_PATH} - ''; + sessionSearchVariables = envVarsExtra; }; # Apply theming also to apps started by systemd. - systemd.user.sessionVariables = envVars // envVarsExtra; + systemd.user.sessionVariables = envVars // { + QT_PLUGIN_PATH = lib.concatStringsSep ":" envVarsExtra.QT_PLUGIN_PATH; + QML2_IMPORT_PATH = lib.concatStringsSep ":" envVarsExtra.QML2_IMPORT_PATH; + }; home.packages = (lib.findFirst (x: x != [ ]) [ ] [ (lib.optionals (platformTheme.package != null) diff --git a/modules/misc/qt/kconfig.nix b/modules/misc/qt/kconfig.nix index f7c35573b..76bf7c686 100644 --- a/modules/misc/qt/kconfig.nix +++ b/modules/misc/qt/kconfig.nix @@ -17,13 +17,13 @@ in { powermanagementprofilesrc.AC.HandleButtonEvents.lidAction = 32; }; description = '' - A set of values to be modified by {command}`kwriteconfig5`. + A set of values to be modified by {command}`kwriteconfig6`. The example value would cause the following command to run in the activation script: ``` shell - kwriteconfig5 --file $XDG_CONFIG_HOME/powermanagementprofilesrc \ + kwriteconfig6 --file $XDG_CONFIG_HOME/powermanagementprofilesrc \ --group AC \ --group HandleButtonEvents \ --group lidAction \ @@ -53,7 +53,7 @@ in { lib.mapAttrsToList (group: value: toLine file (path ++ [ group ]) value) value else - "run test -f '${configHome}/${file}' && run ${pkgs.libsForQt5.kconfig}/bin/kwriteconfig5 --file '${configHome}/${file}' ${ + "run ${pkgs.kdePackages.kconfig}/bin/kwriteconfig6 --file '${configHome}/${file}' ${ lib.concatMapStringsSep " " (x: "--group ${x}") (lib.lists.init path) } --key '${lib.lists.last path}' ${toValue value}"; @@ -62,7 +62,7 @@ in { in builtins.concatStringsSep "\n" lines} # TODO: some way to only call the dbus calls needed - run ${pkgs.libsForQt5.qttools.bin}/bin/qdbus org.kde.KWin /KWin reconfigure || echo "KWin reconfigure failed" + run ${pkgs.kdePackages.qttools}/bin/qdbus org.kde.KWin /KWin reconfigure || echo "KWin reconfigure failed" # the actual values are https://github.com/KDE/plasma-workspace/blob/c97dddf20df5702eb429b37a8c10b2c2d8199d4e/kcms/kcms-common_p.h#L13 for changeType in {0..10}; do # even if one of those calls fails the others keep running diff --git a/modules/misc/shell.nix b/modules/misc/shell.nix new file mode 100644 index 000000000..7ef8bbfc7 --- /dev/null +++ b/modules/misc/shell.nix @@ -0,0 +1,43 @@ +{ config, lib, ... }: + +{ + options.home.shell = { + enableShellIntegration = lib.mkOption { + type = lib.types.bool; + default = true; + example = false; + description = '' + Whether to globally enable shell integration for all supported shells. + + Individual shell integrations can be overridden with their respective + `shell.enableIntegration` option. For example, the following + declaration globally disables shell integration for Bash: + + ```nix + home.shell.enableBashIntegration = false; + ``` + ''; + }; + + enableBashIntegration = lib.hm.shell.mkBashIntegrationOption { + inherit config; + baseName = "Shell"; + }; + enableFishIntegration = lib.hm.shell.mkFishIntegrationOption { + inherit config; + baseName = "Shell"; + }; + enableIonIntegration = lib.hm.shell.mkIonIntegrationOption { + inherit config; + baseName = "Shell"; + }; + enableNushellIntegration = lib.hm.shell.mkNushellIntegrationOption { + inherit config; + baseName = "Shell"; + }; + enableZshIntegration = lib.hm.shell.mkZshIntegrationOption { + inherit config; + baseName = "Shell"; + }; + }; +} diff --git a/modules/misc/specialisation.nix b/modules/misc/specialisation.nix index dc5f78e14..95adc998f 100644 --- a/modules/misc/specialisation.nix +++ b/modules/misc/specialisation.nix @@ -1,27 +1,25 @@ { config, name, extendModules, lib, ... }: -with lib; - { imports = - [ (mkRenamedOptionModule [ "specialization" ] [ "specialisation" ]) ]; + [ (lib.mkRenamedOptionModule [ "specialization" ] [ "specialisation" ]) ]; - options.specialisation = mkOption { - type = types.attrsOf (types.submodule { + options.specialisation = lib.mkOption { + type = lib.types.attrsOf (lib.types.submodule { options = { - configuration = mkOption { + configuration = lib.mkOption { type = let extended = extendModules { modules = [{ # Prevent infinite recursion - specialisation = mkOverride 0 { }; + specialisation = lib.mkOverride 0 { }; # If used inside the NixOS/nix-darwin module, we get conflicting definitions # of `name` inside the specialisation: one is the user name coming from the # NixOS module definition and the other is `configuration`, the name of this # option. Thus we need to explicitly wire the former into the module arguments. # See discussion at https://github.com/nix-community/home-manager/issues/3716 - _module.args.name = mkForce name; + _module.args.name = lib.mkForce name; }]; }; in extended.type; @@ -70,14 +68,21 @@ with lib; ''; }; - config = mkIf (config.specialisation != { }) { + config = lib.mkIf (config.specialisation != { }) { + assertions = map (n: { + assertion = !lib.hasInfix "/" n; + message = + " in specialisation. cannot contain a forward slash."; + }) (lib.attrNames config.specialisation); + home.extraBuilderCommands = let link = n: v: let pkg = v.configuration.home.activationPackage; - in "ln -s ${pkg} $out/specialisation/${n}"; + in "ln -s ${pkg} $out/specialisation/${lib.escapeShellArg n}"; in '' mkdir $out/specialisation - ${concatStringsSep "\n" (mapAttrsToList link config.specialisation)} + ${lib.concatStringsSep "\n" + (lib.mapAttrsToList link config.specialisation)} ''; }; } diff --git a/modules/misc/submodule-support.nix b/modules/misc/submodule-support.nix index 82fbc0a30..b42bc4870 100644 --- a/modules/misc/submodule-support.nix +++ b/modules/misc/submodule-support.nix @@ -1,13 +1,11 @@ { lib, ... }: -with lib; - { - meta.maintainers = [ maintainers.rycee ]; + meta.maintainers = [ lib.maintainers.rycee ]; options.submoduleSupport = { - enable = mkOption { - type = types.bool; + enable = lib.mkOption { + type = lib.types.bool; default = false; internal = true; description = '' @@ -16,8 +14,8 @@ with lib; ''; }; - externalPackageInstall = mkOption { - type = types.bool; + externalPackageInstall = lib.mkOption { + type = lib.types.bool; default = false; internal = true; description = '' @@ -39,9 +37,9 @@ with lib; # module system can not inform modules about their non-existence; see # https://github.com/NixOS/nixpkgs/issues/311709#issuecomment-2110861842 _module.args = { - osConfig = mkDefault null; - nixosConfig = mkDefault null; - darwinConfig = mkDefault null; + osConfig = lib.mkDefault null; + nixosConfig = lib.mkDefault null; + darwinConfig = lib.mkDefault null; }; }; } diff --git a/modules/misc/tmpfiles.nix b/modules/misc/tmpfiles.nix index 9fa072b89..f9debf543 100644 --- a/modules/misc/tmpfiles.nix +++ b/modules/misc/tmpfiles.nix @@ -1,16 +1,14 @@ { config, lib, pkgs, ... }: -with lib; - let cfg = config.systemd.user.tmpfiles; in { - meta.maintainers = [ maintainers.dawidsowa ]; + meta.maintainers = [ lib.maintainers.dawidsowa ]; - options.systemd.user.tmpfiles.rules = mkOption { - type = types.listOf types.str; + options.systemd.user.tmpfiles.rules = lib.mkOption { + type = lib.types.listOf lib.types.str; default = [ ]; example = [ "L /home/user/Documents - - - - /mnt/data/Documents" ]; description = '' @@ -21,10 +19,10 @@ in { ''; }; - config = mkIf (cfg.rules != [ ]) { + config = lib.mkIf (cfg.rules != [ ]) { assertions = [ - (hm.assertions.assertPlatform "systemd.user.tmpfiles" pkgs - platforms.linux) + (lib.hm.assertions.assertPlatform "systemd.user.tmpfiles" pkgs + lib.platforms.linux) ]; xdg.configFile = { @@ -32,7 +30,7 @@ in { text = '' # This file is created automatically and should not be modified. # Please change the option ‘systemd.user.tmpfiles.rules’ instead. - ${concatStringsSep "\n" cfg.rules} + ${lib.concatStringsSep "\n" cfg.rules} ''; onChange = "${pkgs.systemd}/bin/systemd-tmpfiles --user --create"; }; diff --git a/modules/misc/uninstall.nix b/modules/misc/uninstall.nix index b34732b0b..4fe26326e 100644 --- a/modules/misc/uninstall.nix +++ b/modules/misc/uninstall.nix @@ -1,4 +1,4 @@ -{ config, lib, pkgs, ... }: +{ config, lib, ... }: let @@ -21,7 +21,7 @@ in { config = mkIf config.uninstall { home.packages = lib.mkForce [ ]; home.file = lib.mkForce { }; - home.stateVersion = lib.mkForce "24.05"; + home.stateVersion = lib.mkForce "24.11"; home.enableNixpkgsReleaseCheck = lib.mkForce false; manual.manpages.enable = lib.mkForce false; news.display = lib.mkForce "silent"; diff --git a/modules/misc/version.nix b/modules/misc/version.nix index d068a3869..3c7317360 100644 --- a/modules/misc/version.nix +++ b/modules/misc/version.nix @@ -1,12 +1,13 @@ { config, lib, ... }: -with lib; +let + inherit (lib) types; -let releaseInfo = lib.importJSON ../../release.json; + releaseInfo = lib.importJSON ../../release.json; in { options = { - home.stateVersion = mkOption { + home.stateVersion = lib.mkOption { type = types.enum [ "18.09" "19.03" @@ -22,6 +23,7 @@ in { "23.11" "24.05" "24.11" + "25.05" ]; description = '' It is occasionally necessary for Home Manager to change @@ -38,20 +40,20 @@ in { }; home.version = { - full = mkOption { + full = lib.mkOption { internal = true; readOnly = true; type = types.str; default = let inherit (config.home.version) release revision; - suffix = - optionalString (revision != null) "+${substring 0 8 revision}"; + suffix = lib.optionalString (revision != null) + "+${lib.substring 0 8 revision}"; in "${release}${suffix}"; example = "22.11+213a0629"; description = "The full Home Manager version."; }; - release = mkOption { + release = lib.mkOption { internal = true; readOnly = true; type = types.str; @@ -60,7 +62,7 @@ in { description = "The Home Manager release."; }; - isReleaseBranch = mkOption { + isReleaseBranch = lib.mkOption { internal = true; readOnly = true; type = types.bool; @@ -71,11 +73,14 @@ in { ''; }; - revision = mkOption { + revision = lib.mkOption { internal = true; type = types.nullOr types.str; default = let gitRepo = "${toString ./../..}/.git"; - in if pathIsGitRepo gitRepo then commitIdFromGitRepo gitRepo else null; + in if lib.pathIsGitRepo gitRepo then + lib.commitIdFromGitRepo gitRepo + else + null; description = '' The Git revision from which this Home Manager configuration was built. ''; diff --git a/modules/misc/vte.nix b/modules/misc/vte.nix index fbe38c016..c734fd448 100644 --- a/modules/misc/vte.nix +++ b/modules/misc/vte.nix @@ -1,9 +1,7 @@ { config, lib, pkgs, ... }: -with lib; - { - meta.maintainers = [ maintainers.rycee ]; + meta.maintainers = [ lib.maintainers.rycee ]; options.programs = let description = '' @@ -12,13 +10,17 @@ with lib; directory. ''; in { - bash.enableVteIntegration = mkEnableOption "" // { inherit description; }; + bash.enableVteIntegration = lib.mkEnableOption "" // { + inherit description; + }; - zsh.enableVteIntegration = mkEnableOption "" // { inherit description; }; + zsh.enableVteIntegration = lib.mkEnableOption "" // { + inherit description; + }; }; - config = mkMerge [ - (mkIf config.programs.bash.enableVteIntegration { + config = lib.mkMerge [ + (lib.mkIf config.programs.bash.enableVteIntegration { # Unfortunately we have to do a little dance here to fix two # problems with the upstream vte.sh file: # @@ -42,7 +44,7 @@ with lib; ''; }) - (mkIf config.programs.zsh.enableVteIntegration { + (lib.mkIf config.programs.zsh.enableVteIntegration { programs.zsh.initExtra = '' . ${pkgs.vte}/etc/profile.d/vte.sh ''; diff --git a/modules/misc/xdg-autostart.nix b/modules/misc/xdg-autostart.nix new file mode 100644 index 000000000..f6b8b7e24 --- /dev/null +++ b/modules/misc/xdg-autostart.nix @@ -0,0 +1,40 @@ +{ config, lib, ... }: +let + inherit (builtins) baseNameOf listToAttrs map unsafeDiscardStringContext; + inherit (lib) literalExpression mkEnableOption mkIf mkOption types; + + cfg = config.xdg.autostart; + + /* "/nix/store/x-foo/application.desktop" -> { + name = "autostart/application.desktop"; + value = { source = "/nix/store/x-foo/application.desktop"; }; + } + */ + mapDesktopEntry = entry: { + name = "autostart/${unsafeDiscardStringContext (baseNameOf entry)}"; + value.source = entry; + }; +in { + meta.maintainers = with lib.maintainers; [ Scrumplex ]; + + options.xdg.autostart = { + enable = mkEnableOption "creation of XDG autostart entries"; + + entries = mkOption { + type = with types; listOf path; + description = '' + Paths to desktop files that should be linked to `XDG_CONFIG_HOME/autostart` + ''; + default = [ ]; + example = literalExpression '' + [ + "''${pkgs.evolution}/share/applications/org.gnome.Evolution.desktop" + ] + ''; + }; + }; + + config = mkIf (cfg.enable && cfg.entries != [ ]) { + xdg.configFile = listToAttrs (map mapDesktopEntry cfg.entries); + }; +} diff --git a/modules/misc/xdg-desktop-entries.nix b/modules/misc/xdg-desktop-entries.nix index 1aab6ffe7..1bc3ef6b5 100644 --- a/modules/misc/xdg-desktop-entries.nix +++ b/modules/misc/xdg-desktop-entries.nix @@ -1,13 +1,13 @@ { config, lib, pkgs, ... }: -with lib; - let + inherit (lib) literalExpression mkOption types; + desktopEntry = { imports = [ - (mkRemovedOptionModule [ "extraConfig" ] + (lib.mkRemovedOptionModule [ "extraConfig" ] "The `extraConfig` option of `xdg.desktopEntries` has been removed following a change in Nixpkgs.") - (mkRemovedOptionModule [ "fileValidation" ] + (lib.mkRemovedOptionModule [ "fileValidation" ] "Validation of the desktop file is always enabled.") ]; options = { @@ -172,12 +172,12 @@ let type exec icon comment terminal genericName startupNotify noDisplay prefersNonDefaultGPU actions; desktopName = config.name; - mimeTypes = optionals (config.mimeType != null) config.mimeType; - categories = optionals (config.categories != null) config.categories; + mimeTypes = lib.optionals (config.mimeType != null) config.mimeType; + categories = lib.optionals (config.categories != null) config.categories; extraConfig = config.settings; }; in { - meta.maintainers = [ hm.maintainers.cwyc ]; + meta.maintainers = [ lib.hm.maintainers.cwyc ]; options.xdg.desktopEntries = mkOption { description = '' @@ -203,13 +203,16 @@ in { ''; }; - config = mkIf (config.xdg.desktopEntries != { }) { + config = lib.mkIf (config.xdg.desktopEntries != { }) { assertions = [ - (hm.assertions.assertPlatform "xdg.desktopEntries" pkgs platforms.linux) - ] ++ flatten (catAttrs "assertions" (attrValues config.xdg.desktopEntries)); + (lib.hm.assertions.assertPlatform "xdg.desktopEntries" pkgs + lib.platforms.linux) + ] ++ lib.flatten + (lib.catAttrs "assertions" (lib.attrValues config.xdg.desktopEntries)); - home.packages = (map hiPrio # we need hiPrio to override existing entries - (attrsets.mapAttrsToList makeFile config.xdg.desktopEntries)); + home.packages = + (map lib.hiPrio # we need hiPrio to override existing entries + (lib.attrsets.mapAttrsToList makeFile config.xdg.desktopEntries)); }; } diff --git a/modules/misc/xdg-mime-apps.nix b/modules/misc/xdg-mime-apps.nix index c9fd3e8be..6efa43b11 100644 --- a/modules/misc/xdg-mime-apps.nix +++ b/modules/misc/xdg-mime-apps.nix @@ -1,16 +1,15 @@ { config, lib, pkgs, ... }: -with lib; - let + inherit (lib) mkOption types; cfg = config.xdg.mimeApps; strListOrSingleton = with types; - coercedTo (either (listOf str) str) toList (listOf str); + coercedTo (either (listOf str) str) lib.toList (listOf str); in { - meta.maintainers = with maintainers; [ pacien ]; + meta.maintainers = with lib.maintainers; [ euxane ]; options.xdg.mimeApps = { enable = mkOption { @@ -29,7 +28,7 @@ in { associations.added = mkOption { type = types.attrsOf strListOrSingleton; default = { }; - example = literalExpression '' + example = lib.literalExpression '' { "mimetype1" = [ "foo1.desktop" "foo2.desktop" "foo3.desktop" ]; "mimetype2" = "foo4.desktop"; @@ -56,7 +55,7 @@ in { defaultApplications = mkOption { type = types.attrsOf strListOrSingleton; default = { }; - example = literalExpression '' + example = lib.literalExpression '' { "mimetype1" = [ "default1.desktop" "default2.desktop" ]; } @@ -71,22 +70,22 @@ in { }; }; - config = mkMerge [ + config = lib.mkMerge [ { # Given a package that installs .desktop files in the usual location, # return a mapping from mime types to lists of desktop file names. This is # suitable for use with `xdg.mimeApps.defaultApplications`. lib.xdg.mimeAssociations = let processLines = str: - zipAttrs - (filter (e: e != null) (map processLine (splitString "\n" str))); + lib.zipAttrs (lib.filter (e: e != null) + (map processLine (lib.splitString "\n" str))); processLine = str: let - entry = splitString ";" str; - k = elemAt entry 0; - v = elemAt entry 1; - in if length entry == 2 then { ${k} = v; } else null; + entry = lib.splitString ";" str; + k = lib.elemAt entry 0; + v = lib.elemAt entry 1; + in if lib.length entry == 2 then { ${k} = v; } else null; associations = ps: pkgs.runCommand "mime-assoc" { inherit ps; } '' @@ -100,17 +99,19 @@ in { in p: processLines (builtins.readFile (associations p)); } - (mkIf cfg.enable { - assertions = - [ (hm.assertions.assertPlatform "xdg.mimeApps" pkgs platforms.linux) ]; + (lib.mkIf cfg.enable { + assertions = [ + (lib.hm.assertions.assertPlatform "xdg.mimeApps" pkgs + lib.platforms.linux) + ]; # Deprecated but still used by some applications. xdg.dataFile."applications/mimeapps.list".source = config.xdg.configFile."mimeapps.list".source; xdg.configFile."mimeapps.list".text = - let joinValues = mapAttrs (n: concatStringsSep ";"); - in generators.toINI { } { + let joinValues = lib.mapAttrs (n: lib.concatStringsSep ";"); + in lib.generators.toINI { } { "Added Associations" = joinValues cfg.associations.added; "Removed Associations" = joinValues cfg.associations.removed; "Default Applications" = joinValues cfg.defaultApplications; diff --git a/modules/misc/xdg-mime.nix b/modules/misc/xdg-mime.nix index 09f62aaff..fa22f96df 100644 --- a/modules/misc/xdg-mime.nix +++ b/modules/misc/xdg-mime.nix @@ -1,37 +1,54 @@ { config, lib, pkgs, ... }: -with lib; - let cfg = config.xdg.mime; + inherit (lib) getExe getExe' mkOption types; + in { options = { - xdg.mime.enable = mkOption { - type = types.bool; - default = pkgs.stdenv.hostPlatform.isLinux; - defaultText = - literalExpression "true if host platform is Linux, false otherwise"; - description = '' - Whether to install programs and files to support the - XDG Shared MIME-info specification and XDG MIME Applications - specification at - - and - , - respectively. - ''; + xdg.mime = { + enable = mkOption { + type = types.bool; + default = pkgs.stdenv.hostPlatform.isLinux; + defaultText = lib.literalExpression + "true if host platform is Linux, false otherwise"; + description = '' + Whether to install programs and files to support the + XDG Shared MIME-info specification and XDG MIME Applications + specification at + + and + , + respectively. + ''; + }; + + sharedMimeInfoPackage = mkOption { + type = types.package; + default = pkgs.shared-mime-info; + defaultText = lib.literalExpression "pkgs.shared-mime-info"; + description = "The package to use when running update-mime-database."; + }; + + desktopFileUtilsPackage = mkOption { + type = types.package; + default = pkgs.desktop-file-utils; + defaultText = lib.literalExpression "pkgs.desktop-file-utils"; + description = + "The package to use when running update-desktop-database."; + }; }; }; - - config = mkIf config.xdg.mime.enable { - assertions = - [ (hm.assertions.assertPlatform "xdg.mime" pkgs platforms.linux) ]; + config = lib.mkIf cfg.enable { + assertions = [ + (lib.hm.assertions.assertPlatform "xdg.mime" pkgs lib.platforms.linux) + ]; home.packages = [ # Explicitly install package to provide basic mime types. - pkgs.shared-mime-info + cfg.sharedMimeInfoPackage # Make sure the target directories will be real directories. (pkgs.runCommandLocal "dummy-xdg-mime-dirs1" { } '' @@ -46,15 +63,19 @@ in { if [[ -w $out/share/mime && -w $out/share/mime/packages && -d $out/share/mime/packages ]]; then XDG_DATA_DIRS=$out/share \ PKGSYSTEM_ENABLE_FSYNC=0 \ - ${pkgs.buildPackages.shared-mime-info}/bin/update-mime-database \ - -V $out/share/mime > /dev/null + ${ + getExe + (cfg.sharedMimeInfoPackage.__spliced.buildHost or cfg.sharedMimeInfoPackage) + } -V $out/share/mime > /dev/null fi if [[ -w $out/share/applications ]]; then - ${pkgs.buildPackages.desktop-file-utils}/bin/update-desktop-database \ - $out/share/applications + ${ + getExe' + (cfg.desktopFileUtilsPackage.__spliced.buildHost or cfg.desktopFileUtilsPackage) + "update-desktop-database" + } $out/share/applications fi ''; }; - } diff --git a/modules/misc/xdg-system-dirs.nix b/modules/misc/xdg-system-dirs.nix index 0be5e26d2..d02cff71d 100644 --- a/modules/misc/xdg-system-dirs.nix +++ b/modules/misc/xdg-system-dirs.nix @@ -1,33 +1,32 @@ { config, lib, pkgs, ... }: -with lib; - let + inherit (lib) types; cfg = config.xdg.systemDirs; - configDirs = concatStringsSep ":" cfg.config; + configDirs = lib.concatStringsSep ":" cfg.config; - dataDirs = concatStringsSep ":" cfg.data; + dataDirs = lib.concatStringsSep ":" cfg.data; in { - meta.maintainers = with maintainers; [ tadfisher ]; + meta.maintainers = with lib.maintainers; [ tadfisher ]; options.xdg.systemDirs = { - config = mkOption { + config = lib.mkOption { type = types.listOf types.str; default = [ ]; - example = literalExpression ''[ "/etc/xdg" ]''; + example = lib.literalExpression ''[ "/etc/xdg" ]''; description = '' Directory names to add to {env}`XDG_CONFIG_DIRS` in the user session. ''; }; - data = mkOption { + data = lib.mkOption { type = types.listOf types.str; default = [ ]; - example = literalExpression ''[ "/usr/share" "/usr/local/share" ]''; + example = lib.literalExpression ''[ "/usr/share" "/usr/local/share" ]''; description = '' Directory names to add to {env}`XDG_DATA_DIRS` in the user session. @@ -35,14 +34,15 @@ in { }; }; - config = mkMerge [ - (mkIf (cfg.config != [ ] || cfg.data != [ ]) { + config = lib.mkMerge [ + (lib.mkIf (cfg.config != [ ] || cfg.data != [ ]) { assertions = [ - (hm.assertions.assertPlatform "xdg.systemDirs" pkgs platforms.linux) + (lib.hm.assertions.assertPlatform "xdg.systemDirs" pkgs + lib.platforms.linux) ]; }) - (mkIf (cfg.config != [ ]) { + (lib.mkIf (cfg.config != [ ]) { home.sessionVariables.XDG_CONFIG_DIRS = "${configDirs}\${XDG_CONFIG_DIRS:+:$XDG_CONFIG_DIRS}"; @@ -50,7 +50,7 @@ in { "${configDirs}\${XDG_CONFIG_DIRS:+:$XDG_CONFIG_DIRS}"; }) - (mkIf (cfg.data != [ ]) { + (lib.mkIf (cfg.data != [ ]) { home.sessionVariables.XDG_DATA_DIRS = "${dataDirs}\${XDG_DATA_DIRS:+:$XDG_DATA_DIRS}"; diff --git a/modules/misc/xdg-user-dirs.nix b/modules/misc/xdg-user-dirs.nix index 1198ea039..b693118ad 100644 --- a/modules/misc/xdg-user-dirs.nix +++ b/modules/misc/xdg-user-dirs.nix @@ -1,16 +1,15 @@ { config, lib, pkgs, ... }: -with lib; - let + inherit (lib) literalExpression mkOption types; cfg = config.xdg.userDirs; in { - meta.maintainers = with maintainers; [ pacien ]; + meta.maintainers = with lib.maintainers; [ euxane ]; imports = [ - (mkRenamedOptionModule [ "xdg" "userDirs" "publishShare" ] [ + (lib.mkRenamedOptionModule [ "xdg" "userDirs" "publishShare" ] [ "xdg" "userDirs" "publicShare" @@ -108,11 +107,11 @@ in { }; createDirectories = - mkEnableOption "automatic creation of the XDG user directories"; + lib.mkEnableOption "automatic creation of the XDG user directories"; }; config = let - directories = (filterAttrs (n: v: !isNull v) { + directories = (lib.filterAttrs (n: v: !isNull v) { XDG_DESKTOP_DIR = cfg.desktop; XDG_DOCUMENTS_DIR = cfg.documents; XDG_DOWNLOAD_DIR = cfg.download; @@ -122,24 +121,26 @@ in { XDG_TEMPLATES_DIR = cfg.templates; XDG_VIDEOS_DIR = cfg.videos; }) // cfg.extraConfig; - in mkIf cfg.enable { - assertions = - [ (hm.assertions.assertPlatform "xdg.userDirs" pkgs platforms.linux) ]; + in lib.mkIf cfg.enable { + assertions = [ + (lib.hm.assertions.assertPlatform "xdg.userDirs" pkgs lib.platforms.linux) + ]; xdg.configFile."user-dirs.dirs".text = let # For some reason, these need to be wrapped with quotes to be valid. - wrapped = mapAttrs (_: value: ''"${value}"'') directories; - in generators.toKeyValue { } wrapped; + wrapped = lib.mapAttrs (_: value: ''"${value}"'') directories; + in lib.generators.toKeyValue { } wrapped; xdg.configFile."user-dirs.conf".text = "enabled=False"; home.sessionVariables = directories; - home.activation.createXdgUserDirectories = mkIf cfg.createDirectories (let - directoriesList = attrValues directories; - mkdir = - (dir: ''[[ -L "${dir}" ]] || run mkdir -p $VERBOSE_ARG "${dir}"''); - in lib.hm.dag.entryAfter [ "linkGeneration" ] - (strings.concatMapStringsSep "\n" mkdir directoriesList)); + home.activation.createXdgUserDirectories = lib.mkIf cfg.createDirectories + (let + directoriesList = lib.attrValues directories; + mkdir = + (dir: ''[[ -L "${dir}" ]] || run mkdir -p $VERBOSE_ARG "${dir}"''); + in lib.hm.dag.entryAfter [ "linkGeneration" ] + (lib.strings.concatMapStringsSep "\n" mkdir directoriesList)); }; } diff --git a/modules/misc/xdg.nix b/modules/misc/xdg.nix index a47a33f56..e309462e7 100644 --- a/modules/misc/xdg.nix +++ b/modules/misc/xdg.nix @@ -1,8 +1,7 @@ -{ options, config, lib, pkgs, ... }: - -with lib; +{ config, lib, pkgs, ... }: let + inherit (lib) mkOptionDefault mkIf mkOption types; cfg = config.xdg; @@ -22,7 +21,16 @@ let in { options.xdg = { - enable = mkEnableOption "management of XDG base directories"; + enable = lib.mkEnableOption "management of XDG base directories"; + + cacheFile = mkOption { + type = fileType "xdg.cacheFile" "{var}`xdg.cacheHome`" cfg.cacheHome; + default = { }; + description = '' + Attribute set of files to link into the user's XDG + cache home. + ''; + }; cacheHome = mkOption { type = types.path; @@ -30,6 +38,8 @@ in { apply = toString; description = '' Absolute path to directory holding application caches. + + Sets `XDG_CACHE_HOME` for the user if `xdg.enable` is set `true`. ''; }; @@ -48,6 +58,8 @@ in { apply = toString; description = '' Absolute path to directory holding application configurations. + + Sets `XDG_CONFIG_HOME` for the user if `xdg.enable` is set `true`. ''; }; @@ -67,6 +79,8 @@ in { apply = toString; description = '' Absolute path to directory holding application data. + + Sets `XDG_DATA_HOME` for the user if `xdg.enable` is set `true`. ''; }; @@ -86,11 +100,13 @@ in { apply = toString; description = '' Absolute path to directory holding application states. + + Sets `XDG_STATE_HOME` for the user if `xdg.enable` is set `true`. ''; }; }; - config = mkMerge [ + config = lib.mkMerge [ (let variables = { XDG_CACHE_HOME = cfg.cacheHome; @@ -99,10 +115,10 @@ in { XDG_STATE_HOME = cfg.stateHome; }; in mkIf cfg.enable { - xdg.cacheHome = mkDefault defaultCacheHome; - xdg.configHome = mkDefault defaultConfigHome; - xdg.dataHome = mkDefault defaultDataHome; - xdg.stateHome = mkDefault defaultStateHome; + xdg.cacheHome = mkOptionDefault defaultCacheHome; + xdg.configHome = mkOptionDefault defaultConfigHome; + xdg.dataHome = mkOptionDefault defaultDataHome; + xdg.stateHome = mkOptionDefault defaultStateHome; home.sessionVariables = variables; systemd.user.sessionVariables = @@ -110,31 +126,41 @@ in { }) # Legacy non-deterministic setup. - (mkIf (!cfg.enable && versionOlder config.home.stateVersion "20.09") { + (mkIf (!cfg.enable && lib.versionOlder config.home.stateVersion "20.09") { xdg.cacheHome = - mkDefault (getEnvFallback "XDG_CACHE_HOME" defaultCacheHome); + mkOptionDefault (getEnvFallback "XDG_CACHE_HOME" defaultCacheHome); xdg.configHome = - mkDefault (getEnvFallback "XDG_CONFIG_HOME" defaultConfigHome); - xdg.dataHome = mkDefault (getEnvFallback "XDG_DATA_HOME" defaultDataHome); + mkOptionDefault (getEnvFallback "XDG_CONFIG_HOME" defaultConfigHome); + xdg.dataHome = + mkOptionDefault (getEnvFallback "XDG_DATA_HOME" defaultDataHome); + xdg.stateHome = + mkOptionDefault (getEnvFallback "XDG_STATE_HOME" defaultStateHome); }) # "Modern" deterministic setup. - (mkIf (!cfg.enable && versionAtLeast config.home.stateVersion "20.09") { - xdg.cacheHome = mkDefault defaultCacheHome; - xdg.configHome = mkDefault defaultConfigHome; - xdg.dataHome = mkDefault defaultDataHome; - xdg.stateHome = mkDefault defaultStateHome; + (mkIf (!cfg.enable && lib.versionAtLeast config.home.stateVersion "20.09") { + xdg.cacheHome = mkOptionDefault defaultCacheHome; + xdg.configHome = mkOptionDefault defaultConfigHome; + xdg.dataHome = mkOptionDefault defaultDataHome; + xdg.stateHome = mkOptionDefault defaultStateHome; }) { - home.file = mkMerge [ - (mapAttrs' (name: file: nameValuePair "${cfg.configHome}/${name}" file) + home.file = lib.mkMerge [ + (lib.mapAttrs' + (name: file: lib.nameValuePair "${cfg.cacheHome}/${name}" file) + cfg.cacheFile) + (lib.mapAttrs' + (name: file: lib.nameValuePair "${cfg.configHome}/${name}" file) cfg.configFile) - (mapAttrs' (name: file: nameValuePair "${cfg.dataHome}/${name}" file) + (lib.mapAttrs' + (name: file: lib.nameValuePair "${cfg.dataHome}/${name}" file) cfg.dataFile) - (mapAttrs' (name: file: nameValuePair "${cfg.stateHome}/${name}" file) + (lib.mapAttrs' + (name: file: lib.nameValuePair "${cfg.stateHome}/${name}" file) cfg.stateFile) { "${cfg.cacheHome}/.keep".text = ""; } + { "${cfg.stateHome}/.keep".text = ""; } ]; } ]; diff --git a/modules/misc/xfconf.nix b/modules/misc/xfconf.nix index 087040085..b95413676 100644 --- a/modules/misc/xfconf.nix +++ b/modules/misc/xfconf.nix @@ -1,8 +1,7 @@ { config, lib, pkgs, ... }: -with lib; - let + inherit (lib) mkOption types; cfg = config.xfconf; @@ -51,12 +50,12 @@ let "-s" v ] else if builtins.isList v then - [ "-a" ] ++ concatMap withType v + [ "-a" ] ++ lib.concatMap withType v else throw "unexpected xfconf type: ${builtins.typeOf v}"; in { - meta.maintainers = [ maintainers.chuangzhu ]; + meta.maintainers = [ lib.maintainers.chuangzhu ]; options.xfconf = { enable = mkOption { @@ -81,7 +80,7 @@ in { description = "xfconf settings"; }; default = { }; - example = literalExpression '' + example = lib.literalExpression '' { xfce4-session = { "startup/ssh-agent/enabled" = false; @@ -99,16 +98,16 @@ in { }; }; - config = mkIf (cfg.enable && cfg.settings != { }) { + config = lib.mkIf (cfg.enable && cfg.settings != { }) { assertions = - [ (hm.assertions.assertPlatform "xfconf" pkgs platforms.linux) ]; + [ (lib.hm.assertions.assertPlatform "xfconf" pkgs lib.platforms.linux) ]; - home.activation.xfconfSettings = hm.dag.entryAfter [ "installPackages" ] + home.activation.xfconfSettings = lib.hm.dag.entryAfter [ "installPackages" ] (let mkCommand = channel: property: value: '' run ${pkgs.xfce.xfconf}/bin/xfconf-query \ ${ - escapeShellArgs ([ "-c" channel "-p" "/${property}" ] + lib.escapeShellArgs ([ "-c" channel "-p" "/${property}" ] ++ (if value == null then [ "-r" ] else @@ -116,13 +115,12 @@ in { } ''; - commands = mapAttrsToList - (channel: properties: mapAttrsToList (mkCommand channel) properties) - cfg.settings; + commands = lib.mapAttrsToList (channel: properties: + lib.mapAttrsToList (mkCommand channel) properties) cfg.settings; load = pkgs.writeShellScript "load-xfconf" '' ${config.lib.bash.initHomeManagerLib} - ${concatMapStrings concatStrings commands} + ${lib.concatMapStrings lib.concatStrings commands} ''; in '' if [[ -v DBUS_SESSION_BUS_ADDRESS ]]; then diff --git a/modules/modules.nix b/modules/modules.nix index ed2e177f2..9226ed63b 100644 --- a/modules/modules.nix +++ b/modules/modules.nix @@ -9,8 +9,6 @@ # If disabled, the pkgs attribute passed to this function is used instead. , useNixpkgsModule ? true }: -with lib; - let modules = [ @@ -30,17 +28,21 @@ let ./misc/fontconfig.nix ./misc/gtk.nix ./misc/lib.nix + ./misc/mozilla-messaging-hosts.nix ./misc/news.nix + ./misc/nixgl.nix ./misc/numlock.nix ./misc/pam.nix ./misc/qt.nix ./misc/qt/kconfig.nix + ./misc/shell.nix ./misc/specialisation.nix ./misc/submodule-support.nix ./misc/tmpfiles.nix ./misc/uninstall.nix ./misc/version.nix ./misc/vte.nix + ./misc/xdg-autostart.nix ./misc/xdg-desktop-entries.nix ./misc/xdg-mime-apps.nix ./misc/xdg-mime.nix @@ -51,6 +53,7 @@ let ./misc/xfconf.nix ./programs/abook.nix ./programs/aerc.nix + ./programs/aerospace.nix ./programs/afew.nix ./programs/alacritty.nix ./programs/alot.nix @@ -76,13 +79,16 @@ let ./programs/bun.nix ./programs/carapace.nix ./programs/cava.nix + ./programs/cavalier.nix ./programs/chromium.nix + ./programs/cmus.nix ./programs/command-not-found/command-not-found.nix ./programs/comodoro.nix ./programs/darcs.nix ./programs/dircolors.nix ./programs/direnv.nix ./programs/discocss.nix + ./programs/earthly.nix ./programs/eclipse.nix ./programs/emacs.nix ./programs/eww.nix @@ -92,6 +98,7 @@ let ./programs/feh.nix ./programs/firefox.nix ./programs/fish.nix + ./programs/floorp.nix ./programs/foot.nix ./programs/freetube.nix ./programs/fuzzel.nix @@ -100,8 +107,10 @@ 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-worktree-switcher.nix ./programs/git.nix ./programs/gitui.nix ./programs/gnome-shell.nix @@ -129,6 +138,7 @@ let ./programs/java.nix ./programs/jetbrains-remote.nix ./programs/jq.nix + ./programs/jqp.nix ./programs/jujutsu.nix ./programs/joshuto.nix ./programs/joplin-desktop.nix @@ -140,6 +150,8 @@ let ./programs/khard.nix ./programs/kitty.nix ./programs/kodi.nix + ./programs/kubecolor.nix + ./programs/lapce.nix ./programs/lazygit.nix ./programs/ledger.nix ./programs/less.nix @@ -157,6 +169,7 @@ let ./programs/mercurial.nix ./programs/micro.nix ./programs/mise.nix + ./programs/mods.nix ./programs/mpv.nix ./programs/mr.nix ./programs/msmtp.nix @@ -170,8 +183,10 @@ let ./programs/neovide.nix ./programs/neovim.nix ./programs/newsboat.nix + ./programs/nh.nix ./programs/nheko.nix ./programs/nix-index.nix + ./programs/nix-your-shell.nix ./programs/nnn.nix ./programs/noti.nix ./programs/notmuch.nix @@ -185,6 +200,7 @@ let ./programs/pandoc.nix ./programs/papis.nix ./programs/password-store.nix + ./programs/pay-respects.nix ./programs/pazi.nix ./programs/pet.nix ./programs/pidgin.nix @@ -222,6 +238,7 @@ let ./programs/sqls.nix ./programs/ssh.nix ./programs/starship.nix + ./programs/swayimg.nix ./programs/swaylock.nix ./programs/swayr.nix ./programs/taskwarrior.nix @@ -237,12 +254,15 @@ let ./programs/tmate.nix ./programs/tmux.nix ./programs/tofi.nix + ./programs/todoman.nix ./programs/topgrade.nix ./programs/translate-shell.nix ./programs/urxvt.nix ./programs/vdirsyncer.nix - ./programs/vim.nix + ./programs/vifm.nix ./programs/vim-vint.nix + ./programs/vim.nix + ./programs/vinegar.nix ./programs/vscode.nix ./programs/vscode/haskell.nix ./programs/pywal.nix @@ -252,7 +272,6 @@ let ./programs/wezterm.nix ./programs/wlogout.nix ./programs/wofi.nix - ./programs/wpaperd.nix ./programs/xmobar.nix ./programs/xplr.nix ./programs/yambar.nix @@ -260,6 +279,7 @@ let ./programs/yt-dlp.nix ./programs/z-lua.nix ./programs/zathura.nix + ./programs/zed-editor.nix ./programs/zellij.nix ./programs/zk.nix ./programs/zoxide.nix @@ -284,6 +304,7 @@ let ./services/cliphist.nix ./services/clipman.nix ./services/clipmenu.nix + ./services/clipse.nix ./services/comodoro.nix ./services/conky.nix ./services/copyq.nix @@ -318,8 +339,10 @@ let ./services/keybase.nix ./services/keynav.nix ./services/lieer.nix + ./services/linux-wallpaperengine.nix ./services/listenbrainz-mpd.nix ./services/lorri.nix + ./services/macos-remap-keys ./services/mako.nix ./services/mbsync.nix ./services/megasync.nix @@ -334,6 +357,7 @@ let ./services/nextcloud-client.nix ./services/nix-gc.nix ./services/notify-osd.nix + ./services/ollama.nix ./services/opensnitch-ui.nix ./services/osmscout-server.nix ./services/owncloud-client.nix @@ -346,6 +370,7 @@ let ./services/plan9port.nix ./services/playerctld.nix ./services/plex-mpv-shim.nix + ./services/podman-linux ./services/polybar.nix ./services/poweralertd.nix ./services/psd.nix @@ -361,6 +386,7 @@ let ./services/screen-locker.nix ./services/sctd.nix ./services/signaturepdf.nix + ./services/snixembed.nix ./services/spotifyd.nix ./services/ssh-agent.nix ./services/stalonetray.nix @@ -374,6 +400,7 @@ let ./services/taffybar.nix ./services/tahoe-lafs.nix ./services/taskwarrior-sync.nix + ./services/tldr-update.nix ./services/trayer.nix ./services/trayscale.nix ./services/twmn.nix @@ -392,46 +419,51 @@ let ./services/window-managers/i3-sway/swaynag.nix ./services/window-managers/river.nix ./services/window-managers/spectrwm.nix + ./services/window-managers/wayfire.nix ./services/window-managers/xmonad.nix ./services/wlsunset.nix + ./services/wluma.nix ./services/wob.nix + ./services/wpaperd.nix ./services/xcape.nix ./services/xembed-sni-proxy.nix ./services/xidlehook.nix ./services/xscreensaver.nix ./services/xsettingsd.nix ./services/xsuspender.nix + ./services/yubikey-agent.nix ./systemd.nix ./targets/darwin ./targets/generic-linux.nix + ./wayland.nix ./xresources.nix ./xsession.nix ./misc/nix.nix (pkgs.path + "/nixos/modules/misc/assertions.nix") (pkgs.path + "/nixos/modules/misc/meta.nix") - (mkRemovedOptionModule [ "services" "password-store-sync" ] '' + (lib.mkRemovedOptionModule [ "services" "password-store-sync" ] '' Use services.git-sync instead. '') - (mkRemovedOptionModule [ "services" "keepassx" ] '' + (lib.mkRemovedOptionModule [ "services" "keepassx" ] '' KeePassX is no longer maintained. '') - ] ++ optional useNixpkgsModule ./misc/nixpkgs.nix - ++ optional (!useNixpkgsModule) ./misc/nixpkgs-disabled.nix; + ] ++ lib.optional useNixpkgsModule ./misc/nixpkgs.nix + ++ lib.optional (!useNixpkgsModule) ./misc/nixpkgs-disabled.nix; pkgsModule = { config, ... }: { config = { _module.args.baseModules = modules; _module.args.pkgsPath = lib.mkDefault - (if versionAtLeast config.home.stateVersion "20.09" then + (if lib.versionAtLeast config.home.stateVersion "20.09" then pkgs.path else ); _module.args.pkgs = lib.mkDefault pkgs; _module.check = check; lib = lib.hm; - } // optionalAttrs useNixpkgsModule { - nixpkgs.system = mkDefault pkgs.stdenv.hostPlatform.system; + } // lib.optionalAttrs useNixpkgsModule { + nixpkgs.system = lib.mkDefault pkgs.stdenv.hostPlatform.system; }; }; diff --git a/modules/po/ar.po b/modules/po/ar.po index c2469fa54..4e511ec7b 100644 --- a/modules/po/ar.po +++ b/modules/po/ar.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: Home Manager Modules\n" "Report-Msgid-Bugs-To: https://github.com/nix-community/home-manager/issues\n" -"POT-Creation-Date: 2024-04-17 23:19+0200\n" +"POT-Creation-Date: 2025-01-03 09:09+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" @@ -16,23 +16,23 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: modules/files.nix:191 +#: modules/files.nix:188 msgid "Creating home file links in %s" msgstr "" -#: modules/files.nix:204 +#: modules/files.nix:201 msgid "Cleaning up orphan links from %s" msgstr "" -#: modules/files.nix:220 -msgid "Creating profile generation %s" +#: modules/home-environment.nix:591 +msgid "Creating new profile generation" msgstr "" -#: modules/files.nix:237 -msgid "No change so reusing latest profile generation %s" +#: modules/home-environment.nix:594 +msgid "No change so reusing latest profile generation" msgstr "" -#: modules/home-environment.nix:634 +#: modules/home-environment.nix:643 msgid "" "Oops, Nix failed to install your new Home Manager profile!\n" "\n" @@ -48,7 +48,7 @@ msgid "" "Then try activating your Home Manager configuration again." msgstr "" -#: modules/home-environment.nix:667 +#: modules/home-environment.nix:676 msgid "Activating %s" msgstr "" @@ -60,54 +60,34 @@ msgstr "" msgid "Could not find suitable profile directory, tried %s and %s" msgstr "" -#: modules/lib-bash/activation-init.sh:83 -msgid "Sanity checking oldGenNum and oldGenPath" -msgstr "" - -#: modules/lib-bash/activation-init.sh:86 -msgid "" -"The previous generation number and path are in conflict! These\n" -"must be either both empty or both set but are now set to\n" -"\n" -" '%s' and '%s'\n" -"\n" -"If you don't mind losing previous profile generations then\n" -"the easiest solution is probably to run\n" -"\n" -" rm %s/home-manager*\n" -" rm %s/current-home\n" -"\n" -"and trying home-manager switch again. Good luck!" -msgstr "" - -#: modules/lib-bash/activation-init.sh:127 +#: modules/lib-bash/activation-init.sh:106 msgid "Error: USER is set to \"%s\" but we expect \"%s\"" msgstr "" -#: modules/lib-bash/activation-init.sh:136 +#: modules/lib-bash/activation-init.sh:115 msgid "Error: HOME is set to \"%s\" but we expect \"%s\"" msgstr "" -#: modules/lib-bash/activation-init.sh:153 +#: modules/lib-bash/activation-init.sh:132 msgid "Starting Home Manager activation" msgstr "" -#: modules/lib-bash/activation-init.sh:157 +#: modules/lib-bash/activation-init.sh:136 msgid "Sanity checking Nix" msgstr "" -#: modules/lib-bash/activation-init.sh:170 +#: modules/lib-bash/activation-init.sh:149 msgid "This is a dry run" msgstr "" -#: modules/lib-bash/activation-init.sh:174 +#: modules/lib-bash/activation-init.sh:153 msgid "This is a live run" msgstr "" -#: modules/lib-bash/activation-init.sh:180 +#: modules/lib-bash/activation-init.sh:159 msgid "Using Nix version: %s" msgstr "" -#: modules/lib-bash/activation-init.sh:183 +#: modules/lib-bash/activation-init.sh:162 msgid "Activation variables:" msgstr "" diff --git a/modules/po/bg.po b/modules/po/bg.po new file mode 100644 index 000000000..f2bcc905f --- /dev/null +++ b/modules/po/bg.po @@ -0,0 +1,93 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR Home Manager contributors +# This file is distributed under the same license as the Home Manager Modules package. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: Home Manager Modules\n" +"Report-Msgid-Bugs-To: https://github.com/nix-community/home-manager/issues\n" +"POT-Creation-Date: 2025-01-03 09:09+0100\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: bg\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: modules/files.nix:188 +msgid "Creating home file links in %s" +msgstr "" + +#: modules/files.nix:201 +msgid "Cleaning up orphan links from %s" +msgstr "" + +#: modules/home-environment.nix:591 +msgid "Creating new profile generation" +msgstr "" + +#: modules/home-environment.nix:594 +msgid "No change so reusing latest profile generation" +msgstr "" + +#: modules/home-environment.nix:643 +msgid "" +"Oops, Nix failed to install your new Home Manager profile!\n" +"\n" +"Perhaps there is a conflict with a package that was installed using\n" +"\"%s\"? Try running\n" +"\n" +" %s\n" +"\n" +"and if there is a conflicting package you can remove it with\n" +"\n" +" %s\n" +"\n" +"Then try activating your Home Manager configuration again." +msgstr "" + +#: modules/home-environment.nix:676 +msgid "Activating %s" +msgstr "" + +#: modules/lib-bash/activation-init.sh:22 +msgid "Migrating profile from %s to %s" +msgstr "" + +#: modules/lib-bash/activation-init.sh:54 +msgid "Could not find suitable profile directory, tried %s and %s" +msgstr "" + +#: modules/lib-bash/activation-init.sh:106 +msgid "Error: USER is set to \"%s\" but we expect \"%s\"" +msgstr "" + +#: modules/lib-bash/activation-init.sh:115 +msgid "Error: HOME is set to \"%s\" but we expect \"%s\"" +msgstr "" + +#: modules/lib-bash/activation-init.sh:132 +msgid "Starting Home Manager activation" +msgstr "" + +#: modules/lib-bash/activation-init.sh:136 +msgid "Sanity checking Nix" +msgstr "" + +#: modules/lib-bash/activation-init.sh:149 +msgid "This is a dry run" +msgstr "" + +#: modules/lib-bash/activation-init.sh:153 +msgid "This is a live run" +msgstr "" + +#: modules/lib-bash/activation-init.sh:159 +msgid "Using Nix version: %s" +msgstr "" + +#: modules/lib-bash/activation-init.sh:162 +msgid "Activation variables:" +msgstr "" diff --git a/modules/po/ca.po b/modules/po/ca.po index 5f94ebb76..fde4fece4 100644 --- a/modules/po/ca.po +++ b/modules/po/ca.po @@ -7,9 +7,9 @@ msgid "" msgstr "" "Project-Id-Version: Home Manager Modules\n" "Report-Msgid-Bugs-To: https://github.com/nix-community/home-manager/issues\n" -"POT-Creation-Date: 2024-04-17 23:19+0200\n" -"PO-Revision-Date: 2023-12-10 15:58+0000\n" -"Last-Translator: Nara Díaz Viñolas \n" +"POT-Creation-Date: 2025-01-03 09:09+0100\n" +"PO-Revision-Date: 2025-02-19 21:00+0000\n" +"Last-Translator: Alejandro Masó Bonilla \n" "Language-Team: Catalan \n" "Language: ca\n" @@ -17,25 +17,25 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 5.3-dev\n" +"X-Generator: Weblate 5.10.1-dev\n" -#: modules/files.nix:191 +#: modules/files.nix:188 msgid "Creating home file links in %s" msgstr "Creant enllaços dels fitxers personals a %s" -#: modules/files.nix:204 +#: modules/files.nix:201 msgid "Cleaning up orphan links from %s" msgstr "Netejant enllaços orfes de %s" -#: modules/files.nix:220 -msgid "Creating profile generation %s" -msgstr "Creant generació de perfil %s" +#: modules/home-environment.nix:591 +msgid "Creating new profile generation" +msgstr "Creant una nova generació per al nou perfil" -#: modules/files.nix:237 -msgid "No change so reusing latest profile generation %s" -msgstr "No hi ha canvis, reutilitzant últim perfil generat %s" +#: modules/home-environment.nix:594 +msgid "No change so reusing latest profile generation" +msgstr "No hi ha canvis llavors s'utilitzarà la generació anterior" -#: modules/home-environment.nix:634 +#: modules/home-environment.nix:643 msgid "" "Oops, Nix failed to install your new Home Manager profile!\n" "\n" @@ -55,15 +55,15 @@ msgstr "" "Potser hi ha un conflicte amb un paquet instal·lat mitjançant\n" "\"%s\"? Prova d'executar\n" "\n" -" %s\n" +". . . . %s\n" "\n" "i si hi ha un paquet conflictiu el pots eliminar amb\n" "\n" -" %s\n" +". . . . %s\n" "\n" -"i després provar d'activar la teva configuració de Home Manager de nou." +"Després provar d'activar la teva configuració de Home Manager de nou." -#: modules/home-environment.nix:667 +#: modules/home-environment.nix:676 msgid "Activating %s" msgstr "Activant %s" @@ -76,66 +76,70 @@ msgid "Could not find suitable profile directory, tried %s and %s" msgstr "" "No s'ha pogut trobar un directori de perfils adequat, s'ha provat %s i %s" -#: modules/lib-bash/activation-init.sh:83 -msgid "Sanity checking oldGenNum and oldGenPath" -msgstr "Comprovant oldGenNum i oldGenPath" - -#: modules/lib-bash/activation-init.sh:86 -msgid "" -"The previous generation number and path are in conflict! These\n" -"must be either both empty or both set but are now set to\n" -"\n" -" '%s' and '%s'\n" -"\n" -"If you don't mind losing previous profile generations then\n" -"the easiest solution is probably to run\n" -"\n" -" rm %s/home-manager*\n" -" rm %s/current-home\n" -"\n" -"and trying home-manager switch again. Good luck!" -msgstr "" -"Conflicte entre el número de generació prèvia i el camí! Aquests\n" -"han de ser o bé ambdós buits o definits com a:\n" -"\n" -" '%s' i '%s'\n" -"\n" -"Si no t'importa perdre les generacions de perfil prèvies,\n" -"la solució més fàcil probablement és executar:\n" -"\n" -" rm %s/home-manager*\n" -" rm %s/current-home\n" -"\n" -"i provar home-manager switch de nou. Bona Sort!" - -#: modules/lib-bash/activation-init.sh:127 +#: modules/lib-bash/activation-init.sh:106 msgid "Error: USER is set to \"%s\" but we expect \"%s\"" msgstr "Error: USER està configurat a \"%s\", però s'esperava \"%s\"" -#: modules/lib-bash/activation-init.sh:136 +#: modules/lib-bash/activation-init.sh:115 msgid "Error: HOME is set to \"%s\" but we expect \"%s\"" msgstr "Error: HOME està configurat a \"%s\", però s'esperava \"%s\"" -#: modules/lib-bash/activation-init.sh:153 +#: modules/lib-bash/activation-init.sh:132 msgid "Starting Home Manager activation" -msgstr "Començant activació de Home Manager" +msgstr "Començant l'activació de Home Manager" -#: modules/lib-bash/activation-init.sh:157 +#: modules/lib-bash/activation-init.sh:136 msgid "Sanity checking Nix" msgstr "Comprovant Nix" -#: modules/lib-bash/activation-init.sh:170 +#: modules/lib-bash/activation-init.sh:149 msgid "This is a dry run" msgstr "Execució de simulacre" -#: modules/lib-bash/activation-init.sh:174 +#: modules/lib-bash/activation-init.sh:153 msgid "This is a live run" msgstr "Execució en viu" -#: modules/lib-bash/activation-init.sh:180 +#: modules/lib-bash/activation-init.sh:159 msgid "Using Nix version: %s" -msgstr "Utilitzant versió de Nix: %s" +msgstr "Utilitzant la versió de Nix: %s" -#: modules/lib-bash/activation-init.sh:183 +#: modules/lib-bash/activation-init.sh:162 msgid "Activation variables:" msgstr "Variables d'activació:" + +#~ msgid "Creating profile generation %s" +#~ msgstr "Creant generació de perfil %s" + +#~ msgid "No change so reusing latest profile generation %s" +#~ msgstr "No hi ha canvis, reutilitzant últim perfil generat %s" + +#~ msgid "Sanity checking oldGenNum and oldGenPath" +#~ msgstr "Comprovant oldGenNum i oldGenPath" + +#~ msgid "" +#~ "The previous generation number and path are in conflict! These\n" +#~ "must be either both empty or both set but are now set to\n" +#~ "\n" +#~ " '%s' and '%s'\n" +#~ "\n" +#~ "If you don't mind losing previous profile generations then\n" +#~ "the easiest solution is probably to run\n" +#~ "\n" +#~ " rm %s/home-manager*\n" +#~ " rm %s/current-home\n" +#~ "\n" +#~ "and trying home-manager switch again. Good luck!" +#~ msgstr "" +#~ "Conflicte entre el número de generació prèvia i el camí! Aquests\n" +#~ "han de ser o bé ambdós buits o definits com a:\n" +#~ "\n" +#~ " '%s' i '%s'\n" +#~ "\n" +#~ "Si no t'importa perdre les generacions de perfil prèvies,\n" +#~ "la solució més fàcil probablement és executar:\n" +#~ "\n" +#~ " rm %s/home-manager*\n" +#~ " rm %s/current-home\n" +#~ "\n" +#~ "i provar home-manager switch de nou. Bona Sort!" diff --git a/modules/po/cs.po b/modules/po/cs.po index f2da5bcba..485425172 100644 --- a/modules/po/cs.po +++ b/modules/po/cs.po @@ -7,35 +7,35 @@ msgid "" msgstr "" "Project-Id-Version: Home Manager Modules\n" "Report-Msgid-Bugs-To: https://github.com/nix-community/home-manager/issues\n" -"POT-Creation-Date: 2024-04-17 23:19+0200\n" -"PO-Revision-Date: 2023-12-08 12:04+0000\n" -"Last-Translator: David Houdek \n" +"POT-Creation-Date: 2025-01-03 09:09+0100\n" +"PO-Revision-Date: 2025-01-22 01:25+0000\n" +"Last-Translator: Dark Templar \n" "Language-Team: Czech \n" "Language: cs\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" -"X-Generator: Weblate 5.3-dev\n" +"Plural-Forms: nplurals=3; plural=((n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2);\n" +"X-Generator: Weblate 5.10-dev\n" -#: modules/files.nix:191 +#: modules/files.nix:188 msgid "Creating home file links in %s" msgstr "Vytváření linků na domácí soubory v %s" -#: modules/files.nix:204 +#: modules/files.nix:201 msgid "Cleaning up orphan links from %s" msgstr "Čištění osiřelých linků z %s" -#: modules/files.nix:220 -msgid "Creating profile generation %s" -msgstr "Vytvářím profil generace %s" +#: modules/home-environment.nix:591 +msgid "Creating new profile generation" +msgstr "Vytváření nových generací profilu" -#: modules/files.nix:237 -msgid "No change so reusing latest profile generation %s" -msgstr "Žádná změna, takže bude použita profil poslední generace %s" +#: modules/home-environment.nix:594 +msgid "No change so reusing latest profile generation" +msgstr "" -#: modules/home-environment.nix:634 +#: modules/home-environment.nix:643 msgid "" "Oops, Nix failed to install your new Home Manager profile!\n" "\n" @@ -63,7 +63,7 @@ msgstr "" "\n" "Poté zkuste znova aktivovat vaši Home Manager konfiguraci." -#: modules/home-environment.nix:667 +#: modules/home-environment.nix:676 msgid "Activating %s" msgstr "Aktivuji %s" @@ -75,66 +75,70 @@ msgstr "Migruji profil z %s do %s" msgid "Could not find suitable profile directory, tried %s and %s" msgstr "Nebyl nalezen vhodný adresář profilu, byly zkoušeny %s a %s" -#: modules/lib-bash/activation-init.sh:83 -msgid "Sanity checking oldGenNum and oldGenPath" -msgstr "Kontrola správnosti oldGenNum a oldGenPath" - -#: modules/lib-bash/activation-init.sh:86 -msgid "" -"The previous generation number and path are in conflict! These\n" -"must be either both empty or both set but are now set to\n" -"\n" -" '%s' and '%s'\n" -"\n" -"If you don't mind losing previous profile generations then\n" -"the easiest solution is probably to run\n" -"\n" -" rm %s/home-manager*\n" -" rm %s/current-home\n" -"\n" -"and trying home-manager switch again. Good luck!" -msgstr "" -"Poslední číslo a cesta generace jsou konfliktní! Ty\n" -"musí být oboje buď prázdné, nebo nastaveny, ale nyní jsou nastaveny na\n" -"\n" -"\t'%s' a '%s'\n" -"\n" -"Jestli vám nevadí ztráta předchozích generací profilu, potom\n" -"to nejjednodušší řešení bude nejspíš spustit\n" -"\n" -"\trm %s/home-manager*\n" -"\trm %s/current-home\n" -"\n" -"a zkusit přepínač home‐manager znova. Hodně štěstí!" - -#: modules/lib-bash/activation-init.sh:127 +#: modules/lib-bash/activation-init.sh:106 msgid "Error: USER is set to \"%s\" but we expect \"%s\"" msgstr "Chyba: USER je nastaven na \"%s\", ale očekáváme \"%s\"" -#: modules/lib-bash/activation-init.sh:136 +#: modules/lib-bash/activation-init.sh:115 msgid "Error: HOME is set to \"%s\" but we expect \"%s\"" msgstr "Chyba: HOME je nastaven na \"%s\", ale očekáváme \"%s\"" -#: modules/lib-bash/activation-init.sh:153 +#: modules/lib-bash/activation-init.sh:132 msgid "Starting Home Manager activation" msgstr "Zapínám aktivaci Home Manager" -#: modules/lib-bash/activation-init.sh:157 +#: modules/lib-bash/activation-init.sh:136 msgid "Sanity checking Nix" msgstr "Kontrola správnosti Nix" -#: modules/lib-bash/activation-init.sh:170 +#: modules/lib-bash/activation-init.sh:149 msgid "This is a dry run" msgstr "Toto je zkušební běh" -#: modules/lib-bash/activation-init.sh:174 +#: modules/lib-bash/activation-init.sh:153 msgid "This is a live run" msgstr "Toto je běh na ostro" -#: modules/lib-bash/activation-init.sh:180 +#: modules/lib-bash/activation-init.sh:159 msgid "Using Nix version: %s" msgstr "Používám Nix verze: %s" -#: modules/lib-bash/activation-init.sh:183 +#: modules/lib-bash/activation-init.sh:162 msgid "Activation variables:" msgstr "Aktivační proměnné:" + +#~ msgid "Creating profile generation %s" +#~ msgstr "Vytvářím profil generace %s" + +#~ msgid "No change so reusing latest profile generation %s" +#~ msgstr "Žádná změna, takže bude použita profil poslední generace %s" + +#~ msgid "Sanity checking oldGenNum and oldGenPath" +#~ msgstr "Kontrola správnosti oldGenNum a oldGenPath" + +#~ msgid "" +#~ "The previous generation number and path are in conflict! These\n" +#~ "must be either both empty or both set but are now set to\n" +#~ "\n" +#~ " '%s' and '%s'\n" +#~ "\n" +#~ "If you don't mind losing previous profile generations then\n" +#~ "the easiest solution is probably to run\n" +#~ "\n" +#~ " rm %s/home-manager*\n" +#~ " rm %s/current-home\n" +#~ "\n" +#~ "and trying home-manager switch again. Good luck!" +#~ msgstr "" +#~ "Poslední číslo a cesta generace jsou konfliktní! Ty\n" +#~ "musí být oboje buď prázdné, nebo nastaveny, ale nyní jsou nastaveny na\n" +#~ "\n" +#~ "\t'%s' a '%s'\n" +#~ "\n" +#~ "Jestli vám nevadí ztráta předchozích generací profilu, potom\n" +#~ "to nejjednodušší řešení bude nejspíš spustit\n" +#~ "\n" +#~ "\trm %s/home-manager*\n" +#~ "\trm %s/current-home\n" +#~ "\n" +#~ "a zkusit přepínač home‐manager znova. Hodně štěstí!" diff --git a/modules/po/da.po b/modules/po/da.po index acb466622..c8ec04871 100644 --- a/modules/po/da.po +++ b/modules/po/da.po @@ -7,9 +7,9 @@ msgid "" msgstr "" "Project-Id-Version: Home Manager Modules\n" "Report-Msgid-Bugs-To: https://github.com/nix-community/home-manager/issues\n" -"POT-Creation-Date: 2024-04-17 23:19+0200\n" -"PO-Revision-Date: 2023-09-27 11:02+0000\n" -"Last-Translator: Emil Heilbo \n" +"POT-Creation-Date: 2025-01-03 09:09+0100\n" +"PO-Revision-Date: 2025-01-18 01:23+0000\n" +"Last-Translator: Rasmus Enevoldsen \n" "Language-Team: Danish \n" "Language: da\n" @@ -17,25 +17,25 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 5.1-dev\n" +"X-Generator: Weblate 5.10-dev\n" -#: modules/files.nix:191 +#: modules/files.nix:188 msgid "Creating home file links in %s" msgstr "Opretter hjemme fil links i %s" -#: modules/files.nix:204 +#: modules/files.nix:201 msgid "Cleaning up orphan links from %s" msgstr "Oprydder forældreløse links fra %s" -#: modules/files.nix:220 -msgid "Creating profile generation %s" -msgstr "Opretter profil generation %s" +#: modules/home-environment.nix:591 +msgid "Creating new profile generation" +msgstr "Laver ny profil generation" -#: modules/files.nix:237 -msgid "No change so reusing latest profile generation %s" -msgstr "Ingen ændring, dermed genanvendes seneste profil generation %s" +#: modules/home-environment.nix:594 +msgid "No change so reusing latest profile generation" +msgstr "Ingen ændring, så genbruger den tidligste profil generation" -#: modules/home-environment.nix:634 +#: modules/home-environment.nix:643 msgid "" "Oops, Nix failed to install your new Home Manager profile!\n" "\n" @@ -63,7 +63,7 @@ msgstr "" "\n" "Derefter prøv at aktivere din Home Manager konfiguration igen." -#: modules/home-environment.nix:667 +#: modules/home-environment.nix:676 msgid "Activating %s" msgstr "Aktiverer %s" @@ -75,66 +75,70 @@ msgstr "Migrerer profil fra %s til %s" msgid "Could not find suitable profile directory, tried %s and %s" msgstr "Kunne ikke finde en passende profilmappe, forsøgte %s og %s" -#: modules/lib-bash/activation-init.sh:83 -msgid "Sanity checking oldGenNum and oldGenPath" -msgstr "Tjekker fornuften af oldGenNum og oldGenPath" - -#: modules/lib-bash/activation-init.sh:86 -msgid "" -"The previous generation number and path are in conflict! These\n" -"must be either both empty or both set but are now set to\n" -"\n" -" '%s' and '%s'\n" -"\n" -"If you don't mind losing previous profile generations then\n" -"the easiest solution is probably to run\n" -"\n" -" rm %s/home-manager*\n" -" rm %s/current-home\n" -"\n" -"and trying home-manager switch again. Good luck!" -msgstr "" -"Det forrige generationsnummer og sti er i konflikt! Disse skal\n" -"enten begge være tomme, eller begge være sat, men er nu sat til\n" -"\n" -" '%s' og '%s'\n" -"\n" -"Hvis du ikke har noget mod at miste tidligere profil generationer så\n" -"er den nemmeste løsning nok at køre\n" -"\n" -" rm %s/home-manager*\n" -" rm %s/current-home\n" -"\n" -"og forsøge at køre home-manager switch igen. Held og lykke!" - -#: modules/lib-bash/activation-init.sh:127 +#: modules/lib-bash/activation-init.sh:106 msgid "Error: USER is set to \"%s\" but we expect \"%s\"" msgstr "Fejl: USER er sat til \"%s\", men vi forventer \"%s\"" -#: modules/lib-bash/activation-init.sh:136 +#: modules/lib-bash/activation-init.sh:115 msgid "Error: HOME is set to \"%s\" but we expect \"%s\"" msgstr "Fejl: HOME er sat til \"%s\", men vi forventer \"%s\"" -#: modules/lib-bash/activation-init.sh:153 +#: modules/lib-bash/activation-init.sh:132 msgid "Starting Home Manager activation" msgstr "Starter Home Manager aktivering" -#: modules/lib-bash/activation-init.sh:157 +#: modules/lib-bash/activation-init.sh:136 msgid "Sanity checking Nix" msgstr "Tjekker fornuften af Nix" -#: modules/lib-bash/activation-init.sh:170 +#: modules/lib-bash/activation-init.sh:149 msgid "This is a dry run" msgstr "Dette er en test-kørsel" -#: modules/lib-bash/activation-init.sh:174 +#: modules/lib-bash/activation-init.sh:153 msgid "This is a live run" msgstr "Dette er en direkte kørsel" -#: modules/lib-bash/activation-init.sh:180 +#: modules/lib-bash/activation-init.sh:159 msgid "Using Nix version: %s" msgstr "Bruger Nix version: %s" -#: modules/lib-bash/activation-init.sh:183 +#: modules/lib-bash/activation-init.sh:162 msgid "Activation variables:" msgstr "Aktiveringsvariabler:" + +#~ msgid "Creating profile generation %s" +#~ msgstr "Opretter profil generation %s" + +#~ msgid "No change so reusing latest profile generation %s" +#~ msgstr "Ingen ændring, dermed genanvendes seneste profil generation %s" + +#~ msgid "Sanity checking oldGenNum and oldGenPath" +#~ msgstr "Tjekker fornuften af oldGenNum og oldGenPath" + +#~ msgid "" +#~ "The previous generation number and path are in conflict! These\n" +#~ "must be either both empty or both set but are now set to\n" +#~ "\n" +#~ " '%s' and '%s'\n" +#~ "\n" +#~ "If you don't mind losing previous profile generations then\n" +#~ "the easiest solution is probably to run\n" +#~ "\n" +#~ " rm %s/home-manager*\n" +#~ " rm %s/current-home\n" +#~ "\n" +#~ "and trying home-manager switch again. Good luck!" +#~ msgstr "" +#~ "Det forrige generationsnummer og sti er i konflikt! Disse skal\n" +#~ "enten begge være tomme, eller begge være sat, men er nu sat til\n" +#~ "\n" +#~ " '%s' og '%s'\n" +#~ "\n" +#~ "Hvis du ikke har noget mod at miste tidligere profil generationer så\n" +#~ "er den nemmeste løsning nok at køre\n" +#~ "\n" +#~ " rm %s/home-manager*\n" +#~ " rm %s/current-home\n" +#~ "\n" +#~ "og forsøge at køre home-manager switch igen. Held og lykke!" diff --git a/modules/po/de.po b/modules/po/de.po index 5783cd7d7..18089f237 100644 --- a/modules/po/de.po +++ b/modules/po/de.po @@ -7,9 +7,9 @@ msgid "" msgstr "" "Project-Id-Version: Home Manager Modules\n" "Report-Msgid-Bugs-To: https://github.com/nix-community/home-manager/issues\n" -"POT-Creation-Date: 2024-04-17 23:19+0200\n" -"PO-Revision-Date: 2023-12-29 02:09+0000\n" -"Last-Translator: Peter Pfeufer \n" +"POT-Creation-Date: 2025-01-03 09:09+0100\n" +"PO-Revision-Date: 2025-01-05 15:00+0000\n" +"Last-Translator: programmerlexi \n" "Language-Team: German \n" "Language: de\n" @@ -17,25 +17,25 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 5.4-dev\n" +"X-Generator: Weblate 5.10-dev\n" -#: modules/files.nix:191 +#: modules/files.nix:188 msgid "Creating home file links in %s" msgstr "Erstelle home Dateiverknpfungen in %s" -#: modules/files.nix:204 +#: modules/files.nix:201 msgid "Cleaning up orphan links from %s" msgstr "Bereinige verwaiste Links unter %s" -#: modules/files.nix:220 -msgid "Creating profile generation %s" -msgstr "Erstelle Profilgeneration %s" +#: modules/home-environment.nix:591 +msgid "Creating new profile generation" +msgstr "Erstelle neue Profilgeneration" -#: modules/files.nix:237 -msgid "No change so reusing latest profile generation %s" -msgstr "Keine Änderungen. Benutze daher letzte Profilgeneration %s" +#: modules/home-environment.nix:594 +msgid "No change so reusing latest profile generation" +msgstr "Keine Änderung, verwende letzte Profilgeneration" -#: modules/home-environment.nix:634 +#: modules/home-environment.nix:643 msgid "" "Oops, Nix failed to install your new Home Manager profile!\n" "\n" @@ -64,7 +64,7 @@ msgstr "" "\n" "Versuchen Sie dann, Ihre Home Manager Konfiguration erneut zu aktivieren." -#: modules/home-environment.nix:667 +#: modules/home-environment.nix:676 msgid "Activating %s" msgstr "Aktiviere %s" @@ -78,70 +78,74 @@ msgstr "" "Es konnte kein passendes Profilverzeichnis gefunden werden, %s und %s wurden " "versucht" -#: modules/lib-bash/activation-init.sh:83 -msgid "Sanity checking oldGenNum and oldGenPath" -msgstr "Überprüfe zur Sicherheit oldGenNum und oldGenPath" - -#: modules/lib-bash/activation-init.sh:86 -msgid "" -"The previous generation number and path are in conflict! These\n" -"must be either both empty or both set but are now set to\n" -"\n" -" '%s' and '%s'\n" -"\n" -"If you don't mind losing previous profile generations then\n" -"the easiest solution is probably to run\n" -"\n" -" rm %s/home-manager*\n" -" rm %s/current-home\n" -"\n" -"and trying home-manager switch again. Good luck!" -msgstr "" -"Die vorherige Generationsnummer und -pfad stehen im Konflikt. Es\n" -"müssen entweder beide leer sein oder beide haben den Wert\n" -"\n" -" '%s' und '%s'\n" -"\n" -"Wenn es Ihnen nichts ausmacht frühere Generationen zu verlieren,\n" -"dann ist die einfachste Lösung folgendes auszuführen:\n" -"\n" -" rm %s/home-manager*\n" -" rm %s/current-home\n" -"\n" -"Führen Sie danach 'home-manager switch' aus. Viel Glück!" - -#: modules/lib-bash/activation-init.sh:127 +#: modules/lib-bash/activation-init.sh:106 msgid "Error: USER is set to \"%s\" but we expect \"%s\"" -msgstr "Fehler: USER ist auf \"%s\" gesetzt, aber wir erwarten \"%s\"" +msgstr "Fehler: USER ist auf \"%s\" gesetzt, aber es wird \"%s\" erwartet" + +#: modules/lib-bash/activation-init.sh:115 +msgid "Error: HOME is set to \"%s\" but we expect \"%s\"" +msgstr "Fehler: HOME ist auf \"%s\" gesetzt, aber es wird \"%s\" erwartet" + +#: modules/lib-bash/activation-init.sh:132 +msgid "Starting Home Manager activation" +msgstr "Starte Home-Manager-Aktivierung" #: modules/lib-bash/activation-init.sh:136 -msgid "Error: HOME is set to \"%s\" but we expect \"%s\"" -msgstr "Fehler: HOME ist auf \"%s\" gesetzt, aber wir erwarten \"%s\"" - -#: modules/lib-bash/activation-init.sh:153 -msgid "Starting Home Manager activation" -msgstr "Starte Home Manager Aktivierung" - -#: modules/lib-bash/activation-init.sh:157 msgid "Sanity checking Nix" msgstr "Überprüfe zur Sicherheit Nix" -#: modules/lib-bash/activation-init.sh:170 +#: modules/lib-bash/activation-init.sh:149 msgid "This is a dry run" msgstr "Dies ist ein Probelauf" -#: modules/lib-bash/activation-init.sh:174 +#: modules/lib-bash/activation-init.sh:153 msgid "This is a live run" msgstr "Dies ist kein Probelauf" -#: modules/lib-bash/activation-init.sh:180 +#: modules/lib-bash/activation-init.sh:159 msgid "Using Nix version: %s" msgstr "Nutze Nix Version: %s" -#: modules/lib-bash/activation-init.sh:183 +#: modules/lib-bash/activation-init.sh:162 msgid "Activation variables:" msgstr "Aktivierungsvariablen:" +#~ msgid "Creating profile generation %s" +#~ msgstr "Erstelle Profilgeneration %s" + +#~ msgid "No change so reusing latest profile generation %s" +#~ msgstr "Keine Änderungen. Benutze daher letzte Profilgeneration %s" + +#~ msgid "Sanity checking oldGenNum and oldGenPath" +#~ msgstr "Überprüfe zur Sicherheit oldGenNum und oldGenPath" + +#~ msgid "" +#~ "The previous generation number and path are in conflict! These\n" +#~ "must be either both empty or both set but are now set to\n" +#~ "\n" +#~ " '%s' and '%s'\n" +#~ "\n" +#~ "If you don't mind losing previous profile generations then\n" +#~ "the easiest solution is probably to run\n" +#~ "\n" +#~ " rm %s/home-manager*\n" +#~ " rm %s/current-home\n" +#~ "\n" +#~ "and trying home-manager switch again. Good luck!" +#~ msgstr "" +#~ "Die vorherige Generationsnummer und -pfad stehen im Konflikt. Es\n" +#~ "müssen entweder beide leer sein oder beide haben den Wert\n" +#~ "\n" +#~ " '%s' und '%s'\n" +#~ "\n" +#~ "Wenn es Ihnen nichts ausmacht frühere Generationen zu verlieren,\n" +#~ "dann ist die einfachste Lösung folgendes auszuführen:\n" +#~ "\n" +#~ " rm %s/home-manager*\n" +#~ " rm %s/current-home\n" +#~ "\n" +#~ "Führen Sie danach 'home-manager switch' aus. Viel Glück!" + #~ msgid "" #~ "Oops, nix-env failed to install your new Home Manager profile!\n" #~ "\n" diff --git a/modules/po/es.po b/modules/po/es.po index 0178e6d8b..d10ce440d 100644 --- a/modules/po/es.po +++ b/modules/po/es.po @@ -7,9 +7,9 @@ msgid "" msgstr "" "Project-Id-Version: Home Manager Modules\n" "Report-Msgid-Bugs-To: https://github.com/nix-community/home-manager/issues\n" -"POT-Creation-Date: 2024-04-17 23:19+0200\n" -"PO-Revision-Date: 2023-05-27 12:11+0000\n" -"Last-Translator: gallegonovato \n" +"POT-Creation-Date: 2025-01-03 09:09+0100\n" +"PO-Revision-Date: 2025-01-30 12:43+0000\n" +"Last-Translator: Gavagai53 \n" "Language-Team: Spanish \n" "Language: es\n" @@ -17,25 +17,25 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.18-dev\n" +"X-Generator: Weblate 5.10-dev\n" -#: modules/files.nix:191 +#: modules/files.nix:188 msgid "Creating home file links in %s" msgstr "Creando vínculos del directorio de inicio en %s" -#: modules/files.nix:204 +#: modules/files.nix:201 msgid "Cleaning up orphan links from %s" msgstr "Limpiando vínculos huérfanos de %s" -#: modules/files.nix:220 -msgid "Creating profile generation %s" -msgstr "Creando generación de perfil %s" +#: modules/home-environment.nix:591 +msgid "Creating new profile generation" +msgstr "Creando nueva generación de perfil" -#: modules/files.nix:237 -msgid "No change so reusing latest profile generation %s" -msgstr "No hay cambios, reutilizando la generación más reciente del perfil: %s" +#: modules/home-environment.nix:594 +msgid "No change so reusing latest profile generation" +msgstr "No hubo cambio, así que reusando la última generación de perfil" -#: modules/home-environment.nix:634 +#: modules/home-environment.nix:643 msgid "" "Oops, Nix failed to install your new Home Manager profile!\n" "\n" @@ -63,7 +63,7 @@ msgstr "" "\n" "Y después reintente activar su configuración de Home Manager." -#: modules/home-environment.nix:667 +#: modules/home-environment.nix:676 msgid "Activating %s" msgstr "Activando %s" @@ -77,70 +77,77 @@ msgstr "" "No se ha podido encontrar un directorio de perfiles adecuado, se ha probado " "con %s y %s" -#: modules/lib-bash/activation-init.sh:83 -msgid "Sanity checking oldGenNum and oldGenPath" -msgstr "Chequeando oldGenNum y oldGenPath" - -#: modules/lib-bash/activation-init.sh:86 -msgid "" -"The previous generation number and path are in conflict! These\n" -"must be either both empty or both set but are now set to\n" -"\n" -" '%s' and '%s'\n" -"\n" -"If you don't mind losing previous profile generations then\n" -"the easiest solution is probably to run\n" -"\n" -" rm %s/home-manager*\n" -" rm %s/current-home\n" -"\n" -"and trying home-manager switch again. Good luck!" -msgstr "" -"¡El número y la ruta de la generación anterior están en conflicto! Estos\n" -"ambos deben estar vacíos o ambos configurados pero ahora configurados como\n" -"\n" -" '%s' y '%s'\n" -"\n" -"Si no le importa perder las generaciones de perfiles anteriores, entonces\n" -"la solución más fácil es probablemente ejecutar\n" -"\n" -" rm %s/home-manager*\n" -" rm %s/current-home\n" -"\n" -"y probando el cambio de administrador de casa nuevamente. ¡Buena suerte!" - -#: modules/lib-bash/activation-init.sh:127 +#: modules/lib-bash/activation-init.sh:106 msgid "Error: USER is set to \"%s\" but we expect \"%s\"" msgstr "Error: USER está configurado en \"%s\" pero esperamos \"%s\"" -#: modules/lib-bash/activation-init.sh:136 +#: modules/lib-bash/activation-init.sh:115 msgid "Error: HOME is set to \"%s\" but we expect \"%s\"" msgstr "Error: HOME está configurado en \"%s\" pero esperamos \"%s\"" -#: modules/lib-bash/activation-init.sh:153 +#: modules/lib-bash/activation-init.sh:132 msgid "Starting Home Manager activation" msgstr "Comenzando activación de Home Manager" -#: modules/lib-bash/activation-init.sh:157 +#: modules/lib-bash/activation-init.sh:136 msgid "Sanity checking Nix" msgstr "Chequeando Nix" -#: modules/lib-bash/activation-init.sh:170 +#: modules/lib-bash/activation-init.sh:149 msgid "This is a dry run" msgstr "Ejecución de simulacro" -#: modules/lib-bash/activation-init.sh:174 +#: modules/lib-bash/activation-init.sh:153 msgid "This is a live run" msgstr "Ejecución en vivo" -#: modules/lib-bash/activation-init.sh:180 +#: modules/lib-bash/activation-init.sh:159 msgid "Using Nix version: %s" msgstr "Usando Nix versión %s" -#: modules/lib-bash/activation-init.sh:183 +#: modules/lib-bash/activation-init.sh:162 msgid "Activation variables:" msgstr "Variables de activación:" +#~ msgid "Creating profile generation %s" +#~ msgstr "Creando generación de perfil %s" + +#~ msgid "No change so reusing latest profile generation %s" +#~ msgstr "" +#~ "No hay cambios, reutilizando la generación más reciente del perfil: %s" + +#~ msgid "Sanity checking oldGenNum and oldGenPath" +#~ msgstr "Chequeando oldGenNum y oldGenPath" + +#~ msgid "" +#~ "The previous generation number and path are in conflict! These\n" +#~ "must be either both empty or both set but are now set to\n" +#~ "\n" +#~ " '%s' and '%s'\n" +#~ "\n" +#~ "If you don't mind losing previous profile generations then\n" +#~ "the easiest solution is probably to run\n" +#~ "\n" +#~ " rm %s/home-manager*\n" +#~ " rm %s/current-home\n" +#~ "\n" +#~ "and trying home-manager switch again. Good luck!" +#~ msgstr "" +#~ "¡El número y la ruta de la generación anterior están en conflicto! Estos\n" +#~ "ambos deben estar vacíos o ambos configurados pero ahora configurados " +#~ "como\n" +#~ "\n" +#~ " '%s' y '%s'\n" +#~ "\n" +#~ "Si no le importa perder las generaciones de perfiles anteriores, " +#~ "entonces\n" +#~ "la solución más fácil es probablemente ejecutar\n" +#~ "\n" +#~ " rm %s/home-manager*\n" +#~ " rm %s/current-home\n" +#~ "\n" +#~ "y probando el cambio de administrador de casa nuevamente. ¡Buena suerte!" + #~ msgid "Migrating profiles from %s to %s" #~ msgstr "Migrando perfiles de %s a %s" diff --git a/modules/po/fa.po b/modules/po/fa.po index d39e27a92..24fd3ef6b 100644 --- a/modules/po/fa.po +++ b/modules/po/fa.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: Home Manager Modules\n" "Report-Msgid-Bugs-To: https://github.com/nix-community/home-manager/issues\n" -"POT-Creation-Date: 2024-04-17 23:19+0200\n" +"POT-Creation-Date: 2025-01-03 09:09+0100\n" "PO-Revision-Date: 2024-05-02 10:58+0000\n" "Last-Translator: Keivan \n" "Language-Team: Persian 1;\n" "X-Generator: Weblate 5.5.3-dev\n" -#: modules/files.nix:191 +#: modules/files.nix:188 msgid "Creating home file links in %s" msgstr "" -#: modules/files.nix:204 +#: modules/files.nix:201 msgid "Cleaning up orphan links from %s" msgstr "" -#: modules/files.nix:220 -msgid "Creating profile generation %s" +#: modules/home-environment.nix:591 +msgid "Creating new profile generation" msgstr "" -#: modules/files.nix:237 -msgid "No change so reusing latest profile generation %s" +#: modules/home-environment.nix:594 +msgid "No change so reusing latest profile generation" msgstr "" -#: modules/home-environment.nix:634 +#: modules/home-environment.nix:643 msgid "" "Oops, Nix failed to install your new Home Manager profile!\n" "\n" @@ -51,7 +51,7 @@ msgid "" "Then try activating your Home Manager configuration again." msgstr "" -#: modules/home-environment.nix:667 +#: modules/home-environment.nix:676 msgid "Activating %s" msgstr "" @@ -63,54 +63,34 @@ msgstr "" msgid "Could not find suitable profile directory, tried %s and %s" msgstr "بعد از امتحان کردن %s و %s , دایرکتوری مناسب برای پروفایل یافت نشد" -#: modules/lib-bash/activation-init.sh:83 -msgid "Sanity checking oldGenNum and oldGenPath" -msgstr "" - -#: modules/lib-bash/activation-init.sh:86 -msgid "" -"The previous generation number and path are in conflict! These\n" -"must be either both empty or both set but are now set to\n" -"\n" -" '%s' and '%s'\n" -"\n" -"If you don't mind losing previous profile generations then\n" -"the easiest solution is probably to run\n" -"\n" -" rm %s/home-manager*\n" -" rm %s/current-home\n" -"\n" -"and trying home-manager switch again. Good luck!" -msgstr "" - -#: modules/lib-bash/activation-init.sh:127 +#: modules/lib-bash/activation-init.sh:106 msgid "Error: USER is set to \"%s\" but we expect \"%s\"" msgstr "" -#: modules/lib-bash/activation-init.sh:136 +#: modules/lib-bash/activation-init.sh:115 msgid "Error: HOME is set to \"%s\" but we expect \"%s\"" msgstr "" -#: modules/lib-bash/activation-init.sh:153 +#: modules/lib-bash/activation-init.sh:132 msgid "Starting Home Manager activation" msgstr "" -#: modules/lib-bash/activation-init.sh:157 +#: modules/lib-bash/activation-init.sh:136 msgid "Sanity checking Nix" msgstr "چک کردن پایداری Nix" -#: modules/lib-bash/activation-init.sh:170 +#: modules/lib-bash/activation-init.sh:149 msgid "This is a dry run" msgstr "" -#: modules/lib-bash/activation-init.sh:174 +#: modules/lib-bash/activation-init.sh:153 msgid "This is a live run" msgstr "" -#: modules/lib-bash/activation-init.sh:180 +#: modules/lib-bash/activation-init.sh:159 msgid "Using Nix version: %s" msgstr "" -#: modules/lib-bash/activation-init.sh:183 +#: modules/lib-bash/activation-init.sh:162 msgid "Activation variables:" msgstr "" diff --git a/modules/po/fi.po b/modules/po/fi.po index c16c30807..d52afc1cb 100644 --- a/modules/po/fi.po +++ b/modules/po/fi.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: Home Manager Modules\n" "Report-Msgid-Bugs-To: https://github.com/nix-community/home-manager/issues\n" -"POT-Creation-Date: 2024-04-17 23:19+0200\n" +"POT-Creation-Date: 2025-01-03 09:09+0100\n" "PO-Revision-Date: 2024-05-31 17:09+0000\n" "Last-Translator: jarre johansson \n" "Language-Team: Finnish \n" +"POT-Creation-Date: 2025-01-03 09:09+0100\n" +"PO-Revision-Date: 2025-01-05 15:00+0000\n" +"Last-Translator: Dorian Burgun \n" "Language-Team: French \n" "Language: fr\n" @@ -17,25 +17,25 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n > 1;\n" -"X-Generator: Weblate 5.0-dev\n" +"X-Generator: Weblate 5.10-dev\n" -#: modules/files.nix:191 +#: modules/files.nix:188 msgid "Creating home file links in %s" msgstr "Création des liens de fichiers personnels dans %s" -#: modules/files.nix:204 +#: modules/files.nix:201 msgid "Cleaning up orphan links from %s" msgstr "Nettoyage des liens orphelins de %s" -#: modules/files.nix:220 -msgid "Creating profile generation %s" -msgstr "Création de la génération de profil %s" +#: modules/home-environment.nix:591 +msgid "Creating new profile generation" +msgstr "Création d'une nouvelle génération de profil" -#: modules/files.nix:237 -msgid "No change so reusing latest profile generation %s" -msgstr "Pas de changement, réutilisation du dernier profil génération %s" +#: modules/home-environment.nix:594 +msgid "No change so reusing latest profile generation" +msgstr "Aucun changement, donc réutilisation du dernier profil généré" -#: modules/home-environment.nix:634 +#: modules/home-environment.nix:643 msgid "" "Oops, Nix failed to install your new Home Manager profile!\n" "\n" @@ -63,7 +63,7 @@ msgstr "" "\n" "Après, essayez encore d'activer votre configuration de Home Manager." -#: modules/home-environment.nix:667 +#: modules/home-environment.nix:676 msgid "Activating %s" msgstr "Activation de %s" @@ -75,72 +75,76 @@ msgstr "Migration du profil de %s vers %s" msgid "Could not find suitable profile directory, tried %s and %s" msgstr "Impossible de trouver le dossier de profil approprié, essayé %s et %s" -#: modules/lib-bash/activation-init.sh:83 -msgid "Sanity checking oldGenNum and oldGenPath" -msgstr "Vérification de oldGenNum et oldGenPath" - -#: modules/lib-bash/activation-init.sh:86 -msgid "" -"The previous generation number and path are in conflict! These\n" -"must be either both empty or both set but are now set to\n" -"\n" -" '%s' and '%s'\n" -"\n" -"If you don't mind losing previous profile generations then\n" -"the easiest solution is probably to run\n" -"\n" -" rm %s/home-manager*\n" -" rm %s/current-home\n" -"\n" -"and trying home-manager switch again. Good luck!" -msgstr "" -"Le numéro et le chemin de la génération précédente sont en conflit ! Ils " -"doivent\n" -"être vides ou les deux mis à\n" -"\n" -" '%s' et '%s'\n" -"\n" -"Si ça ne vous dérange pas de perdre les générations précédentes, la solution " -"la plus\n" -"simple est probablement d'exécuter\n" -"\n" -" rm %s/home-manager*\n" -" rm %s/current-home\n" -"\n" -"et de réessayer home-manager switch. Bonne chance !" - -#: modules/lib-bash/activation-init.sh:127 +#: modules/lib-bash/activation-init.sh:106 msgid "Error: USER is set to \"%s\" but we expect \"%s\"" msgstr "Erreur : USER vaut « %s » mais nous attendions « %s »" -#: modules/lib-bash/activation-init.sh:136 +#: modules/lib-bash/activation-init.sh:115 msgid "Error: HOME is set to \"%s\" but we expect \"%s\"" msgstr "Erreur : HOME vaut « %s » mais nous attendions « %s »" -#: modules/lib-bash/activation-init.sh:153 +#: modules/lib-bash/activation-init.sh:132 msgid "Starting Home Manager activation" msgstr "Démarrage de l'activation de Home Manager" -#: modules/lib-bash/activation-init.sh:157 +#: modules/lib-bash/activation-init.sh:136 msgid "Sanity checking Nix" msgstr "Vérification de Nix" -#: modules/lib-bash/activation-init.sh:170 +#: modules/lib-bash/activation-init.sh:149 msgid "This is a dry run" msgstr "Ceci est une fausse activation (essai à blanc)" -#: modules/lib-bash/activation-init.sh:174 +#: modules/lib-bash/activation-init.sh:153 msgid "This is a live run" msgstr "Ceci est une vraie activation" -#: modules/lib-bash/activation-init.sh:180 +#: modules/lib-bash/activation-init.sh:159 msgid "Using Nix version: %s" msgstr "Version de Nix : %s" -#: modules/lib-bash/activation-init.sh:183 +#: modules/lib-bash/activation-init.sh:162 msgid "Activation variables:" msgstr "Variables d'activation :" +#~ msgid "Creating profile generation %s" +#~ msgstr "Création de la génération de profil %s" + +#~ msgid "No change so reusing latest profile generation %s" +#~ msgstr "Pas de changement, réutilisation du dernier profil génération %s" + +#~ msgid "Sanity checking oldGenNum and oldGenPath" +#~ msgstr "Vérification de oldGenNum et oldGenPath" + +#~ msgid "" +#~ "The previous generation number and path are in conflict! These\n" +#~ "must be either both empty or both set but are now set to\n" +#~ "\n" +#~ " '%s' and '%s'\n" +#~ "\n" +#~ "If you don't mind losing previous profile generations then\n" +#~ "the easiest solution is probably to run\n" +#~ "\n" +#~ " rm %s/home-manager*\n" +#~ " rm %s/current-home\n" +#~ "\n" +#~ "and trying home-manager switch again. Good luck!" +#~ msgstr "" +#~ "Le numéro et le chemin de la génération précédente sont en conflit ! Ils " +#~ "doivent\n" +#~ "être vides ou les deux mis à\n" +#~ "\n" +#~ " '%s' et '%s'\n" +#~ "\n" +#~ "Si ça ne vous dérange pas de perdre les générations précédentes, la " +#~ "solution la plus\n" +#~ "simple est probablement d'exécuter\n" +#~ "\n" +#~ " rm %s/home-manager*\n" +#~ " rm %s/current-home\n" +#~ "\n" +#~ "et de réessayer home-manager switch. Bonne chance !" + #~ msgid "" #~ "Oops, nix-env failed to install your new Home Manager profile!\n" #~ "\n" diff --git a/modules/po/hi.po b/modules/po/hi.po index 02a7f8528..e525c1d39 100644 --- a/modules/po/hi.po +++ b/modules/po/hi.po @@ -7,32 +7,35 @@ msgid "" msgstr "" "Project-Id-Version: Home Manager Modules\n" "Report-Msgid-Bugs-To: https://github.com/nix-community/home-manager/issues\n" -"POT-Creation-Date: 2024-04-17 23:19+0200\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"POT-Creation-Date: 2025-01-03 09:09+0100\n" +"PO-Revision-Date: 2024-10-09 14:31+0000\n" +"Last-Translator: Utkarsh Sharma \n" +"Language-Team: Hindi \n" "Language: hi\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n > 1;\n" +"X-Generator: Weblate 5.8-dev\n" -#: modules/files.nix:191 +#: modules/files.nix:188 msgid "Creating home file links in %s" msgstr "" -#: modules/files.nix:204 +#: modules/files.nix:201 msgid "Cleaning up orphan links from %s" +msgstr "%s से ऑर्फे़न लिंक्स मिटाई जा रही है" + +#: modules/home-environment.nix:591 +msgid "Creating new profile generation" msgstr "" -#: modules/files.nix:220 -msgid "Creating profile generation %s" +#: modules/home-environment.nix:594 +msgid "No change so reusing latest profile generation" msgstr "" -#: modules/files.nix:237 -msgid "No change so reusing latest profile generation %s" -msgstr "" - -#: modules/home-environment.nix:634 +#: modules/home-environment.nix:643 msgid "" "Oops, Nix failed to install your new Home Manager profile!\n" "\n" @@ -48,7 +51,7 @@ msgid "" "Then try activating your Home Manager configuration again." msgstr "" -#: modules/home-environment.nix:667 +#: modules/home-environment.nix:676 msgid "Activating %s" msgstr "" @@ -60,54 +63,34 @@ msgstr "" msgid "Could not find suitable profile directory, tried %s and %s" msgstr "" -#: modules/lib-bash/activation-init.sh:83 -msgid "Sanity checking oldGenNum and oldGenPath" -msgstr "" - -#: modules/lib-bash/activation-init.sh:86 -msgid "" -"The previous generation number and path are in conflict! These\n" -"must be either both empty or both set but are now set to\n" -"\n" -" '%s' and '%s'\n" -"\n" -"If you don't mind losing previous profile generations then\n" -"the easiest solution is probably to run\n" -"\n" -" rm %s/home-manager*\n" -" rm %s/current-home\n" -"\n" -"and trying home-manager switch again. Good luck!" -msgstr "" - -#: modules/lib-bash/activation-init.sh:127 +#: modules/lib-bash/activation-init.sh:106 msgid "Error: USER is set to \"%s\" but we expect \"%s\"" msgstr "" -#: modules/lib-bash/activation-init.sh:136 +#: modules/lib-bash/activation-init.sh:115 msgid "Error: HOME is set to \"%s\" but we expect \"%s\"" msgstr "" -#: modules/lib-bash/activation-init.sh:153 +#: modules/lib-bash/activation-init.sh:132 msgid "Starting Home Manager activation" msgstr "" -#: modules/lib-bash/activation-init.sh:157 +#: modules/lib-bash/activation-init.sh:136 msgid "Sanity checking Nix" msgstr "" -#: modules/lib-bash/activation-init.sh:170 +#: modules/lib-bash/activation-init.sh:149 msgid "This is a dry run" msgstr "" -#: modules/lib-bash/activation-init.sh:174 +#: modules/lib-bash/activation-init.sh:153 msgid "This is a live run" msgstr "" -#: modules/lib-bash/activation-init.sh:180 +#: modules/lib-bash/activation-init.sh:159 msgid "Using Nix version: %s" msgstr "" -#: modules/lib-bash/activation-init.sh:183 +#: modules/lib-bash/activation-init.sh:162 msgid "Activation variables:" msgstr "" diff --git a/modules/po/hm-modules.pot b/modules/po/hm-modules.pot index 7a33a805a..174fb3eb7 100644 --- a/modules/po/hm-modules.pot +++ b/modules/po/hm-modules.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: Home Manager Modules\n" "Report-Msgid-Bugs-To: https://github.com/nix-community/home-manager/issues\n" -"POT-Creation-Date: 2024-04-17 23:19+0200\n" +"POT-Creation-Date: 2025-01-03 09:09+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -17,23 +17,23 @@ msgstr "" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" -#: modules/files.nix:191 +#: modules/files.nix:188 msgid "Creating home file links in %s" msgstr "" -#: modules/files.nix:204 +#: modules/files.nix:201 msgid "Cleaning up orphan links from %s" msgstr "" -#: modules/files.nix:220 -msgid "Creating profile generation %s" +#: modules/home-environment.nix:591 +msgid "Creating new profile generation" msgstr "" -#: modules/files.nix:237 -msgid "No change so reusing latest profile generation %s" +#: modules/home-environment.nix:594 +msgid "No change so reusing latest profile generation" msgstr "" -#: modules/home-environment.nix:634 +#: modules/home-environment.nix:643 msgid "" "Oops, Nix failed to install your new Home Manager profile!\n" "\n" @@ -49,7 +49,7 @@ msgid "" "Then try activating your Home Manager configuration again." msgstr "" -#: modules/home-environment.nix:667 +#: modules/home-environment.nix:676 msgid "Activating %s" msgstr "" @@ -61,54 +61,34 @@ msgstr "" msgid "Could not find suitable profile directory, tried %s and %s" msgstr "" -#: modules/lib-bash/activation-init.sh:83 -msgid "Sanity checking oldGenNum and oldGenPath" -msgstr "" - -#: modules/lib-bash/activation-init.sh:86 -msgid "" -"The previous generation number and path are in conflict! These\n" -"must be either both empty or both set but are now set to\n" -"\n" -" '%s' and '%s'\n" -"\n" -"If you don't mind losing previous profile generations then\n" -"the easiest solution is probably to run\n" -"\n" -" rm %s/home-manager*\n" -" rm %s/current-home\n" -"\n" -"and trying home-manager switch again. Good luck!" -msgstr "" - -#: modules/lib-bash/activation-init.sh:127 +#: modules/lib-bash/activation-init.sh:106 msgid "Error: USER is set to \"%s\" but we expect \"%s\"" msgstr "" -#: modules/lib-bash/activation-init.sh:136 +#: modules/lib-bash/activation-init.sh:115 msgid "Error: HOME is set to \"%s\" but we expect \"%s\"" msgstr "" -#: modules/lib-bash/activation-init.sh:153 +#: modules/lib-bash/activation-init.sh:132 msgid "Starting Home Manager activation" msgstr "" -#: modules/lib-bash/activation-init.sh:157 +#: modules/lib-bash/activation-init.sh:136 msgid "Sanity checking Nix" msgstr "" -#: modules/lib-bash/activation-init.sh:170 +#: modules/lib-bash/activation-init.sh:149 msgid "This is a dry run" msgstr "" -#: modules/lib-bash/activation-init.sh:174 +#: modules/lib-bash/activation-init.sh:153 msgid "This is a live run" msgstr "" -#: modules/lib-bash/activation-init.sh:180 +#: modules/lib-bash/activation-init.sh:159 msgid "Using Nix version: %s" msgstr "" -#: modules/lib-bash/activation-init.sh:183 +#: modules/lib-bash/activation-init.sh:162 msgid "Activation variables:" msgstr "" diff --git a/modules/po/hu.po b/modules/po/hu.po index 2b013ccc1..bf09e7ad0 100644 --- a/modules/po/hu.po +++ b/modules/po/hu.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: Home Manager Modules\n" "Report-Msgid-Bugs-To: https://github.com/nix-community/home-manager/issues\n" -"POT-Creation-Date: 2024-04-17 23:19+0200\n" +"POT-Creation-Date: 2025-01-03 09:09+0100\n" "PO-Revision-Date: 2024-09-02 17:09+0000\n" "Last-Translator: Ferenci Ákos \n" "Language-Team: Hungarian \n" "Language-Team: Indonesian \n" "Language-Team: Italian \n" "Language-Team: Japanese \n" "Language-Team: Korean \n" "Language-Team: Lithuanian =20) ? 1 : 2);\n" "X-Generator: Weblate 5.4\n" -#: modules/files.nix:191 +#: modules/files.nix:188 msgid "Creating home file links in %s" msgstr "Kuriamos home failų nuorodos adresu %s" -#: modules/files.nix:204 +#: modules/files.nix:201 #, fuzzy msgid "Cleaning up orphan links from %s" msgstr "Valomos pamestos nuorodos iš %s" -#: modules/files.nix:220 -msgid "Creating profile generation %s" -msgstr "Kuriama profilio generacija %s" +#: modules/home-environment.nix:591 +msgid "Creating new profile generation" +msgstr "" -#: modules/files.nix:237 -msgid "No change so reusing latest profile generation %s" -msgstr "Nėra pakeitimų, naudojama paskutinė profilio generacija %s" +#: modules/home-environment.nix:594 +msgid "No change so reusing latest profile generation" +msgstr "" -#: modules/home-environment.nix:634 +#: modules/home-environment.nix:643 msgid "" "Oops, Nix failed to install your new Home Manager profile!\n" "\n" @@ -65,7 +65,7 @@ msgstr "" "\n" "Tada pabandykite aktyvuoti Home Manager konfigūraciją iš naujo." -#: modules/home-environment.nix:667 +#: modules/home-environment.nix:676 msgid "Activating %s" msgstr "Aktyvuojamas %s" @@ -77,54 +77,40 @@ msgstr "Perkeliamas profilis iš %s į %s" msgid "Could not find suitable profile directory, tried %s and %s" msgstr "Nepavyko rasti tinkamo profilio katalogo, bandyta naudoti %s ir %s" -#: modules/lib-bash/activation-init.sh:83 -msgid "Sanity checking oldGenNum and oldGenPath" -msgstr "" - -#: modules/lib-bash/activation-init.sh:86 -msgid "" -"The previous generation number and path are in conflict! These\n" -"must be either both empty or both set but are now set to\n" -"\n" -" '%s' and '%s'\n" -"\n" -"If you don't mind losing previous profile generations then\n" -"the easiest solution is probably to run\n" -"\n" -" rm %s/home-manager*\n" -" rm %s/current-home\n" -"\n" -"and trying home-manager switch again. Good luck!" -msgstr "" - -#: modules/lib-bash/activation-init.sh:127 +#: modules/lib-bash/activation-init.sh:106 msgid "Error: USER is set to \"%s\" but we expect \"%s\"" msgstr "" -#: modules/lib-bash/activation-init.sh:136 +#: modules/lib-bash/activation-init.sh:115 msgid "Error: HOME is set to \"%s\" but we expect \"%s\"" msgstr "" -#: modules/lib-bash/activation-init.sh:153 +#: modules/lib-bash/activation-init.sh:132 msgid "Starting Home Manager activation" msgstr "Pradedamas Home Manager aktivavymas" -#: modules/lib-bash/activation-init.sh:157 +#: modules/lib-bash/activation-init.sh:136 msgid "Sanity checking Nix" msgstr "Nix tikrinamas" -#: modules/lib-bash/activation-init.sh:170 +#: modules/lib-bash/activation-init.sh:149 msgid "This is a dry run" msgstr "Tai yra sausas vykdymas" -#: modules/lib-bash/activation-init.sh:174 +#: modules/lib-bash/activation-init.sh:153 msgid "This is a live run" msgstr "Tai yra gyvas vykdymas" -#: modules/lib-bash/activation-init.sh:180 +#: modules/lib-bash/activation-init.sh:159 msgid "Using Nix version: %s" msgstr "Naudojama Nix versija: %s" -#: modules/lib-bash/activation-init.sh:183 +#: modules/lib-bash/activation-init.sh:162 msgid "Activation variables:" msgstr "Aktyvavimo kintamieji:" + +#~ msgid "Creating profile generation %s" +#~ msgstr "Kuriama profilio generacija %s" + +#~ msgid "No change so reusing latest profile generation %s" +#~ msgstr "Nėra pakeitimų, naudojama paskutinė profilio generacija %s" diff --git a/modules/po/nb_NO.po b/modules/po/nb_NO.po index b3754af0f..345770d66 100644 --- a/modules/po/nb_NO.po +++ b/modules/po/nb_NO.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: Home Manager Modules\n" "Report-Msgid-Bugs-To: https://github.com/nix-community/home-manager/issues\n" -"POT-Creation-Date: 2024-04-17 23:19+0200\n" +"POT-Creation-Date: 2025-01-03 09:09+0100\n" "PO-Revision-Date: 2024-04-02 21:38+0000\n" "Last-Translator: LilleAila \n" "Language-Team: Norwegian Bokmål \n" "Language-Team: Dutch \n" "Language-Team: Polish =20) ? 1 : 2);\n" "X-Generator: Weblate 5.6-dev\n" -#: modules/files.nix:191 +#: modules/files.nix:188 msgid "Creating home file links in %s" msgstr "Tworzenie dowiązań plików w %s" -#: modules/files.nix:204 +#: modules/files.nix:201 msgid "Cleaning up orphan links from %s" msgstr "Czyszczenie osieroconych linków z %s" -#: modules/files.nix:220 -msgid "Creating profile generation %s" -msgstr "Tworzenie profilu generacji %s" +#: modules/home-environment.nix:591 +msgid "Creating new profile generation" +msgstr "" -#: modules/files.nix:237 -msgid "No change so reusing latest profile generation %s" -msgstr "Brak zmian więc używam ostatniej generacji profilu %s" +#: modules/home-environment.nix:594 +msgid "No change so reusing latest profile generation" +msgstr "" -#: modules/home-environment.nix:634 +#: modules/home-environment.nix:643 msgid "" "Oops, Nix failed to install your new Home Manager profile!\n" "\n" @@ -65,7 +65,7 @@ msgstr "" "\n" "Po czym spróbuj aktywować swoją konfigurację Home Manager jeszcze raz." -#: modules/home-environment.nix:667 +#: modules/home-environment.nix:676 msgid "Activating %s" msgstr "Aktywowanie %s" @@ -77,70 +77,74 @@ msgstr "Migracja profilu z %s do %s" msgid "Could not find suitable profile directory, tried %s and %s" msgstr "Nie można znaleźć odpowiedniego katalogu profilu, próbowano %s i %s" -#: modules/lib-bash/activation-init.sh:83 -msgid "Sanity checking oldGenNum and oldGenPath" -msgstr "Sprawdzanie poprawności oldGenNum i oldGenPath" - -#: modules/lib-bash/activation-init.sh:86 -msgid "" -"The previous generation number and path are in conflict! These\n" -"must be either both empty or both set but are now set to\n" -"\n" -" '%s' and '%s'\n" -"\n" -"If you don't mind losing previous profile generations then\n" -"the easiest solution is probably to run\n" -"\n" -" rm %s/home-manager*\n" -" rm %s/current-home\n" -"\n" -"and trying home-manager switch again. Good luck!" -msgstr "" -"Istnieje konflikt pomiędzy poprzednią generacją i ścieżką! Powinny\n" -"być obie puste lub ustawione, a efektywnie są ustawione na:\n" -"\n" -" '%s' i '%s'\n" -"\n" -"Jeśli możesz sobie pozwolić na utratę poprzednich generacji,\n" -"możesz uruchomić\n" -"\n" -" rm %s/home-manager*\n" -" rm %s/current-home\n" -"\n" -"i spróbować uruchomić home-manager switch raz jeszcze. Powodzenia!" - -#: modules/lib-bash/activation-init.sh:127 +#: modules/lib-bash/activation-init.sh:106 msgid "Error: USER is set to \"%s\" but we expect \"%s\"" msgstr "" -"Błąd: Właściwość USER ma wartość \"%s\" podczas gdy spodziewana wartość to \"" -"%s\"" +"Błąd: Właściwość USER ma wartość \"%s\" podczas gdy spodziewana wartość to " +"\"%s\"" -#: modules/lib-bash/activation-init.sh:136 +#: modules/lib-bash/activation-init.sh:115 msgid "Error: HOME is set to \"%s\" but we expect \"%s\"" msgstr "" -"Błąd: Właściwość HOME ma wartość \"%s\" podczas gdy spodziewana wartość to \"" -"%s\"" +"Błąd: Właściwość HOME ma wartość \"%s\" podczas gdy spodziewana wartość to " +"\"%s\"" -#: modules/lib-bash/activation-init.sh:153 +#: modules/lib-bash/activation-init.sh:132 msgid "Starting Home Manager activation" msgstr "Rozpoczynam aktywację Home Managera" -#: modules/lib-bash/activation-init.sh:157 +#: modules/lib-bash/activation-init.sh:136 msgid "Sanity checking Nix" msgstr "Sprawdzanie poprawności Nix" -#: modules/lib-bash/activation-init.sh:170 +#: modules/lib-bash/activation-init.sh:149 msgid "This is a dry run" msgstr "To jest wykonanie testowe" -#: modules/lib-bash/activation-init.sh:174 +#: modules/lib-bash/activation-init.sh:153 msgid "This is a live run" msgstr "To jest wykonanie właściwe" -#: modules/lib-bash/activation-init.sh:180 +#: modules/lib-bash/activation-init.sh:159 msgid "Using Nix version: %s" msgstr "Używając wersji Nix: %s" -#: modules/lib-bash/activation-init.sh:183 +#: modules/lib-bash/activation-init.sh:162 msgid "Activation variables:" msgstr "Zmienne aktywacyjne:" + +#~ msgid "Creating profile generation %s" +#~ msgstr "Tworzenie profilu generacji %s" + +#~ msgid "No change so reusing latest profile generation %s" +#~ msgstr "Brak zmian więc używam ostatniej generacji profilu %s" + +#~ msgid "Sanity checking oldGenNum and oldGenPath" +#~ msgstr "Sprawdzanie poprawności oldGenNum i oldGenPath" + +#~ msgid "" +#~ "The previous generation number and path are in conflict! These\n" +#~ "must be either both empty or both set but are now set to\n" +#~ "\n" +#~ " '%s' and '%s'\n" +#~ "\n" +#~ "If you don't mind losing previous profile generations then\n" +#~ "the easiest solution is probably to run\n" +#~ "\n" +#~ " rm %s/home-manager*\n" +#~ " rm %s/current-home\n" +#~ "\n" +#~ "and trying home-manager switch again. Good luck!" +#~ msgstr "" +#~ "Istnieje konflikt pomiędzy poprzednią generacją i ścieżką! Powinny\n" +#~ "być obie puste lub ustawione, a efektywnie są ustawione na:\n" +#~ "\n" +#~ " '%s' i '%s'\n" +#~ "\n" +#~ "Jeśli możesz sobie pozwolić na utratę poprzednich generacji,\n" +#~ "możesz uruchomić\n" +#~ "\n" +#~ " rm %s/home-manager*\n" +#~ " rm %s/current-home\n" +#~ "\n" +#~ "i spróbować uruchomić home-manager switch raz jeszcze. Powodzenia!" diff --git a/modules/po/pt.po b/modules/po/pt.po index 9bd5144a8..aea710aa5 100644 --- a/modules/po/pt.po +++ b/modules/po/pt.po @@ -7,9 +7,9 @@ msgid "" msgstr "" "Project-Id-Version: Home Manager Modules\n" "Report-Msgid-Bugs-To: https://github.com/nix-community/home-manager/issues\n" -"POT-Creation-Date: 2024-04-17 23:19+0200\n" -"PO-Revision-Date: 2023-10-19 04:00+0000\n" -"Last-Translator: SrGesus \n" +"POT-Creation-Date: 2025-01-03 09:09+0100\n" +"PO-Revision-Date: 2025-02-07 22:02+0000\n" +"Last-Translator: Bruno Fragoso \n" "Language-Team: Portuguese \n" "Language: pt\n" @@ -17,25 +17,25 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n > 1;\n" -"X-Generator: Weblate 5.1\n" +"X-Generator: Weblate 5.10-dev\n" -#: modules/files.nix:191 +#: modules/files.nix:188 msgid "Creating home file links in %s" msgstr "A criar links simbólicos em %s" -#: modules/files.nix:204 +#: modules/files.nix:201 msgid "Cleaning up orphan links from %s" msgstr "A limpar links órfãos do directório %s" -#: modules/files.nix:220 -msgid "Creating profile generation %s" -msgstr "A criar geração %s para o perfil" +#: modules/home-environment.nix:591 +msgid "Creating new profile generation" +msgstr "Criando nova geração de perfil" -#: modules/files.nix:237 -msgid "No change so reusing latest profile generation %s" -msgstr "Nenhuma mudança, portanto a reusar a última geração %s para o perfil" +#: modules/home-environment.nix:594 +msgid "No change so reusing latest profile generation" +msgstr "Reutilizando última geração de perfil devido a não existirem alterações" -#: modules/home-environment.nix:634 +#: modules/home-environment.nix:643 msgid "" "Oops, Nix failed to install your new Home Manager profile!\n" "\n" @@ -63,7 +63,7 @@ msgstr "" "\n" "E então tente novamente ativar a sua configuração do Home Manager." -#: modules/home-environment.nix:667 +#: modules/home-environment.nix:676 msgid "Activating %s" msgstr "Ativando %s" @@ -77,66 +77,71 @@ msgstr "" "Não foi possível encontrar uma diretoria de perfil apropriada, foi tentado " "%s e %s" -#: modules/lib-bash/activation-init.sh:83 -msgid "Sanity checking oldGenNum and oldGenPath" -msgstr "Revalidando oldGenNum e oldGenPath" - -#: modules/lib-bash/activation-init.sh:86 -msgid "" -"The previous generation number and path are in conflict! These\n" -"must be either both empty or both set but are now set to\n" -"\n" -" '%s' and '%s'\n" -"\n" -"If you don't mind losing previous profile generations then\n" -"the easiest solution is probably to run\n" -"\n" -" rm %s/home-manager*\n" -" rm %s/current-home\n" -"\n" -"and trying home-manager switch again. Good luck!" -msgstr "" -"O número da geração anterior e o caminho não batem! Ambos\n" -"precisam estar ou vazios ou definidos, mas estão definidos como\n" -"\n" -" '%s' e '%s'\n" -"\n" -"Se não se importa de perder gerações de perfis anteriores, então\n" -"a solução mais rápida é provavelmente executar\n" -"\n" -" rm %s/home-manager*\n" -" rm %s/current-home\n" -"\n" -"e tentar executar \"home-manager switch\" de novo. Boa sorte!" - -#: modules/lib-bash/activation-init.sh:127 +#: modules/lib-bash/activation-init.sh:106 msgid "Error: USER is set to \"%s\" but we expect \"%s\"" msgstr "Erro: USER está definido como \"%s\" mas é esperado \"%s\"" -#: modules/lib-bash/activation-init.sh:136 +#: modules/lib-bash/activation-init.sh:115 msgid "Error: HOME is set to \"%s\" but we expect \"%s\"" msgstr "Erro: HOME está definida como \"%s\" mas é esperado \"%s\"" -#: modules/lib-bash/activation-init.sh:153 +#: modules/lib-bash/activation-init.sh:132 msgid "Starting Home Manager activation" msgstr "Iniciando ativação do Home Manager" -#: modules/lib-bash/activation-init.sh:157 +#: modules/lib-bash/activation-init.sh:136 msgid "Sanity checking Nix" msgstr "Revalidando Nix" -#: modules/lib-bash/activation-init.sh:170 +#: modules/lib-bash/activation-init.sh:149 msgid "This is a dry run" msgstr "Essa é uma execução de teste" -#: modules/lib-bash/activation-init.sh:174 +#: modules/lib-bash/activation-init.sh:153 msgid "This is a live run" msgstr "Essa é uma execução de fato" -#: modules/lib-bash/activation-init.sh:180 +#: modules/lib-bash/activation-init.sh:159 msgid "Using Nix version: %s" msgstr "Usando versão do Nix: %s" -#: modules/lib-bash/activation-init.sh:183 +#: modules/lib-bash/activation-init.sh:162 msgid "Activation variables:" msgstr "Variáveis durante ativação:" + +#~ msgid "Creating profile generation %s" +#~ msgstr "A criar geração %s para o perfil" + +#~ msgid "No change so reusing latest profile generation %s" +#~ msgstr "" +#~ "Nenhuma mudança, portanto a reusar a última geração %s para o perfil" + +#~ msgid "Sanity checking oldGenNum and oldGenPath" +#~ msgstr "Revalidando oldGenNum e oldGenPath" + +#~ msgid "" +#~ "The previous generation number and path are in conflict! These\n" +#~ "must be either both empty or both set but are now set to\n" +#~ "\n" +#~ " '%s' and '%s'\n" +#~ "\n" +#~ "If you don't mind losing previous profile generations then\n" +#~ "the easiest solution is probably to run\n" +#~ "\n" +#~ " rm %s/home-manager*\n" +#~ " rm %s/current-home\n" +#~ "\n" +#~ "and trying home-manager switch again. Good luck!" +#~ msgstr "" +#~ "O número da geração anterior e o caminho não batem! Ambos\n" +#~ "precisam estar ou vazios ou definidos, mas estão definidos como\n" +#~ "\n" +#~ " '%s' e '%s'\n" +#~ "\n" +#~ "Se não se importa de perder gerações de perfis anteriores, então\n" +#~ "a solução mais rápida é provavelmente executar\n" +#~ "\n" +#~ " rm %s/home-manager*\n" +#~ " rm %s/current-home\n" +#~ "\n" +#~ "e tentar executar \"home-manager switch\" de novo. Boa sorte!" diff --git a/modules/po/pt_BR.po b/modules/po/pt_BR.po index 83d01927c..09b147dae 100644 --- a/modules/po/pt_BR.po +++ b/modules/po/pt_BR.po @@ -7,11 +7,11 @@ msgid "" msgstr "" "Project-Id-Version: Home Manager Modules\n" "Report-Msgid-Bugs-To: https://github.com/nix-community/home-manager/issues\n" -"POT-Creation-Date: 2024-04-17 23:19+0200\n" +"POT-Creation-Date: 2025-01-03 09:09+0100\n" "PO-Revision-Date: 2024-04-19 17:07+0000\n" "Last-Translator: Felipe Silva \n" -"Language-Team: Portuguese (Brazil) \n" +"Language-Team: Portuguese (Brazil) \n" "Language: pt_BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -19,23 +19,23 @@ msgstr "" "Plural-Forms: nplurals=2; plural=n > 1;\n" "X-Generator: Weblate 5.5-dev\n" -#: modules/files.nix:191 +#: modules/files.nix:188 msgid "Creating home file links in %s" msgstr "Criando links simbólicos em %s" -#: modules/files.nix:204 +#: modules/files.nix:201 msgid "Cleaning up orphan links from %s" msgstr "Limpando links órfãos de %s" -#: modules/files.nix:220 -msgid "Creating profile generation %s" -msgstr "Criando perfil de geração %s" +#: modules/home-environment.nix:591 +msgid "Creating new profile generation" +msgstr "" -#: modules/files.nix:237 -msgid "No change so reusing latest profile generation %s" -msgstr "Nenhuma mudança, portanto reusando a última geração %s para o perfil" +#: modules/home-environment.nix:594 +msgid "No change so reusing latest profile generation" +msgstr "" -#: modules/home-environment.nix:634 +#: modules/home-environment.nix:643 msgid "" "Oops, Nix failed to install your new Home Manager profile!\n" "\n" @@ -63,7 +63,7 @@ msgstr "" "\n" "E então tente novamente ativar a sua configuração do Home Manager." -#: modules/home-environment.nix:667 +#: modules/home-environment.nix:676 msgid "Activating %s" msgstr "Ativando %s" @@ -76,66 +76,71 @@ msgid "Could not find suitable profile directory, tried %s and %s" msgstr "" "Não foi possível encontrar um diretório de perfil apropriado, tentou %s e %s" -#: modules/lib-bash/activation-init.sh:83 -msgid "Sanity checking oldGenNum and oldGenPath" -msgstr "Revalidando oldGenNum e oldGenPath" - -#: modules/lib-bash/activation-init.sh:86 -msgid "" -"The previous generation number and path are in conflict! These\n" -"must be either both empty or both set but are now set to\n" -"\n" -" '%s' and '%s'\n" -"\n" -"If you don't mind losing previous profile generations then\n" -"the easiest solution is probably to run\n" -"\n" -" rm %s/home-manager*\n" -" rm %s/current-home\n" -"\n" -"and trying home-manager switch again. Good luck!" -msgstr "" -"O número da geração anterior e o caminho não batem! Ambos\n" -"precisam estar ou vazios ou definidos, mas estão definidos como\n" -"\n" -" '%s' e '%s'\n" -"\n" -"Se você não se importa de perder gerações de perfis anteriores, então\n" -"a solução mais rápida é provavelmente rodar\n" -"\n" -" rm %s/home-manager*\n" -" rm %s/current-home\n" -"\n" -"e tentar rodar \"home-manager switch\" de novo. Boa sorte!" - -#: modules/lib-bash/activation-init.sh:127 +#: modules/lib-bash/activation-init.sh:106 msgid "Error: USER is set to \"%s\" but we expect \"%s\"" msgstr "Erro: USER está definido como \"%s\" mas o esperado é \"%s\"" -#: modules/lib-bash/activation-init.sh:136 +#: modules/lib-bash/activation-init.sh:115 msgid "Error: HOME is set to \"%s\" but we expect \"%s\"" msgstr "Erro: HOME está definido como \"%s\" mas o esperado é \"%s\"" -#: modules/lib-bash/activation-init.sh:153 +#: modules/lib-bash/activation-init.sh:132 msgid "Starting Home Manager activation" msgstr "Iniciando ativação do Home Manager" -#: modules/lib-bash/activation-init.sh:157 +#: modules/lib-bash/activation-init.sh:136 msgid "Sanity checking Nix" msgstr "Revalidando Nix" -#: modules/lib-bash/activation-init.sh:170 +#: modules/lib-bash/activation-init.sh:149 msgid "This is a dry run" msgstr "Essa é uma execução de teste" -#: modules/lib-bash/activation-init.sh:174 +#: modules/lib-bash/activation-init.sh:153 msgid "This is a live run" msgstr "Essa é uma execução de fato" -#: modules/lib-bash/activation-init.sh:180 +#: modules/lib-bash/activation-init.sh:159 msgid "Using Nix version: %s" msgstr "Usando versão do Nix: %s" -#: modules/lib-bash/activation-init.sh:183 +#: modules/lib-bash/activation-init.sh:162 msgid "Activation variables:" msgstr "Variáveis durante ativação:" + +#~ msgid "Creating profile generation %s" +#~ msgstr "Criando perfil de geração %s" + +#~ msgid "No change so reusing latest profile generation %s" +#~ msgstr "" +#~ "Nenhuma mudança, portanto reusando a última geração %s para o perfil" + +#~ msgid "Sanity checking oldGenNum and oldGenPath" +#~ msgstr "Revalidando oldGenNum e oldGenPath" + +#~ msgid "" +#~ "The previous generation number and path are in conflict! These\n" +#~ "must be either both empty or both set but are now set to\n" +#~ "\n" +#~ " '%s' and '%s'\n" +#~ "\n" +#~ "If you don't mind losing previous profile generations then\n" +#~ "the easiest solution is probably to run\n" +#~ "\n" +#~ " rm %s/home-manager*\n" +#~ " rm %s/current-home\n" +#~ "\n" +#~ "and trying home-manager switch again. Good luck!" +#~ msgstr "" +#~ "O número da geração anterior e o caminho não batem! Ambos\n" +#~ "precisam estar ou vazios ou definidos, mas estão definidos como\n" +#~ "\n" +#~ " '%s' e '%s'\n" +#~ "\n" +#~ "Se você não se importa de perder gerações de perfis anteriores, então\n" +#~ "a solução mais rápida é provavelmente rodar\n" +#~ "\n" +#~ " rm %s/home-manager*\n" +#~ " rm %s/current-home\n" +#~ "\n" +#~ "e tentar rodar \"home-manager switch\" de novo. Boa sorte!" diff --git a/modules/po/ro.po b/modules/po/ro.po index d817496a7..cfdb24b9e 100644 --- a/modules/po/ro.po +++ b/modules/po/ro.po @@ -7,9 +7,9 @@ msgid "" msgstr "" "Project-Id-Version: Home Manager Modules\n" "Report-Msgid-Bugs-To: https://github.com/nix-community/home-manager/issues\n" -"POT-Creation-Date: 2024-04-17 23:19+0200\n" -"PO-Revision-Date: 2023-08-11 19:51+0000\n" -"Last-Translator: HeartBlin913861820c094e37 \n" +"POT-Creation-Date: 2025-01-03 09:09+0100\n" +"PO-Revision-Date: 2024-10-13 22:15+0000\n" +"Last-Translator: AtomicDude \n" "Language-Team: Romanian \n" "Language: ro\n" @@ -18,25 +18,25 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=n==1 ? 0 : (n==0 || (n%100 > 0 && n%100 < " "20)) ? 1 : 2;\n" -"X-Generator: Weblate 5.0-dev\n" +"X-Generator: Weblate 5.8-dev\n" -#: modules/files.nix:191 +#: modules/files.nix:188 msgid "Creating home file links in %s" msgstr "Se creează legături ale fișierelor personale în %s" -#: modules/files.nix:204 +#: modules/files.nix:201 msgid "Cleaning up orphan links from %s" -msgstr "Se curăță legăturiile orfane din %s" +msgstr "Se curăță legăturile orfane din %s" -#: modules/files.nix:220 -msgid "Creating profile generation %s" -msgstr "Se creează generația %s a profilului" +#: modules/home-environment.nix:591 +msgid "Creating new profile generation" +msgstr "" -#: modules/files.nix:237 -msgid "No change so reusing latest profile generation %s" -msgstr "Nicio schimbare, se reutilizează ultimul profil generat %s" +#: modules/home-environment.nix:594 +msgid "No change so reusing latest profile generation" +msgstr "" -#: modules/home-environment.nix:634 +#: modules/home-environment.nix:643 msgid "" "Oops, Nix failed to install your new Home Manager profile!\n" "\n" @@ -64,7 +64,7 @@ msgstr "" "\n" "Apoi încearcă să activați configurația ta Home Manager din nou." -#: modules/home-environment.nix:667 +#: modules/home-environment.nix:676 msgid "Activating %s" msgstr "Se activează %s" @@ -77,67 +77,71 @@ msgid "Could not find suitable profile directory, tried %s and %s" msgstr "" "Nu s-a putut găsi un director cu un profil potrivit, s-a încercat %s și %s" -#: modules/lib-bash/activation-init.sh:83 -msgid "Sanity checking oldGenNum and oldGenPath" -msgstr "Se verifică corectitudinea oldGenNum și oldGenPath" - -#: modules/lib-bash/activation-init.sh:86 -msgid "" -"The previous generation number and path are in conflict! These\n" -"must be either both empty or both set but are now set to\n" -"\n" -" '%s' and '%s'\n" -"\n" -"If you don't mind losing previous profile generations then\n" -"the easiest solution is probably to run\n" -"\n" -" rm %s/home-manager*\n" -" rm %s/current-home\n" -"\n" -"and trying home-manager switch again. Good luck!" -msgstr "" -"Numărul generației anterioare și calea sunt în conflict! Acestea\n" -"trebuie să fie ambele goale sau ambele setate, dar acum sunt setate la\n" -"\n" -" '%s' și '%s'\n" -"\n" -"Dacă nu vă deranjează pierderea generațiilor anterioare de profiluri, " -"atunci\n" -"cea mai ușoară soluție ar fi să rulezi\n" -"\n" -" rm %s/home-manager*\n" -" rm %s/current-home\n" -"\n" -"și să încerci să rulezi home-manager switch din nou. Mult noroc!" - -#: modules/lib-bash/activation-init.sh:127 +#: modules/lib-bash/activation-init.sh:106 msgid "Error: USER is set to \"%s\" but we expect \"%s\"" msgstr "Eroare: USER este setat la \"%s\", dar noi ne așteptam la \"%s\"" -#: modules/lib-bash/activation-init.sh:136 +#: modules/lib-bash/activation-init.sh:115 msgid "Error: HOME is set to \"%s\" but we expect \"%s\"" msgstr "Eroare: HOME este setat la \"%s\", dar noi ne așteptam la \"%s\"" -#: modules/lib-bash/activation-init.sh:153 +#: modules/lib-bash/activation-init.sh:132 msgid "Starting Home Manager activation" msgstr "Se pornește activarea Home Managerului" -#: modules/lib-bash/activation-init.sh:157 +#: modules/lib-bash/activation-init.sh:136 msgid "Sanity checking Nix" msgstr "Se verifică corectitudinea Nix" -#: modules/lib-bash/activation-init.sh:170 +#: modules/lib-bash/activation-init.sh:149 msgid "This is a dry run" msgstr "Aceasta este o rulare simulată" -#: modules/lib-bash/activation-init.sh:174 +#: modules/lib-bash/activation-init.sh:153 msgid "This is a live run" msgstr "Aceasta este o rulare directă" -#: modules/lib-bash/activation-init.sh:180 +#: modules/lib-bash/activation-init.sh:159 msgid "Using Nix version: %s" msgstr "Folosind versiunea Nix: %s" -#: modules/lib-bash/activation-init.sh:183 +#: modules/lib-bash/activation-init.sh:162 msgid "Activation variables:" msgstr "Variabile de activație:" + +#~ msgid "Creating profile generation %s" +#~ msgstr "Se creează generația %s a profilului" + +#~ msgid "No change so reusing latest profile generation %s" +#~ msgstr "Nicio schimbare, se reutilizează ultimul profil generat %s" + +#~ msgid "Sanity checking oldGenNum and oldGenPath" +#~ msgstr "Se verifică corectitudinea oldGenNum și oldGenPath" + +#~ msgid "" +#~ "The previous generation number and path are in conflict! These\n" +#~ "must be either both empty or both set but are now set to\n" +#~ "\n" +#~ " '%s' and '%s'\n" +#~ "\n" +#~ "If you don't mind losing previous profile generations then\n" +#~ "the easiest solution is probably to run\n" +#~ "\n" +#~ " rm %s/home-manager*\n" +#~ " rm %s/current-home\n" +#~ "\n" +#~ "and trying home-manager switch again. Good luck!" +#~ msgstr "" +#~ "Numărul generației anterioare și calea sunt în conflict! Acestea\n" +#~ "trebuie să fie ambele goale sau ambele setate, dar acum sunt setate la\n" +#~ "\n" +#~ " '%s' și '%s'\n" +#~ "\n" +#~ "Dacă nu vă deranjează pierderea generațiilor anterioare de profiluri, " +#~ "atunci\n" +#~ "cea mai ușoară soluție ar fi să rulezi\n" +#~ "\n" +#~ " rm %s/home-manager*\n" +#~ " rm %s/current-home\n" +#~ "\n" +#~ "și să încerci să rulezi home-manager switch din nou. Mult noroc!" diff --git a/modules/po/ru.po b/modules/po/ru.po index 432da018d..271de0d68 100644 --- a/modules/po/ru.po +++ b/modules/po/ru.po @@ -7,36 +7,36 @@ msgid "" msgstr "" "Project-Id-Version: Home Manager Modules\n" "Report-Msgid-Bugs-To: https://github.com/nix-community/home-manager/issues\n" -"POT-Creation-Date: 2024-04-17 23:19+0200\n" -"PO-Revision-Date: 2023-12-11 16:06+0000\n" -"Last-Translator: Blezz Rot \n" +"POT-Creation-Date: 2025-01-03 09:09+0100\n" +"PO-Revision-Date: 2025-01-31 17:29+0000\n" +"Last-Translator: Vladimir \n" "Language-Team: Russian \n" "Language: ru\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && " -"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" -"X-Generator: Weblate 5.3-dev\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && " +"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" +"X-Generator: Weblate 5.10-dev\n" -#: modules/files.nix:191 +#: modules/files.nix:188 msgid "Creating home file links in %s" msgstr "Создаю ссылки в домашней директории %s" -#: modules/files.nix:204 +#: modules/files.nix:201 msgid "Cleaning up orphan links from %s" msgstr "Удаляю устаревшие ссылки из %s" -#: modules/files.nix:220 -msgid "Creating profile generation %s" -msgstr "Создаю профиль в поколении %s" +#: modules/home-environment.nix:591 +msgid "Creating new profile generation" +msgstr "Создание нового поколения профиля" -#: modules/files.nix:237 -msgid "No change so reusing latest profile generation %s" -msgstr "Изменений нет, переиспользую профиль в последнем поколении %s" +#: modules/home-environment.nix:594 +msgid "No change so reusing latest profile generation" +msgstr "Изменений нет, повторно исползуем последнее поколение профиля" -#: modules/home-environment.nix:634 +#: modules/home-environment.nix:643 msgid "" "Oops, Nix failed to install your new Home Manager profile!\n" "\n" @@ -64,7 +64,7 @@ msgstr "" "\n" "После попробуйте активировать конфигурацию снова." -#: modules/home-environment.nix:667 +#: modules/home-environment.nix:676 msgid "Activating %s" msgstr "Активирую %s" @@ -76,71 +76,75 @@ msgstr "Переношу профиль из %s в %s" msgid "Could not find suitable profile directory, tried %s and %s" msgstr "Не найдена подходящая директория профиля, пробовали %s и %s" -#: modules/lib-bash/activation-init.sh:83 -msgid "Sanity checking oldGenNum and oldGenPath" -msgstr "Проверка oldGenNum и oldGenPath" - -#: modules/lib-bash/activation-init.sh:86 -msgid "" -"The previous generation number and path are in conflict! These\n" -"must be either both empty or both set but are now set to\n" -"\n" -" '%s' and '%s'\n" -"\n" -"If you don't mind losing previous profile generations then\n" -"the easiest solution is probably to run\n" -"\n" -" rm %s/home-manager*\n" -" rm %s/current-home\n" -"\n" -"and trying home-manager switch again. Good luck!" -msgstr "" -"Обнаружен конфликт между номером и расположением предыдущего поколения!\n" -"Обе переменные должны иметь значения либо быть пустыми, но следующие " -"значения:\n" -"\n" -" '%s' and '%s'\n" -"\n" -"Если вы не возражаете потерять предыдущие поколения профиля,\n" -"наиболее простым решением будет выполнение\n" -"\n" -" rm %s/home-manager*\n" -" rm %s/current-home\n" -"\n" -"и повторный запуск 'home-manager switch'. Удачи!" - -#: modules/lib-bash/activation-init.sh:127 +#: modules/lib-bash/activation-init.sh:106 msgid "Error: USER is set to \"%s\" but we expect \"%s\"" msgstr "Ошибка: USER установлена в \"%s\", но ожидается \"%s\"" -#: modules/lib-bash/activation-init.sh:136 +#: modules/lib-bash/activation-init.sh:115 msgid "Error: HOME is set to \"%s\" but we expect \"%s\"" msgstr "Ошибка: HOME установлена в \"%s\", но ожидается \"%s\"" -#: modules/lib-bash/activation-init.sh:153 +#: modules/lib-bash/activation-init.sh:132 msgid "Starting Home Manager activation" msgstr "Начинаю активацию Home Manager" -#: modules/lib-bash/activation-init.sh:157 +#: modules/lib-bash/activation-init.sh:136 msgid "Sanity checking Nix" msgstr "Проверка работоспособности Nix" -#: modules/lib-bash/activation-init.sh:170 +#: modules/lib-bash/activation-init.sh:149 msgid "This is a dry run" msgstr "Это пробный запуск" -#: modules/lib-bash/activation-init.sh:174 +#: modules/lib-bash/activation-init.sh:153 msgid "This is a live run" msgstr "Это реальный запуск" -#: modules/lib-bash/activation-init.sh:180 +#: modules/lib-bash/activation-init.sh:159 msgid "Using Nix version: %s" msgstr "Использую Nix версии: %s" -#: modules/lib-bash/activation-init.sh:183 +#: modules/lib-bash/activation-init.sh:162 msgid "Activation variables:" msgstr "Переменные для активации:" +#~ msgid "Creating profile generation %s" +#~ msgstr "Создаю профиль в поколении %s" + +#~ msgid "No change so reusing latest profile generation %s" +#~ msgstr "Изменений нет, переиспользую профиль в последнем поколении %s" + +#~ msgid "Sanity checking oldGenNum and oldGenPath" +#~ msgstr "Проверка oldGenNum и oldGenPath" + +#~ msgid "" +#~ "The previous generation number and path are in conflict! These\n" +#~ "must be either both empty or both set but are now set to\n" +#~ "\n" +#~ " '%s' and '%s'\n" +#~ "\n" +#~ "If you don't mind losing previous profile generations then\n" +#~ "the easiest solution is probably to run\n" +#~ "\n" +#~ " rm %s/home-manager*\n" +#~ " rm %s/current-home\n" +#~ "\n" +#~ "and trying home-manager switch again. Good luck!" +#~ msgstr "" +#~ "Обнаружен конфликт между номером и расположением предыдущего поколения!\n" +#~ "Обе переменные должны иметь значения либо быть пустыми, но следующие " +#~ "значения:\n" +#~ "\n" +#~ " '%s' and '%s'\n" +#~ "\n" +#~ "Если вы не возражаете потерять предыдущие поколения профиля,\n" +#~ "наиболее простым решением будет выполнение\n" +#~ "\n" +#~ " rm %s/home-manager*\n" +#~ " rm %s/current-home\n" +#~ "\n" +#~ "и повторный запуск 'home-manager switch'. Удачи!" + #~ msgid "" #~ "Oops, nix-env failed to install your new Home Manager profile!\n" #~ "\n" diff --git a/modules/po/sv.po b/modules/po/sv.po index 266a84d8d..69c910b01 100644 --- a/modules/po/sv.po +++ b/modules/po/sv.po @@ -7,9 +7,9 @@ msgid "" msgstr "" "Project-Id-Version: Home Manager Modules\n" "Report-Msgid-Bugs-To: https://github.com/nix-community/home-manager/issues\n" -"POT-Creation-Date: 2024-04-17 23:19+0200\n" -"PO-Revision-Date: 2023-05-27 12:11+0000\n" -"Last-Translator: Robert Helgesson \n" +"POT-Creation-Date: 2025-01-03 09:09+0100\n" +"PO-Revision-Date: 2025-02-08 08:17+0000\n" +"Last-Translator: bittin1ddc447d824349b2 \n" "Language-Team: Swedish \n" "Language: sv\n" @@ -17,25 +17,25 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.18-dev\n" +"X-Generator: Weblate 5.10-dev\n" -#: modules/files.nix:191 +#: modules/files.nix:188 msgid "Creating home file links in %s" msgstr "Skapar hemfil-länkar i %s" -#: modules/files.nix:204 +#: modules/files.nix:201 msgid "Cleaning up orphan links from %s" msgstr "Rensar bort överflödiga länkar från %s" -#: modules/files.nix:220 -msgid "Creating profile generation %s" -msgstr "Skapar profil för generation %s" +#: modules/home-environment.nix:591 +msgid "Creating new profile generation" +msgstr "Skapar ny profilgeneration" -#: modules/files.nix:237 -msgid "No change so reusing latest profile generation %s" -msgstr "Ingen förändring, återanvänder därför profil-generation %s" +#: modules/home-environment.nix:594 +msgid "No change so reusing latest profile generation" +msgstr "Ingen förändring så återanvänder senaste profilgeneration" -#: modules/home-environment.nix:634 +#: modules/home-environment.nix:643 msgid "" "Oops, Nix failed to install your new Home Manager profile!\n" "\n" @@ -63,7 +63,7 @@ msgstr "" "\n" "Prova sedan att aktivera din Home Manager-konfiguration igen." -#: modules/home-environment.nix:667 +#: modules/home-environment.nix:676 msgid "Activating %s" msgstr "Aktiverar %s" @@ -75,70 +75,74 @@ msgstr "Migrerar profil från %s till %s" msgid "Could not find suitable profile directory, tried %s and %s" msgstr "Kunde inte hitta lämplig profil-katalog, försökte med %s och %s" -#: modules/lib-bash/activation-init.sh:83 -msgid "Sanity checking oldGenNum and oldGenPath" -msgstr "Kontrollerar värdena på oldGenNum och oldGenPath" - -#: modules/lib-bash/activation-init.sh:86 -msgid "" -"The previous generation number and path are in conflict! These\n" -"must be either both empty or both set but are now set to\n" -"\n" -" '%s' and '%s'\n" -"\n" -"If you don't mind losing previous profile generations then\n" -"the easiest solution is probably to run\n" -"\n" -" rm %s/home-manager*\n" -" rm %s/current-home\n" -"\n" -"and trying home-manager switch again. Good luck!" -msgstr "" -"Föregående generationsnummer och sökväg motsäger varandra! Dessa måste\n" -"antingen båda vara tomma eller båda vara satta men de har nu värdena\n" -"\n" -" '%s' and '%s'\n" -"\n" -"Om du inte har något emot att förlora tidigare profilgenerationer så\n" -"är den enklaste lösningen antagligen att köra\n" -"\n" -" rm %s/home-manager*\n" -" rm %s/current-home\n" -"\n" -"och prova 'home-manager switch' igen. Lycka till!" - -#: modules/lib-bash/activation-init.sh:127 +#: modules/lib-bash/activation-init.sh:106 msgid "Error: USER is set to \"%s\" but we expect \"%s\"" msgstr "Fel: USER är satt till \"%s\" men \"%s\" förväntades" -#: modules/lib-bash/activation-init.sh:136 +#: modules/lib-bash/activation-init.sh:115 msgid "Error: HOME is set to \"%s\" but we expect \"%s\"" msgstr "Fel: HOME är satt till \"%s\" men \"%s\" förväntades" -#: modules/lib-bash/activation-init.sh:153 +#: modules/lib-bash/activation-init.sh:132 msgid "Starting Home Manager activation" msgstr "Startar Home Manager-aktivering" -#: modules/lib-bash/activation-init.sh:157 +#: modules/lib-bash/activation-init.sh:136 msgid "Sanity checking Nix" msgstr "Kontrollerar att Nix funkar" -#: modules/lib-bash/activation-init.sh:170 +#: modules/lib-bash/activation-init.sh:149 msgid "This is a dry run" msgstr "Detta är en simulerad körning" -#: modules/lib-bash/activation-init.sh:174 +#: modules/lib-bash/activation-init.sh:153 msgid "This is a live run" msgstr "Detta är en verklig körning" -#: modules/lib-bash/activation-init.sh:180 +#: modules/lib-bash/activation-init.sh:159 msgid "Using Nix version: %s" msgstr "Använder Nix-version: %s" -#: modules/lib-bash/activation-init.sh:183 +#: modules/lib-bash/activation-init.sh:162 msgid "Activation variables:" msgstr "Aktiveringsvariabler:" +#~ msgid "Creating profile generation %s" +#~ msgstr "Skapar profil för generation %s" + +#~ msgid "No change so reusing latest profile generation %s" +#~ msgstr "Ingen förändring, återanvänder därför profil-generation %s" + +#~ msgid "Sanity checking oldGenNum and oldGenPath" +#~ msgstr "Kontrollerar värdena på oldGenNum och oldGenPath" + +#~ msgid "" +#~ "The previous generation number and path are in conflict! These\n" +#~ "must be either both empty or both set but are now set to\n" +#~ "\n" +#~ " '%s' and '%s'\n" +#~ "\n" +#~ "If you don't mind losing previous profile generations then\n" +#~ "the easiest solution is probably to run\n" +#~ "\n" +#~ " rm %s/home-manager*\n" +#~ " rm %s/current-home\n" +#~ "\n" +#~ "and trying home-manager switch again. Good luck!" +#~ msgstr "" +#~ "Föregående generationsnummer och sökväg motsäger varandra! Dessa måste\n" +#~ "antingen båda vara tomma eller båda vara satta men de har nu värdena\n" +#~ "\n" +#~ " '%s' and '%s'\n" +#~ "\n" +#~ "Om du inte har något emot att förlora tidigare profilgenerationer så\n" +#~ "är den enklaste lösningen antagligen att köra\n" +#~ "\n" +#~ " rm %s/home-manager*\n" +#~ " rm %s/current-home\n" +#~ "\n" +#~ "och prova 'home-manager switch' igen. Lycka till!" + #~ msgid "Migrating profiles from %s to %s" #~ msgstr "Migrerar profiler från %s till %s" diff --git a/modules/po/ta.po b/modules/po/ta.po new file mode 100644 index 000000000..627f4bea6 --- /dev/null +++ b/modules/po/ta.po @@ -0,0 +1,93 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR Home Manager contributors +# This file is distributed under the same license as the Home Manager Modules package. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: Home Manager Modules\n" +"Report-Msgid-Bugs-To: https://github.com/nix-community/home-manager/issues\n" +"POT-Creation-Date: 2025-01-03 09:09+0100\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: ta\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: modules/files.nix:188 +msgid "Creating home file links in %s" +msgstr "" + +#: modules/files.nix:201 +msgid "Cleaning up orphan links from %s" +msgstr "" + +#: modules/home-environment.nix:591 +msgid "Creating new profile generation" +msgstr "" + +#: modules/home-environment.nix:594 +msgid "No change so reusing latest profile generation" +msgstr "" + +#: modules/home-environment.nix:643 +msgid "" +"Oops, Nix failed to install your new Home Manager profile!\n" +"\n" +"Perhaps there is a conflict with a package that was installed using\n" +"\"%s\"? Try running\n" +"\n" +" %s\n" +"\n" +"and if there is a conflicting package you can remove it with\n" +"\n" +" %s\n" +"\n" +"Then try activating your Home Manager configuration again." +msgstr "" + +#: modules/home-environment.nix:676 +msgid "Activating %s" +msgstr "" + +#: modules/lib-bash/activation-init.sh:22 +msgid "Migrating profile from %s to %s" +msgstr "" + +#: modules/lib-bash/activation-init.sh:54 +msgid "Could not find suitable profile directory, tried %s and %s" +msgstr "" + +#: modules/lib-bash/activation-init.sh:106 +msgid "Error: USER is set to \"%s\" but we expect \"%s\"" +msgstr "" + +#: modules/lib-bash/activation-init.sh:115 +msgid "Error: HOME is set to \"%s\" but we expect \"%s\"" +msgstr "" + +#: modules/lib-bash/activation-init.sh:132 +msgid "Starting Home Manager activation" +msgstr "" + +#: modules/lib-bash/activation-init.sh:136 +msgid "Sanity checking Nix" +msgstr "" + +#: modules/lib-bash/activation-init.sh:149 +msgid "This is a dry run" +msgstr "" + +#: modules/lib-bash/activation-init.sh:153 +msgid "This is a live run" +msgstr "" + +#: modules/lib-bash/activation-init.sh:159 +msgid "Using Nix version: %s" +msgstr "" + +#: modules/lib-bash/activation-init.sh:162 +msgid "Activation variables:" +msgstr "" diff --git a/modules/po/th.po b/modules/po/th.po index 9e6521664..0adfb7b9d 100644 --- a/modules/po/th.po +++ b/modules/po/th.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: Home Manager Modules\n" "Report-Msgid-Bugs-To: https://github.com/nix-community/home-manager/issues\n" -"POT-Creation-Date: 2024-04-17 23:19+0200\n" +"POT-Creation-Date: 2025-01-03 09:09+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" @@ -16,23 +16,23 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: modules/files.nix:191 +#: modules/files.nix:188 msgid "Creating home file links in %s" msgstr "" -#: modules/files.nix:204 +#: modules/files.nix:201 msgid "Cleaning up orphan links from %s" msgstr "" -#: modules/files.nix:220 -msgid "Creating profile generation %s" +#: modules/home-environment.nix:591 +msgid "Creating new profile generation" msgstr "" -#: modules/files.nix:237 -msgid "No change so reusing latest profile generation %s" +#: modules/home-environment.nix:594 +msgid "No change so reusing latest profile generation" msgstr "" -#: modules/home-environment.nix:634 +#: modules/home-environment.nix:643 msgid "" "Oops, Nix failed to install your new Home Manager profile!\n" "\n" @@ -48,7 +48,7 @@ msgid "" "Then try activating your Home Manager configuration again." msgstr "" -#: modules/home-environment.nix:667 +#: modules/home-environment.nix:676 msgid "Activating %s" msgstr "" @@ -60,54 +60,34 @@ msgstr "" msgid "Could not find suitable profile directory, tried %s and %s" msgstr "" -#: modules/lib-bash/activation-init.sh:83 -msgid "Sanity checking oldGenNum and oldGenPath" -msgstr "" - -#: modules/lib-bash/activation-init.sh:86 -msgid "" -"The previous generation number and path are in conflict! These\n" -"must be either both empty or both set but are now set to\n" -"\n" -" '%s' and '%s'\n" -"\n" -"If you don't mind losing previous profile generations then\n" -"the easiest solution is probably to run\n" -"\n" -" rm %s/home-manager*\n" -" rm %s/current-home\n" -"\n" -"and trying home-manager switch again. Good luck!" -msgstr "" - -#: modules/lib-bash/activation-init.sh:127 +#: modules/lib-bash/activation-init.sh:106 msgid "Error: USER is set to \"%s\" but we expect \"%s\"" msgstr "" -#: modules/lib-bash/activation-init.sh:136 +#: modules/lib-bash/activation-init.sh:115 msgid "Error: HOME is set to \"%s\" but we expect \"%s\"" msgstr "" -#: modules/lib-bash/activation-init.sh:153 +#: modules/lib-bash/activation-init.sh:132 msgid "Starting Home Manager activation" msgstr "" -#: modules/lib-bash/activation-init.sh:157 +#: modules/lib-bash/activation-init.sh:136 msgid "Sanity checking Nix" msgstr "" -#: modules/lib-bash/activation-init.sh:170 +#: modules/lib-bash/activation-init.sh:149 msgid "This is a dry run" msgstr "" -#: modules/lib-bash/activation-init.sh:174 +#: modules/lib-bash/activation-init.sh:153 msgid "This is a live run" msgstr "" -#: modules/lib-bash/activation-init.sh:180 +#: modules/lib-bash/activation-init.sh:159 msgid "Using Nix version: %s" msgstr "" -#: modules/lib-bash/activation-init.sh:183 +#: modules/lib-bash/activation-init.sh:162 msgid "Activation variables:" msgstr "" diff --git a/modules/po/tok.po b/modules/po/tok.po new file mode 100644 index 000000000..d20bb2b51 --- /dev/null +++ b/modules/po/tok.po @@ -0,0 +1,93 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR Home Manager contributors +# This file is distributed under the same license as the Home Manager Modules package. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: Home Manager Modules\n" +"Report-Msgid-Bugs-To: https://github.com/nix-community/home-manager/issues\n" +"POT-Creation-Date: 2025-01-03 09:09+0100\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: tok\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: modules/files.nix:188 +msgid "Creating home file links in %s" +msgstr "" + +#: modules/files.nix:201 +msgid "Cleaning up orphan links from %s" +msgstr "" + +#: modules/home-environment.nix:591 +msgid "Creating new profile generation" +msgstr "" + +#: modules/home-environment.nix:594 +msgid "No change so reusing latest profile generation" +msgstr "" + +#: modules/home-environment.nix:643 +msgid "" +"Oops, Nix failed to install your new Home Manager profile!\n" +"\n" +"Perhaps there is a conflict with a package that was installed using\n" +"\"%s\"? Try running\n" +"\n" +" %s\n" +"\n" +"and if there is a conflicting package you can remove it with\n" +"\n" +" %s\n" +"\n" +"Then try activating your Home Manager configuration again." +msgstr "" + +#: modules/home-environment.nix:676 +msgid "Activating %s" +msgstr "" + +#: modules/lib-bash/activation-init.sh:22 +msgid "Migrating profile from %s to %s" +msgstr "" + +#: modules/lib-bash/activation-init.sh:54 +msgid "Could not find suitable profile directory, tried %s and %s" +msgstr "" + +#: modules/lib-bash/activation-init.sh:106 +msgid "Error: USER is set to \"%s\" but we expect \"%s\"" +msgstr "" + +#: modules/lib-bash/activation-init.sh:115 +msgid "Error: HOME is set to \"%s\" but we expect \"%s\"" +msgstr "" + +#: modules/lib-bash/activation-init.sh:132 +msgid "Starting Home Manager activation" +msgstr "" + +#: modules/lib-bash/activation-init.sh:136 +msgid "Sanity checking Nix" +msgstr "" + +#: modules/lib-bash/activation-init.sh:149 +msgid "This is a dry run" +msgstr "" + +#: modules/lib-bash/activation-init.sh:153 +msgid "This is a live run" +msgstr "" + +#: modules/lib-bash/activation-init.sh:159 +msgid "Using Nix version: %s" +msgstr "" + +#: modules/lib-bash/activation-init.sh:162 +msgid "Activation variables:" +msgstr "" diff --git a/modules/po/tr.po b/modules/po/tr.po index f6f3fbc4d..ac39eeef7 100644 --- a/modules/po/tr.po +++ b/modules/po/tr.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: Home Manager Modules\n" "Report-Msgid-Bugs-To: https://github.com/nix-community/home-manager/issues\n" -"POT-Creation-Date: 2024-04-17 23:19+0200\n" +"POT-Creation-Date: 2025-01-03 09:09+0100\n" "PO-Revision-Date: 2023-11-13 17:06+0000\n" "Last-Translator: Oğuz Ersen \n" "Language-Team: Turkish \n" "Language-Team: Ukrainian =20) ? 1 : 2;\n" "X-Generator: Weblate 5.4-dev\n" -#: modules/files.nix:191 +#: modules/files.nix:188 msgid "Creating home file links in %s" msgstr "Створення посилань на файли в домашньому каталозі в %s" -#: modules/files.nix:204 +#: modules/files.nix:201 msgid "Cleaning up orphan links from %s" msgstr "Очищення невідомих посилань із %s" -#: modules/files.nix:220 -msgid "Creating profile generation %s" -msgstr "Створення генерації профілю %s" +#: modules/home-environment.nix:591 +msgid "Creating new profile generation" +msgstr "" -#: modules/files.nix:237 -msgid "No change so reusing latest profile generation %s" -msgstr "Без змін, тому повторне використання останньої генерації профілю %s" +#: modules/home-environment.nix:594 +msgid "No change so reusing latest profile generation" +msgstr "" -#: modules/home-environment.nix:634 +#: modules/home-environment.nix:643 msgid "" "Oops, Nix failed to install your new Home Manager profile!\n" "\n" @@ -64,7 +64,7 @@ msgstr "" "\n" "Потім спробуйте знову активувати конфігурацію Home Manager." -#: modules/home-environment.nix:667 +#: modules/home-environment.nix:676 msgid "Activating %s" msgstr "Активація %s" @@ -76,70 +76,74 @@ msgstr "Перенесення профілю з %s на %s" msgid "Could not find suitable profile directory, tried %s and %s" msgstr "Не вдалося знайти відповідний каталог профілю, спробував %s і %s" -#: modules/lib-bash/activation-init.sh:83 -msgid "Sanity checking oldGenNum and oldGenPath" -msgstr "Перевірка цілісності oldGenNum та oldGenPath" - -#: modules/lib-bash/activation-init.sh:86 -msgid "" -"The previous generation number and path are in conflict! These\n" -"must be either both empty or both set but are now set to\n" -"\n" -" '%s' and '%s'\n" -"\n" -"If you don't mind losing previous profile generations then\n" -"the easiest solution is probably to run\n" -"\n" -" rm %s/home-manager*\n" -" rm %s/current-home\n" -"\n" -"and trying home-manager switch again. Good luck!" -msgstr "" -"Номер і шлях попередньої генерації конфліктують! Ці\n" -"мають бути або порожніми, або обидва встановлені, але тепер встановлено " -"значення\n" -"\n" -" \"%s\" і \"%s\"\n" -"\n" -"Якщо ви не проти втратити попередні генерації профілів, тоді\n" -"найпростішим рішенням є, мабуть, запуск\n" -"\n" -" rm %shome-manager*\n" -" rm %current-home\n" -"\n" -"і знову намагатися переключитися на home-manager switch. Удачі!" - -#: modules/lib-bash/activation-init.sh:127 +#: modules/lib-bash/activation-init.sh:106 msgid "Error: USER is set to \"%s\" but we expect \"%s\"" msgstr "Помилка: USER встановлено на \"%s\", але очікувалося \"%s\"" -#: modules/lib-bash/activation-init.sh:136 +#: modules/lib-bash/activation-init.sh:115 msgid "Error: HOME is set to \"%s\" but we expect \"%s\"" msgstr "Помилка: HOME встановлено на \"%s\", але очікувалося \"%s\"" -#: modules/lib-bash/activation-init.sh:153 +#: modules/lib-bash/activation-init.sh:132 msgid "Starting Home Manager activation" msgstr "Початок активації Home Manager" -#: modules/lib-bash/activation-init.sh:157 +#: modules/lib-bash/activation-init.sh:136 msgid "Sanity checking Nix" msgstr "Перевірка адекватності Nix" -#: modules/lib-bash/activation-init.sh:170 +#: modules/lib-bash/activation-init.sh:149 msgid "This is a dry run" msgstr "Це пробний запуск" -#: modules/lib-bash/activation-init.sh:174 +#: modules/lib-bash/activation-init.sh:153 msgid "This is a live run" msgstr "Це справжній запуск" -#: modules/lib-bash/activation-init.sh:180 +#: modules/lib-bash/activation-init.sh:159 msgid "Using Nix version: %s" msgstr "Використання версії Nix: %s" -#: modules/lib-bash/activation-init.sh:183 +#: modules/lib-bash/activation-init.sh:162 msgid "Activation variables:" msgstr "Активація змінних:" +#~ msgid "Creating profile generation %s" +#~ msgstr "Створення генерації профілю %s" + +#~ msgid "No change so reusing latest profile generation %s" +#~ msgstr "Без змін, тому повторне використання останньої генерації профілю %s" + +#~ msgid "Sanity checking oldGenNum and oldGenPath" +#~ msgstr "Перевірка цілісності oldGenNum та oldGenPath" + +#~ msgid "" +#~ "The previous generation number and path are in conflict! These\n" +#~ "must be either both empty or both set but are now set to\n" +#~ "\n" +#~ " '%s' and '%s'\n" +#~ "\n" +#~ "If you don't mind losing previous profile generations then\n" +#~ "the easiest solution is probably to run\n" +#~ "\n" +#~ " rm %s/home-manager*\n" +#~ " rm %s/current-home\n" +#~ "\n" +#~ "and trying home-manager switch again. Good luck!" +#~ msgstr "" +#~ "Номер і шлях попередньої генерації конфліктують! Ці\n" +#~ "мають бути або порожніми, або обидва встановлені, але тепер встановлено " +#~ "значення\n" +#~ "\n" +#~ " \"%s\" і \"%s\"\n" +#~ "\n" +#~ "Якщо ви не проти втратити попередні генерації профілів, тоді\n" +#~ "найпростішим рішенням є, мабуть, запуск\n" +#~ "\n" +#~ " rm %shome-manager*\n" +#~ " rm %current-home\n" +#~ "\n" +#~ "і знову намагатися переключитися на home-manager switch. Удачі!" + #~ msgid "Migrating profiles from %s to %s" #~ msgstr "Перенесення профілів з %s на %s" diff --git a/modules/po/vi.po b/modules/po/vi.po index 827e32066..4d1d67db6 100644 --- a/modules/po/vi.po +++ b/modules/po/vi.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: Home Manager Modules\n" "Report-Msgid-Bugs-To: https://github.com/nix-community/home-manager/issues\n" -"POT-Creation-Date: 2024-04-17 23:19+0200\n" +"POT-Creation-Date: 2025-01-03 09:09+0100\n" "PO-Revision-Date: 2024-08-01 04:09+0000\n" "Last-Translator: goatastronaut0212 \n" "Language-Team: Vietnamese \n" "Language-Team: Chinese (Simplified) \n" -"Language-Team: Chinese (Traditional) \n" +"POT-Creation-Date: 2025-01-03 09:09+0100\n" +"PO-Revision-Date: 2025-03-07 18:58+0000\n" +"Last-Translator: 807 \n" +"Language-Team: Chinese (Traditional Han script) \n" "Language: zh_Hant\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Weblate 4.15.1-dev\n" +"X-Generator: Weblate 5.10.3-dev\n" -#: modules/files.nix:191 +#: modules/files.nix:188 msgid "Creating home file links in %s" msgstr "正在 %s 中建立家目錄檔案連結" -#: modules/files.nix:204 +#: modules/files.nix:201 msgid "Cleaning up orphan links from %s" msgstr "正在從 %s 清理孤立連結" -#: modules/files.nix:220 -msgid "Creating profile generation %s" -msgstr "正在建立配置檔案世代 %s" +#: modules/home-environment.nix:591 +msgid "Creating new profile generation" +msgstr "正在建立新一代的配置文件中" -#: modules/files.nix:237 -msgid "No change so reusing latest profile generation %s" -msgstr "未發生變化,正在重新使用最近一次的配置檔案世代 %s" +#: modules/home-environment.nix:594 +msgid "No change so reusing latest profile generation" +msgstr "為發生改變,請重新使用新一代的配置文件" -#: modules/home-environment.nix:634 +#: modules/home-environment.nix:643 msgid "" "Oops, Nix failed to install your new Home Manager profile!\n" "\n" @@ -63,66 +63,55 @@ msgstr "" "\n" "來移除。然後嘗試再次啟用您的 Home Manager 配置。" -#: modules/home-environment.nix:667 +#: modules/home-environment.nix:676 msgid "Activating %s" msgstr "正在啟用 %s" #: modules/lib-bash/activation-init.sh:22 msgid "Migrating profile from %s to %s" -msgstr "" +msgstr "正在從 %S 配置文件轉移到 %s 中" #: modules/lib-bash/activation-init.sh:54 msgid "Could not find suitable profile directory, tried %s and %s" -msgstr "" +msgstr "找不到合適的 profile 目錄,已經嘗試 %s 和 %s" -#: modules/lib-bash/activation-init.sh:83 -msgid "Sanity checking oldGenNum and oldGenPath" -msgstr "正在進行 oldGenNum 和 oldGenPath 的完整性檢查" - -#: modules/lib-bash/activation-init.sh:86 -msgid "" -"The previous generation number and path are in conflict! These\n" -"must be either both empty or both set but are now set to\n" -"\n" -" '%s' and '%s'\n" -"\n" -"If you don't mind losing previous profile generations then\n" -"the easiest solution is probably to run\n" -"\n" -" rm %s/home-manager*\n" -" rm %s/current-home\n" -"\n" -"and trying home-manager switch again. Good luck!" -msgstr "" - -#: modules/lib-bash/activation-init.sh:127 +#: modules/lib-bash/activation-init.sh:106 msgid "Error: USER is set to \"%s\" but we expect \"%s\"" -msgstr "" +msgstr "錯誤:USER 被設定為 「%s」但我們希望是 「%s」" -#: modules/lib-bash/activation-init.sh:136 +#: modules/lib-bash/activation-init.sh:115 msgid "Error: HOME is set to \"%s\" but we expect \"%s\"" -msgstr "" +msgstr "錯誤:HOME 被設定為 「%s」但我們預期得到 「%s」" -#: modules/lib-bash/activation-init.sh:153 +#: modules/lib-bash/activation-init.sh:132 msgid "Starting Home Manager activation" msgstr "正在啟動 Home Manager 初始化程式" -#: modules/lib-bash/activation-init.sh:157 +#: modules/lib-bash/activation-init.sh:136 msgid "Sanity checking Nix" msgstr "正在進行 Nix 完整性檢查" -#: modules/lib-bash/activation-init.sh:170 +#: modules/lib-bash/activation-init.sh:149 msgid "This is a dry run" msgstr "這是試運行" -#: modules/lib-bash/activation-init.sh:174 +#: modules/lib-bash/activation-init.sh:153 msgid "This is a live run" msgstr "這是在實際運行" -#: modules/lib-bash/activation-init.sh:180 +#: modules/lib-bash/activation-init.sh:159 msgid "Using Nix version: %s" msgstr "正在使用的 Nix 版本: %s" -#: modules/lib-bash/activation-init.sh:183 +#: modules/lib-bash/activation-init.sh:162 msgid "Activation variables:" msgstr "啟用的變數:" + +#~ msgid "Creating profile generation %s" +#~ msgstr "正在建立配置檔案世代 %s" + +#~ msgid "No change so reusing latest profile generation %s" +#~ msgstr "未發生變化,正在重新使用最近一次的配置檔案世代 %s" + +#~ msgid "Sanity checking oldGenNum and oldGenPath" +#~ msgstr "正在進行 oldGenNum 和 oldGenPath 的完整性檢查" diff --git a/modules/programs/abook.nix b/modules/programs/abook.nix index a9945d0e7..68d9ca75f 100644 --- a/modules/programs/abook.nix +++ b/modules/programs/abook.nix @@ -27,9 +27,6 @@ in { }; config = mkIf cfg.enable { - assertions = - [ (hm.assertions.assertPlatform "programs.abook" pkgs platforms.linux) ]; - home.packages = [ pkgs.abook ]; xdg.configFile."abook/abookrc" = mkIf (cfg.extraConfig != "") { diff --git a/modules/programs/aerc-accounts.nix b/modules/programs/aerc-accounts.nix index 6a6153e5e..8ebfef0bb 100644 --- a/modules/programs/aerc-accounts.nix +++ b/modules/programs/aerc-accounts.nix @@ -134,8 +134,9 @@ in { oauthParams = { auth, params }: if useOauth auth && params != null && params != { } then - "?" + builtins.concatStringsSep "&" lib.attrsets.mapAttrsToList - (k: v: k + "=" + lib.strings.escapeURL v) params + "?" + builtins.concatStringsSep "&" + (lib.attrsets.mapAttrsToList (k: v: k + "=" + lib.strings.escapeURL v) + (lib.attrsets.filterAttrs (k: v: v != null) params)) else ""; @@ -230,8 +231,15 @@ in { else { }; + gpgCfg = account: + optionalAttrs (account.gpg != null) { + pgp-key-id = account.gpg.key; + pgp-auto-sign = account.gpg.signByDefault; + pgp-opportunistic-encrypt = account.gpg.encryptByDefault; + }; + in (basicCfg account) // (sourceCfg account) // (outgoingCfg account) - // account.aerc.extraAccounts; + // (gpgCfg account) // account.aerc.extraAccounts; mkAccountConfig = name: account: mapAttrNames (addAccountName name) account.aerc.extraConfig; diff --git a/modules/programs/aerc.nix b/modules/programs/aerc.nix index 7a48d91a5..477bfddfd 100644 --- a/modules/programs/aerc.nix +++ b/modules/programs/aerc.nix @@ -38,7 +38,7 @@ in { enable = mkEnableOption "aerc"; - package = mkPackageOption pkgs "aerc" { }; + package = mkPackageOption pkgs "aerc" { nullable = true; }; extraAccounts = mkOption { type = sectionsOrLines; @@ -193,7 +193,7 @@ in { ''; }]; - home.packages = [ cfg.package ]; + home.packages = lib.mkIf (cfg.package != null) [ cfg.package ]; home.file = { "${configDir}/accounts.conf" = mkIf genAccountsConf { diff --git a/modules/programs/aerospace.nix b/modules/programs/aerospace.nix new file mode 100644 index 000000000..bb66fee4d --- /dev/null +++ b/modules/programs/aerospace.nix @@ -0,0 +1,240 @@ +{ config, lib, pkgs, ... }: +let + inherit (lib) mkOption types; + cfg = config.programs.aerospace; + + tomlFormat = pkgs.formats.toml { }; + + # filterAttrsRecursive supporting lists, as well. + filterListAndAttrsRecursive = pred: set: + lib.listToAttrs (lib.concatMap (name: + let v = set.${name}; + in if pred v then + [ + (lib.nameValuePair name (if lib.isAttrs v then + filterListAndAttrsRecursive pred v + else if lib.isList v then + (map (i: + if lib.isAttrs i then filterListAndAttrsRecursive pred i else i) + (lib.filter pred v)) + else + v)) + ] + else + [ ]) (lib.attrNames set)); + filterNulls = filterListAndAttrsRecursive (v: v != null); +in { + meta.maintainers = with lib.hm.maintainers; [ damidoug ]; + + options.programs.aerospace = { + enable = lib.mkEnableOption "AeroSpace window manager"; + + package = lib.mkPackageOption pkgs "aerospace" { nullable = true; }; + + userSettings = mkOption { + type = types.submodule { + freeformType = tomlFormat.type; + options = { + start-at-login = lib.mkOption { + type = types.bool; + default = false; + description = "Start AeroSpace at login."; + }; + after-login-command = mkOption { + type = with types; listOf str; + default = [ ]; + description = '' + You can use it to add commands that run after login to macOS user session. + 'start-at-login' needs to be 'true' for 'after-login-command' to work. + ''; + }; + after-startup-command = mkOption { + type = with types; listOf str; + default = [ ]; + description = '' + You can use it to add commands that run after AeroSpace startup. + 'after-startup-command' is run after 'after-login-command' + ''; + example = [ "layout tiles" ]; + }; + enable-normalization-flatten-containers = mkOption { + type = types.bool; + default = true; + description = + ''Containers that have only one child are "flattened".''; + }; + enable-normalization-opposite-orientation-for-nested-containers = + mkOption { + type = types.bool; + default = true; + description = + "Containers that nest into each other must have opposite orientations."; + }; + accordion-padding = mkOption { + type = types.int; + default = 30; + description = "Padding between windows in an accordion container."; + }; + default-root-container-layout = mkOption { + type = types.enum [ "tiles" "accordion" ]; + default = "tiles"; + description = "Default layout for the root container."; + }; + default-root-container-orientation = mkOption { + type = types.enum [ "horizontal" "vertical" "auto" ]; + default = "auto"; + description = "Default orientation for the root container."; + }; + on-window-detected = mkOption { + type = types.listOf (types.submodule { + options = { + "if" = mkOption { + type = types.submodule { + options = { + app-id = mkOption { + type = with types; nullOr str; + default = null; + description = "The application ID to match (optional)."; + }; + workspace = mkOption { + type = with types; nullOr str; + default = null; + description = "The workspace name to match (optional)."; + }; + window-title-regex-substring = mkOption { + type = with types; nullOr str; + default = null; + description = + "Substring to match in the window title (optional)."; + }; + app-name-regex-substring = mkOption { + type = with types; nullOr str; + default = null; + description = + "Regex substring to match the app name (optional)."; + }; + during-aerospace-startup = mkOption { + type = with types; nullOr bool; + default = null; + description = + "Whether to match during aerospace startup (optional)."; + }; + }; + }; + default = { }; + description = "Conditions for detecting a window."; + }; + check-further-callbacks = mkOption { + type = with types; nullOr bool; + default = null; + description = + "Whether to check further callbacks after this rule (optional)."; + }; + run = mkOption { + type = with types; oneOf [ str (listOf str) ]; + example = [ "move-node-to-workspace m" "resize-node" ]; + description = + "Commands to execute when the conditions match (required)."; + }; + }; + }); + default = [ ]; + example = [{ + "if" = { + app-id = "Another.Cool.App"; + workspace = "cool-workspace"; + window-title-regex-substring = "Title"; + app-name-regex-substring = "CoolApp"; + during-aerospace-startup = false; + }; + check-further-callbacks = false; + run = [ "move-node-to-workspace m" "resize-node" ]; + }]; + description = + "Commands to run every time a new window is detected with optional conditions."; + }; + workspace-to-monitor-force-assignment = mkOption { + type = with types; + nullOr (attrsOf (oneOf [ int str (listOf str) ])); + default = null; + description = '' + Map workspaces to specific monitors. + Left-hand side is the workspace name, and right-hand side is the monitor pattern. + ''; + example = { + "1" = 1; # First monitor from left to right. + "2" = "main"; # Main monitor. + "3" = "secondary"; # Secondary monitor (non-main). + "4" = "built-in"; # Built-in display. + "5" = + "^built-in retina display$"; # Regex for the built-in retina display. + "6" = [ "secondary" "dell" ]; # Match first pattern in the list. + }; + }; + on-focus-changed = mkOption { + type = with types; listOf str; + default = [ ]; + example = [ "move-mouse monitor-lazy-center" ]; + description = + "Commands to run every time focused window or workspace changes."; + }; + on-focused-monitor-changed = mkOption { + type = with types; listOf str; + default = [ "move-mouse monitor-lazy-center" ]; + description = "Commands to run every time focused monitor changes."; + }; + exec-on-workspace-change = mkOption { + type = with types; listOf str; + default = [ ]; + example = [ + "/bin/bash" + "-c" + "sketchybar --trigger aerospace_workspace_change FOCUSED=$AEROSPACE_FOCUSED_WORKSPACE" + ]; + description = "Commands to run every time workspace changes."; + }; + key-mapping.preset = mkOption { + type = types.enum [ "qwerty" "dvorak" ]; + default = "qwerty"; + description = "Keymapping preset."; + }; + }; + }; + default = { }; + example = lib.literalExpression '' + { + gaps = { + outer.left = 8; + outer.bottom = 8; + outer.top = 8; + outer.right = 8; + }; + mode.main.binding = { + alt-h = "focus left"; + alt-j = "focus down"; + alt-k = "focus up"; + alt-l = "focus right"; + }; + } + ''; + description = '' + AeroSpace configuration, see + + for supported values. + ''; + }; + }; + + config = lib.mkIf cfg.enable { + assertions = [ + (lib.hm.assertions.assertPlatform "programs.aerospace" pkgs + lib.platforms.darwin) + ]; + + home = { + packages = lib.mkIf (cfg.package != null) [ cfg.package ]; + file.".config/aerospace/aerospace.toml".source = + tomlFormat.generate "aerospace" (filterNulls cfg.userSettings); + }; + }; +} diff --git a/modules/programs/alot.nix b/modules/programs/alot.nix index d0f552f92..243215746 100644 --- a/modules/programs/alot.nix +++ b/modules/programs/alot.nix @@ -132,6 +132,8 @@ in { ''; }; + package = mkPackageOption pkgs "alot" { nullable = true; }; + hooks = mkOption { type = types.lines; default = ""; @@ -229,7 +231,7 @@ in { }; config = mkIf cfg.enable { - home.packages = [ pkgs.alot ]; + home.packages = lib.mkIf (cfg.package != null) [ cfg.package ]; xdg.configFile."alot/config".text = configFile; diff --git a/modules/programs/atuin.nix b/modules/programs/atuin.nix index a27bcf860..50e088b12 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"; @@ -21,33 +23,26 @@ in { description = "The package to use for atuin."; }; - enableBashIntegration = mkOption { - type = types.bool; - default = true; - description = '' - Whether to enable Atuin's Bash integration. This will bind - `ctrl-r` to open the Atuin history. - ''; + enableBashIntegration = lib.hm.shell.mkBashIntegrationOption { + inherit config; + extraDescription = + "If enabled, this will bind `ctrl-r` to open the Atuin history."; }; - enableZshIntegration = mkOption { - type = types.bool; - default = true; - description = '' - Whether to enable Atuin's Zsh integration. - - If enabled, this will bind `ctrl-r` and the up-arrow - key 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."; }; - enableFishIntegration = mkOption { - default = true; - type = types.bool; - description = '' - Whether to enable Atuin's Fish integration. + enableNushellIntegration = + lib.hm.shell.mkNushellIntegrationOption { inherit config; }; - If enabled, this will bind the up-arrow key to open the Atuin history. + 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. ''; }; @@ -87,56 +82,143 @@ in { ''; }; - enableNushellIntegration = mkOption { - default = true; - type = types.bool; - description = '' - 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 = let + socket_dir = if versionAtLeast cfg.package.version "18.4.0" then + "%t" + else + "%D/atuin"; + in { + Unit = { Description = "Atuin daemon socket"; }; + Install = { WantedBy = [ "sockets.target" ]; }; + Socket = { + ListenStream = "${socket_dir}/atuin.sock"; + SocketMode = "0600"; + RemoveOnStop = true; + }; + }; + }) + (mkIf isDarwin { + programs.atuin.settings = { + daemon = { + socket_path = + lib.mkDefault "${config.xdg.dataHome}/atuin/daemon.sock"; + }; + }; + + 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"; + }; + }; + }) + ])) + ]); } diff --git a/modules/programs/autojump.nix b/modules/programs/autojump.nix index e8bf6b437..3177001c8 100644 --- a/modules/programs/autojump.nix +++ b/modules/programs/autojump.nix @@ -13,29 +13,14 @@ in { options.programs.autojump = { enable = mkEnableOption "autojump"; - enableBashIntegration = mkOption { - default = true; - type = types.bool; - description = '' - Whether to enable Bash integration. - ''; - }; + enableBashIntegration = + lib.hm.shell.mkBashIntegrationOption { inherit config; }; - enableZshIntegration = mkOption { - default = true; - type = types.bool; - description = '' - Whether to enable Zsh integration. - ''; - }; + enableFishIntegration = + lib.hm.shell.mkFishIntegrationOption { inherit config; }; - enableFishIntegration = mkOption { - default = true; - type = types.bool; - description = '' - Whether to enable Fish integration. - ''; - }; + enableZshIntegration = + lib.hm.shell.mkZshIntegrationOption { inherit config; }; }; config = mkIf cfg.enable { diff --git a/modules/programs/bacon.nix b/modules/programs/bacon.nix index a24d9ffe1..528be2a06 100644 --- a/modules/programs/bacon.nix +++ b/modules/programs/bacon.nix @@ -7,13 +7,19 @@ let cfg = config.programs.bacon; settingsFormat = pkgs.formats.toml { }; + + configDir = if pkgs.stdenv.isDarwin then + "Library/Application Support/org.dystroy.bacon" + else + "${config.xdg.configHome}/bacon"; + in { meta.maintainers = [ hm.maintainers.shimunn ]; options.programs.bacon = { enable = mkEnableOption "bacon, a background rust code checker"; - package = mkPackageOption pkgs "bacon" { }; + package = mkPackageOption pkgs "bacon" { nullable = true; }; settings = mkOption { type = settingsFormat.type; @@ -32,9 +38,10 @@ in { }; config = mkIf cfg.enable { - home.packages = [ cfg.package ]; + home.packages = lib.mkIf (cfg.package != null) [ cfg.package ]; - xdg.configFile."bacon/prefs.toml".source = - settingsFormat.generate "prefs.toml" cfg.settings; + home.file."${configDir}/prefs.toml" = mkIf (cfg.settings != { }) { + source = settingsFormat.generate "prefs.toml" cfg.settings; + }; }; } diff --git a/modules/programs/bash.nix b/modules/programs/bash.nix index 3a367b9e7..e9cf983dd 100644 --- a/modules/programs/bash.nix +++ b/modules/programs/bash.nix @@ -29,7 +29,10 @@ in { programs.bash = { enable = mkEnableOption "GNU Bourne-Again SHell"; - package = mkPackageOption pkgs "bash" { default = "bashInteractive"; }; + package = mkPackageOption pkgs "bash" { + nullable = true; + default = "bashInteractive"; + }; enableCompletion = mkOption { type = types.bool; @@ -51,7 +54,7 @@ in { }; historySize = mkOption { - type = types.int; + type = types.nullOr types.int; default = 10000; description = "Number of history lines to keep in memory."; }; @@ -63,7 +66,7 @@ in { }; historyFileSize = mkOption { - type = types.int; + type = types.nullOr types.int; default = 100000; description = "Number of history lines to keep on file."; }; @@ -180,19 +183,22 @@ in { sessionVarsStr = config.lib.shell.exportAll cfg.sessionVariables; - historyControlStr = concatStringsSep "\n" - (mapAttrsToList (n: v: "${n}=${v}") ({ - HISTFILESIZE = toString cfg.historyFileSize; - HISTSIZE = toString cfg.historySize; - } // optionalAttrs (cfg.historyFile != null) { - HISTFILE = ''"${cfg.historyFile}"''; - } // optionalAttrs (cfg.historyControl != [ ]) { - HISTCONTROL = concatStringsSep ":" cfg.historyControl; - } // optionalAttrs (cfg.historyIgnore != [ ]) { - HISTIGNORE = escapeShellArg (concatStringsSep ":" cfg.historyIgnore); - })); + historyControlStr = (concatStringsSep "\n" + (mapAttrsToList (n: v: "${n}=${v}") + (optionalAttrs (cfg.historyFileSize != null) { + HISTFILESIZE = toString cfg.historyFileSize; + } // optionalAttrs (cfg.historySize != null) { + HISTSIZE = toString cfg.historySize; + } // optionalAttrs (cfg.historyFile != null) { + HISTFILE = ''"${cfg.historyFile}"''; + } // optionalAttrs (cfg.historyControl != [ ]) { + HISTCONTROL = concatStringsSep ":" cfg.historyControl; + } // optionalAttrs (cfg.historyIgnore != [ ]) { + HISTIGNORE = escapeShellArg (concatStringsSep ":" cfg.historyIgnore); + }) ++ optional (cfg.historyFile != null) + ''mkdir -p "$(dirname "$HISTFILE")"'')); in mkIf cfg.enable { - home.packages = [ cfg.package ]; + home.packages = lib.mkIf (cfg.package != null) [ cfg.package ]; home.file.".bash_profile".source = writeBashScript "bash_profile" '' # include .profile if it exists diff --git a/modules/programs/bat.nix b/modules/programs/bat.nix index 5d09145af..fce1f5e63 100644 --- a/modules/programs/bat.nix +++ b/modules/programs/bat.nix @@ -1,28 +1,25 @@ { config, lib, pkgs, ... }: - -with lib; - let + inherit (lib) literalExpression mkEnableOption mkOption mkIf types; cfg = config.programs.bat; toConfigFile = attrs: let inherit (builtins) isBool attrNames; - nonBoolFlags = filterAttrs (_: v: !(isBool v)) attrs; - enabledBoolFlags = filterAttrs (_: v: isBool v && v) attrs; + nonBoolFlags = lib.filterAttrs (_: v: !(isBool v)) attrs; + enabledBoolFlags = lib.filterAttrs (_: v: isBool v && v) attrs; - keyValuePairs = generators.toKeyValue { + keyValuePairs = lib.generators.toKeyValue { mkKeyValue = k: v: "--${k}=${lib.escapeShellArg v}"; listsAsDuplicateKeys = true; } nonBoolFlags; - switches = concatMapStrings (k: '' + switches = lib.concatMapStrings (k: '' --${k} '') (attrNames enabledBoolFlags); in keyValuePairs + switches; - in { - meta.maintainers = [ ]; + meta.maintainers = with lib.maintainers; [ khaneliman ]; options.programs.bat = { enable = mkEnableOption "bat, a cat clone with wings"; @@ -50,7 +47,7 @@ in { ''; }; - package = mkPackageOption pkgs "bat" { }; + package = lib.mkPackageOption pkgs "bat" { }; themes = mkOption { type = types.attrsOf (types.either types.lines (types.submodule { @@ -122,15 +119,15 @@ in { }; }; - config = mkIf cfg.enable (mkMerge [ - (mkIf (any isString (attrValues cfg.themes)) { + config = mkIf cfg.enable (lib.mkMerge [ + (mkIf (lib.any lib.isString (lib.attrValues cfg.themes)) { warnings = ['' Using programs.bat.themes as a string option is deprecated and will be removed in the future. Please change to using it as an attribute set instead. '']; }) - (mkIf (any isString (attrValues cfg.syntaxes)) { + (mkIf (lib.any lib.isString (lib.attrValues cfg.syntaxes)) { warnings = ['' Using programs.bat.syntaxes as a string option is deprecated and will be removed in the future. Please change to using it as an attribute set @@ -140,18 +137,18 @@ in { { home.packages = [ cfg.package ] ++ cfg.extraPackages; - xdg.configFile = mkMerge ([({ + xdg.configFile = lib.mkMerge ([{ "bat/config" = mkIf (cfg.config != { }) { text = toConfigFile cfg.config; }; - })] ++ (flip mapAttrsToList cfg.themes (name: val: { - "bat/themes/${name}.tmTheme" = if isString val then { + }] ++ (lib.flip lib.mapAttrsToList cfg.themes (name: val: { + "bat/themes/${name}.tmTheme" = if lib.isString val then { text = val; } else { source = if isNull val.file then "${val.src}" else "${val.src}/${val.file}"; }; - })) ++ (flip mapAttrsToList cfg.syntaxes (name: val: { - "bat/syntaxes/${name}.sublime-syntax" = if isString val then { + })) ++ (lib.flip lib.mapAttrsToList cfg.syntaxes (name: val: { + "bat/syntaxes/${name}.sublime-syntax" = if lib.isString val then { text = val; } else { source = @@ -162,9 +159,9 @@ in { # NOTE: run `bat cache --build` in an empty directory to work # around failure when ~/cache exists # https://github.com/sharkdp/bat/issues/1726 - home.activation.batCache = hm.dag.entryAfter [ "linkGeneration" ] '' + home.activation.batCache = lib.hm.dag.entryAfter [ "linkGeneration" ] '' ( - export XDG_CACHE_HOME=${escapeShellArg config.xdg.cacheHome} + export XDG_CACHE_HOME=${lib.escapeShellArg config.xdg.cacheHome} verboseEcho "Rebuilding bat theme cache" cd "${pkgs.emptyDirectory}" run ${lib.getExe cfg.package} cache --build diff --git a/modules/programs/bemenu.nix b/modules/programs/bemenu.nix index 58d24dcc2..6c6e793ff 100644 --- a/modules/programs/bemenu.nix +++ b/modules/programs/bemenu.nix @@ -7,12 +7,12 @@ let cfg = config.programs.bemenu; in { - meta.maintainers = [ hm.maintainers.omernaveedxyz ]; + meta.maintainers = [ ]; options.programs.bemenu = { enable = mkEnableOption "bemenu"; - package = mkPackageOption pkgs "bemenu" { }; + package = mkPackageOption pkgs "bemenu" { nullable = true; }; settings = mkOption { type = with types; attrsOf (oneOf [ str number bool ]); @@ -44,7 +44,7 @@ in { assertions = [ (hm.assertions.assertPlatform "programs.bemenu" pkgs platforms.linux) ]; - home.packages = [ cfg.package ]; + home.packages = lib.mkIf (cfg.package != null) [ cfg.package ]; home.sessionVariables = mkIf (cfg.settings != { }) { BEMENU_OPTS = cli.toGNUCommandLineShell { } cfg.settings; diff --git a/modules/programs/borgmatic.nix b/modules/programs/borgmatic.nix index 97a1d54ce..92f171c27 100644 --- a/modules/programs/borgmatic.nix +++ b/modules/programs/borgmatic.nix @@ -243,7 +243,7 @@ in { programs.borgmatic = { enable = mkEnableOption "Borgmatic"; - package = mkPackageOption pkgs "borgmatic" { }; + package = mkPackageOption pkgs "borgmatic" { nullable = true; }; backups = mkOption { type = types.attrsOf configModule; @@ -292,6 +292,6 @@ in { text = writeConfig config; }) cfg.backups; - home.packages = [ cfg.package ]; + home.packages = lib.mkIf (cfg.package != null) [ cfg.package ]; }; } diff --git a/modules/programs/boxxy.nix b/modules/programs/boxxy.nix index 566a11e7e..dc6c1cbdc 100644 --- a/modules/programs/boxxy.nix +++ b/modules/programs/boxxy.nix @@ -84,7 +84,7 @@ in { options.programs.boxxy = { enable = mkEnableOption "boxxy: Boxes in badly behaving applications"; - package = mkPackageOption pkgs "boxxy" { }; + package = mkPackageOption pkgs "boxxy" { nullable = true; }; rules = mkOption { type = types.listOf boxxyRulesOpts; @@ -102,7 +102,7 @@ in { settingsFormat.generate "boxxy-config.yaml" { rules = cfg.rules; }; }; - home.packages = [ cfg.package ]; + home.packages = lib.mkIf (cfg.package != null) [ cfg.package ]; }; meta.maintainers = with lib.hm.maintainers; [ nikp123 ]; diff --git a/modules/programs/broot.nix b/modules/programs/broot.nix index 6a1680e07..c19534f1a 100644 --- a/modules/programs/broot.nix +++ b/modules/programs/broot.nix @@ -15,7 +15,7 @@ let modal = mkEnableOption "modal (vim) mode"; verbs = mkOption { - type = with types; listOf (attrsOf (either bool str)); + type = with types; listOf (attrsOf (oneOf [ bool str (listOf str) ])); default = [ ]; example = literalExpression '' [ @@ -46,6 +46,9 @@ let `key` (optional) : a keyboard key triggering execution + `keys` (optional) + : multiple keyboard keys each triggering execution + `shortcut` (optional) : an alternate way to call the verb (without the arguments part) @@ -54,7 +57,7 @@ let : whether to quit broot on execution (default: `true`) - `from_shell` (optional) + `from_shell` (optional) : whether the verb must be executed from the parent shell (default: `false`) ''; @@ -151,37 +154,17 @@ in { options.programs.broot = { enable = mkEnableOption "Broot, a better way to navigate directories"; - enableBashIntegration = mkOption { - default = true; - type = types.bool; - description = '' - Whether to enable Bash integration. - ''; - }; + enableBashIntegration = + lib.hm.shell.mkBashIntegrationOption { inherit config; }; - enableZshIntegration = mkOption { - default = true; - type = types.bool; - description = '' - Whether to enable Zsh integration. - ''; - }; + enableFishIntegration = + lib.hm.shell.mkFishIntegrationOption { inherit config; }; - enableFishIntegration = mkOption { - default = true; - type = types.bool; - description = '' - Whether to enable Fish integration. - ''; - }; + enableNushellIntegration = + lib.hm.shell.mkNushellIntegrationOption { inherit config; }; - enableNushellIntegration = mkOption { - default = true; - type = types.bool; - description = '' - Whether to enable Nushell integration. - ''; - }; + enableZshIntegration = + lib.hm.shell.mkZshIntegrationOption { inherit config; }; package = mkOption { type = types.package; @@ -225,9 +208,9 @@ in { programs.broot.settings = builtins.fromJSON (builtins.readFile (pkgs.runCommand "default-conf.json" { - nativeBuildInputs = [ pkgs.hjson ]; + nativeBuildInputs = [ pkgs.hjson-go ]; } - "hjson -c ${cfg.package.src}/resources/default-conf/conf.hjson > $out")); + "hjson-cli -c ${cfg.package.src}/resources/default-conf/conf.hjson > $out")); programs.bash.initExtra = mkIf cfg.enableBashIntegration (shellInit "bash"); diff --git a/modules/programs/btop.nix b/modules/programs/btop.nix index e30a9f43e..61c7f795a 100644 --- a/modules/programs/btop.nix +++ b/modules/programs/btop.nix @@ -1,14 +1,10 @@ { config, lib, pkgs, ... }: - -with lib; - let - cfg = config.programs.btop; finalConfig = let - toKeyValue = generators.toKeyValue { - mkKeyValue = generators.mkKeyValueDefault { + toKeyValue = lib.generators.toKeyValue { + mkKeyValue = lib.generators.mkKeyValueDefault { mkValueString = v: with builtins; if isBool v then @@ -21,19 +17,18 @@ let }; in '' ${toKeyValue cfg.settings} - ${optionalString (cfg.extraConfig != "") cfg.extraConfig} + ${lib.optionalString (cfg.extraConfig != "") cfg.extraConfig} ''; - in { - meta.maintainers = [ hm.maintainers.GaetanLepage ]; + meta.maintainers = with lib.maintainers; [ GaetanLepage khaneliman ]; options.programs.btop = { - enable = mkEnableOption "btop"; + enable = lib.mkEnableOption "btop"; - package = mkPackageOption pkgs "btop" { }; + package = lib.mkPackageOption pkgs "btop" { nullable = true; }; - settings = mkOption { - type = with types; attrsOf (oneOf [ bool float int str ]); + settings = lib.mkOption { + type = with lib.types; attrsOf (oneOf [ bool float int str ]); default = { }; example = { color_theme = "Default"; @@ -46,8 +41,8 @@ in { ''; }; - extraConfig = mkOption { - type = types.lines; + extraConfig = lib.mkOption { + type = lib.types.lines; default = ""; description = '' Extra lines added to the {file}`btop.conf` file. @@ -55,10 +50,10 @@ in { }; }; - config = mkIf cfg.enable { - home.packages = [ cfg.package ]; + config = lib.mkIf cfg.enable { + home.packages = lib.mkIf (cfg.package != null) [ cfg.package ]; xdg.configFile."btop/btop.conf" = - mkIf (cfg.settings != { }) { text = finalConfig; }; + lib.mkIf (cfg.settings != { }) { text = finalConfig; }; }; } diff --git a/modules/programs/bun.nix b/modules/programs/bun.nix index f186982e2..ffc9167ef 100644 --- a/modules/programs/bun.nix +++ b/modules/programs/bun.nix @@ -9,7 +9,7 @@ in { options.programs.bun = { enable = lib.mkEnableOption "Bun JavaScript runtime"; - package = lib.mkPackageOption pkgs "bun" { }; + package = lib.mkPackageOption pkgs "bun" { nullable = true; }; settings = lib.mkOption { type = tomlFormat.type; @@ -42,7 +42,13 @@ in { }; config = lib.mkIf cfg.enable { - home.packages = [ cfg.package ]; + warnings = lib.optional (cfg.package == null && cfg.enableGitIntegration) '' + You have enabled git integration for `bun` but have not set `package`. + + Git integration will not be configured. + ''; + + home.packages = lib.mkIf (cfg.package != null) [ cfg.package ]; xdg.configFile.".bunfig.toml" = lib.mkIf (cfg.settings != { }) { source = tomlFormat.generate "bun-config" cfg.settings; @@ -50,10 +56,12 @@ in { # https://bun.sh/docs/install/lockfile#how-do-i-git-diff-bun-s-lockfile programs.git.attributes = - lib.mkIf cfg.enableGitIntegration [ "*.lockb binary diff=lockb" ]; - programs.git.extraConfig.diff.lockb = lib.mkIf cfg.enableGitIntegration { - textconv = lib.getExe cfg.package; - binary = true; - }; + lib.mkIf (cfg.enableGitIntegration && (cfg.package != null)) + [ "*.lockb binary diff=lockb" ]; + programs.git.extraConfig.diff.lockb = + lib.mkIf (cfg.enableGitIntegration && (cfg.package != null)) { + textconv = lib.getExe cfg.package; + binary = true; + }; }; } diff --git a/modules/programs/carapace.nix b/modules/programs/carapace.nix index c31e2feed..09cc55635 100644 --- a/modules/programs/carapace.nix +++ b/modules/programs/carapace.nix @@ -16,21 +16,17 @@ in { package = mkPackageOption pkgs "carapace" { }; - enableBashIntegration = mkEnableOption "Bash integration" // { - default = true; - }; + enableBashIntegration = + lib.hm.shell.mkBashIntegrationOption { inherit config; }; - enableZshIntegration = mkEnableOption "Zsh integration" // { - default = true; - }; + enableFishIntegration = + lib.hm.shell.mkFishIntegrationOption { inherit config; }; - enableFishIntegration = mkEnableOption "Fish integration" // { - default = true; - }; + enableNushellIntegration = + lib.hm.shell.mkNushellIntegrationOption { inherit config; }; - enableNushellIntegration = mkEnableOption "Nushell integration" // { - default = true; - }; + enableZshIntegration = + lib.hm.shell.mkZshIntegrationOption { inherit config; }; }; config = mkIf cfg.enable { diff --git a/modules/programs/cava.nix b/modules/programs/cava.nix index 63173248f..946656b06 100644 --- a/modules/programs/cava.nix +++ b/modules/programs/cava.nix @@ -14,7 +14,7 @@ in { options.programs.cava = { enable = mkEnableOption "Cava audio visualizer"; - package = mkPackageOption pkgs "cava" { }; + package = mkPackageOption pkgs "cava" { nullable = true; }; settings = mkOption { type = iniFmt.type; @@ -39,7 +39,7 @@ in { }; config = mkIf cfg.enable { - home.packages = [ cfg.package ]; + home.packages = lib.mkIf (cfg.package != null) [ cfg.package ]; xdg.configFile."cava/config" = mkIf (cfg.settings != { }) { text = '' diff --git a/modules/programs/cavalier.nix b/modules/programs/cavalier.nix new file mode 100644 index 000000000..8ba05de93 --- /dev/null +++ b/modules/programs/cavalier.nix @@ -0,0 +1,102 @@ +{ pkgs, config, lib, ... }: + +with lib; + +let + + cfg = config.programs.cavalier; + + iniFmt = pkgs.formats.ini { }; + + jsonFmt = pkgs.formats.json { }; + +in { + meta.maintainers = [ hm.maintainers.bricked ]; + + options.programs.cavalier = { + enable = mkEnableOption "Cava audio visualizer GUI"; + + package = mkPackageOption pkgs "cavalier" { nullable = true; }; + + settings = { + general = mkOption { + type = jsonFmt.type; + default = { }; + example = literalExpression '' + { + ShowControls = true; + ColorProfiles = [ + { + Name = "Default"; + FgColors = [ + "#ffed333b" + "#ffffa348" + "#fff8e45c" + "#ff57e389" + "#ff62a0ea" + "#ffc061cb" + ]; + BgColors = [ + "#ff1e1e2e" + ]; + Theme = 1; + } + ]; + ActiveProfile = 0; + } + ''; + description = '' + Settings to be written to the Cavalier configuration file. See + + for all available options. + ''; + }; + + cava = mkOption { + type = iniFmt.type; + default = { }; + example = literalExpression '' + { + general.framerate = 60; + input.method = "alsa"; + smoothing.noise_reduction = 88; + color = { + background = "'#000000'"; + foreground = "'#FFFFFF'"; + }; + } + ''; + description = '' + Settings to be written to the underlying Cava configuration file. See + for + all available options. + ''; + }; + }; + }; + + config = mkIf cfg.enable { + assertions = [ + (lib.hm.assertions.assertPlatform "programs.cavalier" pkgs + lib.platforms.linux) + ]; + + home.packages = lib.mkIf (cfg.package != null) [ cfg.package ]; + + xdg.configFile = { + "Nickvision Cavalier/config.json" = mkIf (cfg.settings.general != { }) { + text = '' + ${generators.toJSON { } cfg.settings.general} + ''; + }; + + "Nickvision Cavalier/cava_config" = mkIf (cfg.settings.cava != { }) { + text = '' + ; Generated by Home Manager + + ${generators.toINI { } cfg.settings.cava} + ''; + }; + }; + }; +} diff --git a/modules/programs/chromium.nix b/modules/programs/chromium.nix index 0a02311b7..ffb488fc9 100644 --- a/modules/programs/chromium.nix +++ b/modules/programs/chromium.nix @@ -137,6 +137,18 @@ let List of ${name} dictionaries to install. ''; }; + nativeMessagingHosts = mkOption { + type = types.listOf types.package; + default = [ ]; + example = literalExpression '' + [ + pkgs.kdePackages.plasma-browser-integration + ] + ''; + description = '' + List of ${name} native messaging hosts to install. + ''; + }; }; browserConfig = cfg: @@ -178,6 +190,11 @@ let value.source = pkg; }; + nativeMessagingHostsJoined = pkgs.symlinkJoin { + name = "${drvName}-native-messaging-hosts"; + paths = cfg.nativeMessagingHosts; + }; + package = if cfg.commandLineArgs != [ ] then cfg.package.override { commandLineArgs = concatStringsSep " " cfg.commandLineArgs; @@ -189,7 +206,14 @@ let home.packages = [ package ]; home.file = optionalAttrs (!isProprietaryChrome) (listToAttrs ((map extensionJson cfg.extensions) - ++ (map dictionary cfg.dictionaries))); + ++ (map dictionary cfg.dictionaries)) // { + "${configDir}/NativeMessagingHosts" = + lib.mkIf (cfg.nativeMessagingHosts != [ ]) { + source = + "${nativeMessagingHostsJoined}/etc/chromium/native-messaging-hosts"; + recursive = true; + }; + }); }; in { diff --git a/modules/programs/cmus.nix b/modules/programs/cmus.nix new file mode 100644 index 000000000..ac3e46ee1 --- /dev/null +++ b/modules/programs/cmus.nix @@ -0,0 +1,44 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + cfg = config.programs.cmus; + +in { + meta.maintainers = [ hm.maintainers.joygnu ]; + + options.programs.cmus = { + enable = mkEnableOption "Enable cmus, the music player."; + + theme = mkOption { + type = types.lines; + default = ""; + example = "gruvbox"; + description = '' + Select color theme. A list of available color themes can be found + here: . + ''; + }; + + extraConfig = mkOption { + type = types.lines; + default = ""; + example = '' + set audio_backend = "mpd" + set status_display = "default" + ''; + description = "Extra configuration to add to cmus {file}`rc`."; + }; + }; + + config = mkIf cfg.enable { + home.packages = [ pkgs.cmus ]; + + home.file.".config/cmus/rc".text = '' + ${optionalString (cfg.theme != "") "colorscheme ${cfg.theme}"} + ${cfg.extraConfig} + ''; + }; +} diff --git a/modules/programs/comodoro.nix b/modules/programs/comodoro.nix index fba0bce86..af59261ef 100644 --- a/modules/programs/comodoro.nix +++ b/modules/programs/comodoro.nix @@ -10,7 +10,7 @@ in { options.programs.comodoro = { enable = lib.mkEnableOption "Comodoro, a CLI to manage your time"; - package = lib.mkPackageOption pkgs "comodoro" { }; + package = lib.mkPackageOption pkgs "comodoro" { nullable = true; }; settings = lib.mkOption { type = lib.types.submodule { freeformType = tomlFormat.type; }; @@ -23,7 +23,7 @@ in { }; config = lib.mkIf cfg.enable { - home.packages = [ cfg.package ]; + home.packages = lib.mkIf (cfg.package != null) [ cfg.package ]; xdg.configFile."comodoro/config.toml".source = tomlFormat.generate "comodoro-config.toml" cfg.settings; diff --git a/modules/programs/darcs.nix b/modules/programs/darcs.nix index a2a45cba4..263d668fe 100644 --- a/modules/programs/darcs.nix +++ b/modules/programs/darcs.nix @@ -13,7 +13,7 @@ in { programs.darcs = { enable = mkEnableOption "darcs"; - package = mkPackageOption pkgs "darcs" { }; + package = mkPackageOption pkgs "darcs" { nullable = true; }; author = mkOption { type = types.listOf types.str; @@ -36,7 +36,7 @@ in { }; config = mkIf cfg.enable (mkMerge [ - { home.packages = [ cfg.package ]; } + { home.packages = lib.mkIf (cfg.package != null) [ cfg.package ]; } (mkIf (cfg.author != [ ]) { home.file.".darcs/author".text = diff --git a/modules/programs/dircolors.nix b/modules/programs/dircolors.nix index de4610893..240be4a27 100644 --- a/modules/programs/dircolors.nix +++ b/modules/programs/dircolors.nix @@ -19,29 +19,14 @@ in { ''; }; - enableBashIntegration = mkOption { - type = types.bool; - default = true; - description = '' - Whether to enable Bash integration. - ''; - }; + enableBashIntegration = + lib.hm.shell.mkBashIntegrationOption { inherit config; }; - enableFishIntegration = mkOption { - type = types.bool; - default = true; - description = '' - Whether to enable Fish integration. - ''; - }; + enableFishIntegration = + lib.hm.shell.mkFishIntegrationOption { inherit config; }; - enableZshIntegration = mkOption { - type = types.bool; - default = true; - description = '' - Whether to enable Zsh integration. - ''; - }; + enableZshIntegration = + lib.hm.shell.mkZshIntegrationOption { inherit config; }; settings = mkOption { type = with types; attrsOf str; @@ -69,155 +54,168 @@ in { }; }; - config = mkIf cfg.enable { - # Add default settings from `dircolors --print-database`. - programs.dircolors.settings = { - RESET = mkDefault "0"; - DIR = mkDefault "01;34"; - LINK = mkDefault "01;36"; - MULTIHARDLINK = mkDefault "00"; - FIFO = mkDefault "40;33"; - SOCK = mkDefault "01;35"; - DOOR = mkDefault "01;35"; - BLK = mkDefault "40;33;01"; - CHR = mkDefault "40;33;01"; - ORPHAN = mkDefault "40;31;01"; - MISSING = mkDefault "00"; - SETUID = mkDefault "37;41"; - SETGID = mkDefault "30;43"; - CAPABILITY = mkDefault "30;41"; - STICKY_OTHER_WRITABLE = mkDefault "30;42"; - OTHER_WRITABLE = mkDefault "34;42"; - STICKY = mkDefault "37;44"; - EXEC = mkDefault "01;32"; - ".tar" = mkDefault "01;31"; - ".tgz" = mkDefault "01;31"; - ".arc" = mkDefault "01;31"; - ".arj" = mkDefault "01;31"; - ".taz" = mkDefault "01;31"; - ".lha" = mkDefault "01;31"; - ".lz4" = mkDefault "01;31"; - ".lzh" = mkDefault "01;31"; - ".lzma" = mkDefault "01;31"; - ".tlz" = mkDefault "01;31"; - ".txz" = mkDefault "01;31"; - ".tzo" = mkDefault "01;31"; - ".t7z" = mkDefault "01;31"; - ".zip" = mkDefault "01;31"; - ".z" = mkDefault "01;31"; - ".dz" = mkDefault "01;31"; - ".gz" = mkDefault "01;31"; - ".lrz" = mkDefault "01;31"; - ".lz" = mkDefault "01;31"; - ".lzo" = mkDefault "01;31"; - ".xz" = mkDefault "01;31"; - ".zst" = mkDefault "01;31"; - ".tzst" = mkDefault "01;31"; - ".bz2" = mkDefault "01;31"; - ".bz" = mkDefault "01;31"; - ".tbz" = mkDefault "01;31"; - ".tbz2" = mkDefault "01;31"; - ".tz" = mkDefault "01;31"; - ".deb" = mkDefault "01;31"; - ".rpm" = mkDefault "01;31"; - ".jar" = mkDefault "01;31"; - ".war" = mkDefault "01;31"; - ".ear" = mkDefault "01;31"; - ".sar" = mkDefault "01;31"; - ".rar" = mkDefault "01;31"; - ".alz" = mkDefault "01;31"; - ".ace" = mkDefault "01;31"; - ".zoo" = mkDefault "01;31"; - ".cpio" = mkDefault "01;31"; - ".7z" = mkDefault "01;31"; - ".rz" = mkDefault "01;31"; - ".cab" = mkDefault "01;31"; - ".wim" = mkDefault "01;31"; - ".swm" = mkDefault "01;31"; - ".dwm" = mkDefault "01;31"; - ".esd" = mkDefault "01;31"; - ".jpg" = mkDefault "01;35"; - ".jpeg" = mkDefault "01;35"; - ".mjpg" = mkDefault "01;35"; - ".mjpeg" = mkDefault "01;35"; - ".gif" = mkDefault "01;35"; - ".bmp" = mkDefault "01;35"; - ".pbm" = mkDefault "01;35"; - ".pgm" = mkDefault "01;35"; - ".ppm" = mkDefault "01;35"; - ".tga" = mkDefault "01;35"; - ".xbm" = mkDefault "01;35"; - ".xpm" = mkDefault "01;35"; - ".tif" = mkDefault "01;35"; - ".tiff" = mkDefault "01;35"; - ".png" = mkDefault "01;35"; - ".svg" = mkDefault "01;35"; - ".svgz" = mkDefault "01;35"; - ".mng" = mkDefault "01;35"; - ".pcx" = mkDefault "01;35"; - ".mov" = mkDefault "01;35"; - ".mpg" = mkDefault "01;35"; - ".mpeg" = mkDefault "01;35"; - ".m2v" = mkDefault "01;35"; - ".mkv" = mkDefault "01;35"; - ".webm" = mkDefault "01;35"; - ".ogm" = mkDefault "01;35"; - ".mp4" = mkDefault "01;35"; - ".m4v" = mkDefault "01;35"; - ".mp4v" = mkDefault "01;35"; - ".vob" = mkDefault "01;35"; - ".qt" = mkDefault "01;35"; - ".nuv" = mkDefault "01;35"; - ".wmv" = mkDefault "01;35"; - ".asf" = mkDefault "01;35"; - ".rm" = mkDefault "01;35"; - ".rmvb" = mkDefault "01;35"; - ".flc" = mkDefault "01;35"; - ".avi" = mkDefault "01;35"; - ".fli" = mkDefault "01;35"; - ".flv" = mkDefault "01;35"; - ".gl" = mkDefault "01;35"; - ".dl" = mkDefault "01;35"; - ".xcf" = mkDefault "01;35"; - ".xwd" = mkDefault "01;35"; - ".yuv" = mkDefault "01;35"; - ".cgm" = mkDefault "01;35"; - ".emf" = mkDefault "01;35"; - ".ogv" = mkDefault "01;35"; - ".ogx" = mkDefault "01;35"; - ".aac" = mkDefault "00;36"; - ".au" = mkDefault "00;36"; - ".flac" = mkDefault "00;36"; - ".m4a" = mkDefault "00;36"; - ".mid" = mkDefault "00;36"; - ".midi" = mkDefault "00;36"; - ".mka" = mkDefault "00;36"; - ".mp3" = mkDefault "00;36"; - ".mpc" = mkDefault "00;36"; - ".ogg" = mkDefault "00;36"; - ".ra" = mkDefault "00;36"; - ".wav" = mkDefault "00;36"; - ".oga" = mkDefault "00;36"; - ".opus" = mkDefault "00;36"; - ".spx" = mkDefault "00;36"; - ".xspf" = mkDefault "00;36"; - }; + config = let + dircolorsPath = if config.home.preferXdgDirectories then + "${config.xdg.configHome}/dir_colors" + else + "~/.dir_colors"; - home.file.".dir_colors".text = concatStringsSep "\n" ([ ] + dircolorsConfig = concatStringsSep "\n" ([ ] ++ mapAttrsToList formatLine cfg.settings ++ [ "" ] ++ optional (cfg.extraConfig != "") cfg.extraConfig); + in mkIf cfg.enable (mkMerge [ + { + # Add default settings from `dircolors --print-database`. + programs.dircolors.settings = { + RESET = mkDefault "0"; + DIR = mkDefault "01;34"; + LINK = mkDefault "01;36"; + MULTIHARDLINK = mkDefault "00"; + FIFO = mkDefault "40;33"; + SOCK = mkDefault "01;35"; + DOOR = mkDefault "01;35"; + BLK = mkDefault "40;33;01"; + CHR = mkDefault "40;33;01"; + ORPHAN = mkDefault "40;31;01"; + MISSING = mkDefault "00"; + SETUID = mkDefault "37;41"; + SETGID = mkDefault "30;43"; + CAPABILITY = mkDefault "30;41"; + STICKY_OTHER_WRITABLE = mkDefault "30;42"; + OTHER_WRITABLE = mkDefault "34;42"; + STICKY = mkDefault "37;44"; + EXEC = mkDefault "01;32"; + ".tar" = mkDefault "01;31"; + ".tgz" = mkDefault "01;31"; + ".arc" = mkDefault "01;31"; + ".arj" = mkDefault "01;31"; + ".taz" = mkDefault "01;31"; + ".lha" = mkDefault "01;31"; + ".lz4" = mkDefault "01;31"; + ".lzh" = mkDefault "01;31"; + ".lzma" = mkDefault "01;31"; + ".tlz" = mkDefault "01;31"; + ".txz" = mkDefault "01;31"; + ".tzo" = mkDefault "01;31"; + ".t7z" = mkDefault "01;31"; + ".zip" = mkDefault "01;31"; + ".z" = mkDefault "01;31"; + ".dz" = mkDefault "01;31"; + ".gz" = mkDefault "01;31"; + ".lrz" = mkDefault "01;31"; + ".lz" = mkDefault "01;31"; + ".lzo" = mkDefault "01;31"; + ".xz" = mkDefault "01;31"; + ".zst" = mkDefault "01;31"; + ".tzst" = mkDefault "01;31"; + ".bz2" = mkDefault "01;31"; + ".bz" = mkDefault "01;31"; + ".tbz" = mkDefault "01;31"; + ".tbz2" = mkDefault "01;31"; + ".tz" = mkDefault "01;31"; + ".deb" = mkDefault "01;31"; + ".rpm" = mkDefault "01;31"; + ".jar" = mkDefault "01;31"; + ".war" = mkDefault "01;31"; + ".ear" = mkDefault "01;31"; + ".sar" = mkDefault "01;31"; + ".rar" = mkDefault "01;31"; + ".alz" = mkDefault "01;31"; + ".ace" = mkDefault "01;31"; + ".zoo" = mkDefault "01;31"; + ".cpio" = mkDefault "01;31"; + ".7z" = mkDefault "01;31"; + ".rz" = mkDefault "01;31"; + ".cab" = mkDefault "01;31"; + ".wim" = mkDefault "01;31"; + ".swm" = mkDefault "01;31"; + ".dwm" = mkDefault "01;31"; + ".esd" = mkDefault "01;31"; + ".jpg" = mkDefault "01;35"; + ".jpeg" = mkDefault "01;35"; + ".mjpg" = mkDefault "01;35"; + ".mjpeg" = mkDefault "01;35"; + ".gif" = mkDefault "01;35"; + ".bmp" = mkDefault "01;35"; + ".pbm" = mkDefault "01;35"; + ".pgm" = mkDefault "01;35"; + ".ppm" = mkDefault "01;35"; + ".tga" = mkDefault "01;35"; + ".xbm" = mkDefault "01;35"; + ".xpm" = mkDefault "01;35"; + ".tif" = mkDefault "01;35"; + ".tiff" = mkDefault "01;35"; + ".png" = mkDefault "01;35"; + ".svg" = mkDefault "01;35"; + ".svgz" = mkDefault "01;35"; + ".mng" = mkDefault "01;35"; + ".pcx" = mkDefault "01;35"; + ".mov" = mkDefault "01;35"; + ".mpg" = mkDefault "01;35"; + ".mpeg" = mkDefault "01;35"; + ".m2v" = mkDefault "01;35"; + ".mkv" = mkDefault "01;35"; + ".webm" = mkDefault "01;35"; + ".ogm" = mkDefault "01;35"; + ".mp4" = mkDefault "01;35"; + ".m4v" = mkDefault "01;35"; + ".mp4v" = mkDefault "01;35"; + ".vob" = mkDefault "01;35"; + ".qt" = mkDefault "01;35"; + ".nuv" = mkDefault "01;35"; + ".wmv" = mkDefault "01;35"; + ".asf" = mkDefault "01;35"; + ".rm" = mkDefault "01;35"; + ".rmvb" = mkDefault "01;35"; + ".flc" = mkDefault "01;35"; + ".avi" = mkDefault "01;35"; + ".fli" = mkDefault "01;35"; + ".flv" = mkDefault "01;35"; + ".gl" = mkDefault "01;35"; + ".dl" = mkDefault "01;35"; + ".xcf" = mkDefault "01;35"; + ".xwd" = mkDefault "01;35"; + ".yuv" = mkDefault "01;35"; + ".cgm" = mkDefault "01;35"; + ".emf" = mkDefault "01;35"; + ".ogv" = mkDefault "01;35"; + ".ogx" = mkDefault "01;35"; + ".aac" = mkDefault "00;36"; + ".au" = mkDefault "00;36"; + ".flac" = mkDefault "00;36"; + ".m4a" = mkDefault "00;36"; + ".mid" = mkDefault "00;36"; + ".midi" = mkDefault "00;36"; + ".mka" = mkDefault "00;36"; + ".mp3" = mkDefault "00;36"; + ".mpc" = mkDefault "00;36"; + ".ogg" = mkDefault "00;36"; + ".ra" = mkDefault "00;36"; + ".wav" = mkDefault "00;36"; + ".oga" = mkDefault "00;36"; + ".opus" = mkDefault "00;36"; + ".spx" = mkDefault "00;36"; + ".xspf" = mkDefault "00;36"; + }; - programs.bash.initExtra = mkIf cfg.enableBashIntegration '' - eval $(${pkgs.coreutils}/bin/dircolors -b ~/.dir_colors) - ''; + programs.bash.initExtra = mkIf cfg.enableBashIntegration '' + eval $(${pkgs.coreutils}/bin/dircolors -b ${dircolorsPath}) + ''; - programs.fish.shellInit = mkIf cfg.enableFishIntegration '' - eval (${pkgs.coreutils}/bin/dircolors -c ~/.dir_colors) - ''; + programs.fish.shellInit = mkIf cfg.enableFishIntegration '' + eval (${pkgs.coreutils}/bin/dircolors -c ${dircolorsPath}) + ''; - # Set `LS_COLORS` before Oh My Zsh and `initExtra`. - programs.zsh.initExtraBeforeCompInit = mkIf cfg.enableZshIntegration '' - eval $(${pkgs.coreutils}/bin/dircolors -b ~/.dir_colors) - ''; - }; + # Set `LS_COLORS` before Oh My Zsh and `initExtra`. + programs.zsh.initExtraBeforeCompInit = mkIf cfg.enableZshIntegration '' + eval $(${pkgs.coreutils}/bin/dircolors -b ${dircolorsPath}) + ''; + } + (mkIf (!config.home.preferXdgDirectories) { + home.file.".dir_colors".text = dircolorsConfig; + }) + (mkIf config.home.preferXdgDirectories { + xdg.configFile.dir_colors.text = dircolorsConfig; + }) + ]); } diff --git a/modules/programs/direnv.nix b/modules/programs/direnv.nix index 4d4862afb..a387a4bc7 100644 --- a/modules/programs/direnv.nix +++ b/modules/programs/direnv.nix @@ -19,7 +19,7 @@ in { "Flake support is now always enabled.") ]; - meta.maintainers = [ lib.maintainers.rycee ]; + meta.maintainers = with lib.maintainers; [ khaneliman rycee shikanime ]; options.programs.direnv = { enable = mkEnableOption "direnv, the environment switcher"; @@ -48,44 +48,32 @@ in { ''; }; - enableBashIntegration = mkOption { - default = true; - type = types.bool; - description = '' - Whether to enable Bash integration. - ''; - }; + enableBashIntegration = + lib.hm.shell.mkBashIntegrationOption { inherit config; }; - enableZshIntegration = mkOption { - default = true; - type = types.bool; - description = '' - Whether to enable Zsh integration. - ''; - }; + enableFishIntegration = lib.hm.shell.mkFishIntegrationOption { + inherit config; + extraDescription = '' + Note, enabling the direnv module will always active its functionality + for Fish since the direnv package automatically gets loaded in Fish. + If this is not the case try adding - enableFishIntegration = mkOption { - default = true; - type = types.bool; - readOnly = true; - description = '' - Whether to enable Fish integration. Note, enabling the direnv module - will always active its functionality for Fish since the direnv package - automatically gets loaded in Fish. If this is not the case try adding ```nix - environment.pathsToLink = [ "/share/fish" ]; + environment.pathsToLink = [ "/share/fish" ]; ``` + to the system configuration. ''; + } // { + default = true; + readOnly = true; }; - enableNushellIntegration = mkOption { - default = true; - type = types.bool; - description = '' - Whether to enable Nushell integration. - ''; - }; + enableNushellIntegration = + lib.hm.shell.mkNushellIntegrationOption { inherit config; }; + + enableZshIntegration = + lib.hm.shell.mkZshIntegrationOption { inherit config; }; nix-direnv = { enable = mkEnableOption '' @@ -95,6 +83,14 @@ in { package = mkPackageOption pkgs "nix-direnv" { }; }; + mise = { + enable = mkEnableOption '' + [mise](https://mise.jdx.dev/direnv.html), + integration of use_mise for direnv''; + + package = mkPackageOption pkgs "mise" { }; + }; + silent = mkEnableOption "silent mode, that is, disabling direnv logging"; }; @@ -112,6 +108,12 @@ in { xdg.configFile."direnv/direnvrc" = lib.mkIf (cfg.stdlib != "") { text = cfg.stdlib; }; + xdg.configFile."direnv/lib/hm-mise.sh" = mkIf cfg.mise.enable { + text = '' + eval "$(${getExe cfg.mise.package} direnv activate)" + ''; + }; + programs.bash.initExtra = mkIf cfg.enableBashIntegration ( # Using mkAfter to make it more likely to appear after other # manipulations of the prompt. @@ -130,60 +132,29 @@ in { ${getExe cfg.package} hook fish | source ''); - programs.nushell.extraConfig = mkIf cfg.enableNushellIntegration (let - # We want to get the stdout from direnv even if it exits with non-zero, - # because it will have the DIRENV_ internal variables defined. - # - # However, nushell's current implementation of try-catch is subtly - # broken with external commands in pipelines[0]. - # - # This means we don't have a good way to ignore the exit code - # without using do | complete, which has a side effect of also - # capturing stderr, which we don't want. - # - # So, as a workaround, we wrap nushell in a second script that - # just ignores the exit code and does nothing else, allowing - # nushell to capture our stdout, but letting stderr go through - # and not causing a spurious "command failed" message. - # - # [0]: https://github.com/nushell/nushell/issues/13868 - # - # FIXME: remove the wrapper once the upstream issue is fixed - - direnvWrapped = pkgs.writeShellScript "direnv-wrapped" '' - ${getExe cfg.package} export json || true - ''; - # Using mkAfter to make it more likely to appear after other - # manipulations of the prompt. - in mkAfter '' + # Using mkAfter to make it more likely to appear after other + # manipulations of the prompt. + programs.nushell.extraConfig = mkIf cfg.enableNushellIntegration (mkAfter '' $env.config = ($env.config? | default {}) $env.config.hooks = ($env.config.hooks? | default {}) $env.config.hooks.pre_prompt = ( $env.config.hooks.pre_prompt? | default [] | append {|| - let direnv = ( - ${direnvWrapped} - | from json --strict - | default {} - ) - if ($direnv | is-empty) { - return - } - $direnv + ${getExe cfg.package} export json + | from json --strict + | default {} | items {|key, value| - { - key: $key - value: (do ( - $env.ENV_CONVERSIONS? - | default {} - | get -i $key - | get -i from_string - | default {|x| $x} - ) $value) - } + let value = do ( + $env.ENV_CONVERSIONS? + | default {} + | get -i $key + | get -i from_string + | default {|x| $x} + ) $value + return [ $key $value ] } - | transpose -ird + | into record | load-env } ) diff --git a/modules/programs/discocss.nix b/modules/programs/discocss.nix index 5a35f187f..7fa2c7965 100644 --- a/modules/programs/discocss.nix +++ b/modules/programs/discocss.nix @@ -11,9 +11,9 @@ in { enable = mkEnableOption "discocss, a tiny Discord CSS injector for Linux and MacOS"; - package = mkPackageOption pkgs "discocss" { }; + package = mkPackageOption pkgs "discocss" { nullable = true; }; - discordPackage = mkPackageOption pkgs "discord" { }; + discordPackage = mkPackageOption pkgs "discord" { nullable = true; }; discordAlias = mkOption { type = types.bool; @@ -37,10 +37,10 @@ in { "To use discocss with discordAlias you have to remove discord from home.packages, or set discordAlias to false."; }]; - home.packages = [ + home.packages = lib.mkIf (cfg.package != null) [ (cfg.package.override { discordAlias = cfg.discordAlias; - discord = cfg.discordPackage; + discord = lib.mkIf (cfg.discordPackage != null) cfg.discordPackage; }) ]; diff --git a/modules/programs/earthly.nix b/modules/programs/earthly.nix new file mode 100644 index 000000000..a2b2a44c1 --- /dev/null +++ b/modules/programs/earthly.nix @@ -0,0 +1,40 @@ +{ config, lib, pkgs, ... }: + +let + + cfg = config.programs.earthly; + + yamlFormat = pkgs.formats.yaml { }; + +in { + meta.maintainers = [ lib.hm.maintainers.folliehiyuki ]; + + options.programs.earthly = { + enable = lib.mkEnableOption "earthly"; + + package = lib.mkPackageOption pkgs "earthly" { nullable = true; }; + + settings = lib.mkOption { + type = yamlFormat.type; + default = { }; + description = '' + Configuration written to ~/.earthly/config.yml file. + See https://docs.earthly.dev/docs/earthly-config for supported values. + ''; + example = lib.literalExpression '' + global = { + disable_analytics = true; + disable_log_sharing = true; + }; + ''; + }; + }; + + config = lib.mkIf cfg.enable { + home.packages = lib.mkIf (cfg.package != null) [ cfg.package ]; + + home.file.".earthly/config.yml" = lib.mkIf (cfg.settings != { }) { + source = yamlFormat.generate "earthly-config" cfg.settings; + }; + }; +} diff --git a/modules/programs/eww.nix b/modules/programs/eww.nix index 75a109226..2559068ad 100644 --- a/modules/programs/eww.nix +++ b/modules/programs/eww.nix @@ -24,7 +24,8 @@ in { }; configDir = mkOption { - type = types.path; + type = types.nullOr types.path; + default = null; example = literalExpression "./eww-config-dir"; description = '' The directory that gets symlinked to @@ -32,22 +33,20 @@ in { ''; }; - enableBashIntegration = mkEnableOption "Bash integration" // { - default = true; - }; + enableBashIntegration = + lib.hm.shell.mkBashIntegrationOption { inherit config; }; - enableZshIntegration = mkEnableOption "Zsh integration" // { - default = true; - }; + enableFishIntegration = + lib.hm.shell.mkFishIntegrationOption { inherit config; }; - enableFishIntegration = mkEnableOption "Fish integration" // { - default = true; - }; + enableZshIntegration = + lib.hm.shell.mkZshIntegrationOption { inherit config; }; }; config = mkIf cfg.enable { home.packages = [ cfg.package ]; - xdg.configFile."eww".source = cfg.configDir; + xdg = + mkIf (cfg.configDir != null) { configFile."eww".source = cfg.configDir; }; programs.bash.initExtra = mkIf cfg.enableBashIntegration '' if [[ $TERM != "dumb" ]]; then diff --git a/modules/programs/eza.nix b/modules/programs/eza.nix index d55d6f56e..14547d730 100644 --- a/modules/programs/eza.nix +++ b/modules/programs/eza.nix @@ -21,23 +21,20 @@ with lib; options.programs.eza = { enable = mkEnableOption "eza, a modern replacement for {command}`ls`"; - enableBashIntegration = mkEnableOption "Bash integration" // { - default = true; - }; + enableBashIntegration = + lib.hm.shell.mkBashIntegrationOption { inherit config; }; - enableZshIntegration = mkEnableOption "Zsh integration" // { - default = true; - }; + enableFishIntegration = + lib.hm.shell.mkFishIntegrationOption { inherit config; }; - enableFishIntegration = mkEnableOption "Fish integration" // { - default = true; - }; + enableIonIntegration = + lib.hm.shell.mkIonIntegrationOption { inherit config; }; - enableIonIntegration = mkEnableOption "Ion integration" // { - default = true; - }; + enableNushellIntegration = + lib.hm.shell.mkNushellIntegrationOption { inherit config; }; - enableNushellIntegration = mkEnableOption "Nushell integration"; + enableZshIntegration = + lib.hm.shell.mkZshIntegrationOption { inherit config; }; extraOptions = mkOption { type = types.listOf types.str; @@ -49,10 +46,21 @@ with lib; }; icons = mkOption { - type = types.bool; - default = false; + type = types.enum [ null true false "auto" "always" "never" ]; + default = null; description = '' Display icons next to file names ({option}`--icons` argument). + + Note, the support for Boolean values is deprecated. + Setting this option to `true` corresponds to `--icons=auto`. + ''; + }; + + colors = mkOption { + type = types.enum [ null "auto" "always" "never" ]; + default = null; + description = '' + Use terminal colors in output ({option}`--color` argument). ''; }; @@ -64,13 +72,21 @@ with lib; ''; }; - package = mkPackageOption pkgs "eza" { }; + package = mkPackageOption pkgs "eza" { nullable = true; }; }; config = let cfg = config.programs.eza; - args = escapeShellArgs (optional cfg.icons "--icons" + iconsOption = let + v = if isBool cfg.icons then + (if cfg.icons then "auto" else null) + else + cfg.icons; + in optionals (v != null) [ "--icons" v ]; + + args = escapeShellArgs (iconsOption + ++ optionals (cfg.colors != null) [ "--color" cfg.colors ] ++ optional cfg.git "--git" ++ cfg.extraOptions); optionsAlias = optionalAttrs (args != "") { eza = "eza ${args}"; }; @@ -83,7 +99,13 @@ with lib; lla = "eza -la"; }; in mkIf cfg.enable { - home.packages = [ cfg.package ]; + warnings = optional (isBool cfg.icons) '' + Setting programs.eza.icons to a Boolean is deprecated. + Please update your configuration so that + + programs.eza.icons = ${if cfg.icons then ''"auto"'' else "null"}''; + + home.packages = lib.mkIf (cfg.package != null) [ cfg.package ]; programs.bash.shellAliases = optionsAlias // optionalAttrs cfg.enableBashIntegration aliases; diff --git a/modules/programs/fastfetch.nix b/modules/programs/fastfetch.nix index 55a932f9a..abc4d7cda 100644 --- a/modules/programs/fastfetch.nix +++ b/modules/programs/fastfetch.nix @@ -7,12 +7,13 @@ let jsonFormat = pkgs.formats.json { }; in { - meta.maintainers = with lib.hm.maintainers; [ afresquet ]; + meta.maintainers = + [ lib.hm.maintainers.afresquet lib.maintainers.khaneliman ]; options.programs.fastfetch = { enable = mkEnableOption "Fastfetch"; - package = mkPackageOption pkgs "fastfetch" { }; + package = mkPackageOption pkgs "fastfetch" { nullable = true; }; settings = mkOption { type = jsonFormat.type; @@ -58,7 +59,7 @@ in { }; config = mkIf cfg.enable { - home.packages = [ cfg.package ]; + home.packages = lib.mkIf (cfg.package != null) [ cfg.package ]; xdg.configFile."fastfetch/config.jsonc" = mkIf (cfg.settings != { }) { source = jsonFormat.generate "config.jsonc" cfg.settings; diff --git a/modules/programs/fd.nix b/modules/programs/fd.nix index f8f59eb54..17911ebed 100644 --- a/modules/programs/fd.nix +++ b/modules/programs/fd.nix @@ -30,7 +30,7 @@ with lib; { ''; }; - package = mkPackageOption pkgs "fd" { }; + package = mkPackageOption pkgs "fd" { nullable = true; }; }; config = let @@ -40,7 +40,7 @@ with lib; { optionsAlias = optionalAttrs (args != "") { fd = "fd ${args}"; }; in mkIf cfg.enable { - home.packages = [ cfg.package ]; + home.packages = lib.mkIf (cfg.package != null) [ cfg.package ]; programs.bash.shellAliases = optionsAlias; diff --git a/modules/programs/feh.nix b/modules/programs/feh.nix index f44f184a3..b96c9a27a 100644 --- a/modules/programs/feh.nix +++ b/modules/programs/feh.nix @@ -8,6 +8,12 @@ let bindingsOf = t: with types; attrsOf (nullOr (either t (listOf t))); + renderThemes = options: + let + render = + mapAttrsToList (theme: options: "${theme} ${escapeShellArgs options}"); + in concatStringsSep "\n" (render options); + renderBindings = bindings: let enabled = filterAttrs (n: v: v != null) bindings; @@ -27,7 +33,7 @@ in { options.programs.feh = { enable = mkEnableOption "feh - a fast and light image viewer"; - package = mkPackageOption pkgs "feh" { }; + package = mkPackageOption pkgs "feh" { nullable = true; }; buttons = mkOption { default = { }; @@ -41,7 +47,7 @@ in { Override feh's default mouse button mapping. If you want to disable an action, set its value to null. If you want to bind multiple buttons to an action, set its value to a list. - See for + See for default bindings and available commands. ''; }; @@ -58,10 +64,37 @@ in { Override feh's default keybindings. If you want to disable a keybinding set its value to null. If you want to bind multiple keys to an action, set its value to a list. - See for + See for default bindings and available commands. ''; }; + + themes = mkOption { + default = { }; + type = with types; attrsOf (listOf str); + example = { + feh = [ "--image-bg" "black" ]; + webcam = [ "--multiwindow" "--reload" "20" ]; + present = [ "--full-screen" "--sort" "name" "--hide-pointer" ]; + booth = [ "--full-screen" "--hide-pointer" "--slideshow-delay" "20" ]; + imagemap = [ + "-rVq" + "--thumb-width" + "40" + "--thumb-height" + "30" + "--index-info" + "%n\\n%wx%h" + ]; + example = [ "--info" "foo bar" ]; + }; + description = '' + Define themes for feh. + See for + important guidelines and limitations related to theme configuration. + ''; + }; + }; config = mkIf cfg.enable { @@ -71,7 +104,7 @@ in { "To disable a keybinding, use `null` instead of an empty string."; }]; - home.packages = [ cfg.package ]; + home.packages = lib.mkIf (cfg.package != null) [ cfg.package ]; xdg.configFile."feh/buttons" = mkIf (cfg.buttons != { }) { text = renderBindings cfg.buttons + "\n"; }; @@ -79,5 +112,8 @@ in { xdg.configFile."feh/keys" = mkIf (cfg.keybindings != { }) { text = renderBindings cfg.keybindings + "\n"; }; + + xdg.configFile."feh/themes" = + mkIf (cfg.themes != { }) { text = renderThemes cfg.themes + "\n"; }; }; } diff --git a/modules/programs/firefox.nix b/modules/programs/firefox.nix index ac85990ff..01cab9bd8 100644 --- a/modules/programs/firefox.nix +++ b/modules/programs/firefox.nix @@ -1,18 +1,14 @@ { lib, ... }: - with lib; - let - modulePath = [ "programs" "firefox" ]; moduleName = concatStringsSep "." modulePath; mkFirefoxModule = import ./firefox/mkFirefoxModule.nix; - in { meta.maintainers = - [ maintainers.rycee maintainers.kira-bruneau hm.maintainers.bricked ]; + [ maintainers.rycee hm.maintainers.bricked hm.maintainers.HPsaucii ]; imports = [ (mkFirefoxModule { @@ -22,25 +18,20 @@ in { unwrappedPackageName = "firefox-unwrapped"; visible = true; - platforms.linux = rec { - vendorPath = ".mozilla"; - configPath = "${vendorPath}/firefox"; - }; + platforms.linux = rec { configPath = ".mozilla/firefox"; }; platforms.darwin = { - vendorPath = "Library/Application Support/Mozilla"; configPath = "Library/Application Support/Firefox"; }; }) (mkRemovedOptionModule (modulePath ++ [ "extensions" ]) '' - Extensions are now managed per-profile. That is, change from ${moduleName}.extensions = [ foo bar ]; to - ${moduleName}.profiles.myprofile.extensions = [ foo bar ];'') + ${moduleName}.profiles.myprofile.extensions.packages = [ foo bar ];'') (mkRemovedOptionModule (modulePath ++ [ "enableAdobeFlash" ]) "Support for this option has been removed.") (mkRemovedOptionModule (modulePath ++ [ "enableGoogleTalk" ]) diff --git a/modules/programs/firefox/mkFirefoxModule.nix b/modules/programs/firefox/mkFirefoxModule.nix index 2e4c23cde..733c8ec94 100644 --- a/modules/programs/firefox/mkFirefoxModule.nix +++ b/modules/programs/firefox/mkFirefoxModule.nix @@ -1,14 +1,13 @@ { modulePath, name, description ? null, wrappedPackageName ? null -, unwrappedPackageName ? null, platforms, visible ? false }: - +, unwrappedPackageName ? null, platforms, visible ? false +, enableBookmarks ? true, }: { config, lib, pkgs, ... }: - with lib; - let - inherit (pkgs.stdenv.hostPlatform) isDarwin; + appName = name; + moduleName = concatStringsSep "." modulePath; cfg = getAttrFromPath modulePath config; @@ -31,23 +30,6 @@ let profilesPath = if isDarwin then "${cfg.configPath}/Profiles" else cfg.configPath; - nativeMessagingHostsPath = if isDarwin then - "${cfg.vendorPath}/NativeMessagingHosts" - else - "${cfg.vendorPath}/native-messaging-hosts"; - - nativeMessagingHostsJoined = pkgs.symlinkJoin { - name = "ff_native-messaging-hosts"; - paths = [ - # Link a .keep file to keep the directory around - (pkgs.writeTextDir "lib/mozilla/native-messaging-hosts/.keep" "") - # Link package configured native messaging hosts (entire browser actually) - cfg.finalPackage - ] - # Link user configured native messaging hosts - ++ cfg.nativeMessagingHosts; - }; - # The extensions path shared by all profiles; will not be supported # by future browser versions. extensionPath = "extensions/{ec8030f7-c20a-464f-9b0e-13a3a9e97384}"; @@ -74,15 +56,19 @@ let else builtins.toJSON pref); - mkUserJs = prefs: extraPrefs: bookmarks: + mkUserJs = prePrefs: prefs: extraPrefs: bookmarks: extensions: let prefs' = lib.optionalAttrs ([ ] != bookmarks) { "browser.bookmarks.file" = toString (browserBookmarksFile bookmarks); "browser.places.importBookmarksHTML" = true; + } // lib.optionalAttrs (extensions != { }) { + "extensions.webextensions.ExtensionStorageIDB.enabled" = false; } // prefs; in '' // Generated by Home Manager. + ${prePrefs} + ${concatStrings (mapAttrsToList (name: value: '' user_pref("${name}", ${userPrefValue value}); '') prefs')} @@ -101,7 +87,7 @@ let }; in '' ${builtins.toJSON { - version = 4; + version = 5; lastUserContextId = foldlAttrs (acc: _: value: if value.id > acc then value.id else acc) 0 containers; @@ -198,7 +184,7 @@ let in { assertion = duplicates == { }; message = '' - Must not have a ${name} ${entityKind} with an existing ID but + Must not have a ${appName} ${entityKind} with an existing ID but '' + concatStringsSep "\n" (mapAttrsToList mkMsg duplicates); }); @@ -213,7 +199,6 @@ let # The configuration expected by the Firefox wrapper builder. bcfg = setAttrByPath [ browserName ] fcfg; - in if package == null then null else if isDarwin then @@ -222,10 +207,10 @@ let package.override (old: { cfg = old.cfg or { } // fcfg; extraPolicies = (old.extraPolicies or { }) // cfg.policies; + pkcs11Modules = (old.pkcs11Modules or [ ]) ++ cfg.pkcs11Modules; }) else (pkgs.wrapFirefox.override { config = bcfg; }) package { }; - in { options = setAttrByPath modulePath { enable = mkOption { @@ -233,11 +218,11 @@ in { default = false; example = true; description = '' - Whether to enable ${name}.${ + Whether to enable ${appName}.${ optionalString (description != null) " ${description}" } ${optionalString (!visible) - "See `programs.firefox` for more configuration options."} + "See `${moduleName}` for more configuration options."} ''; }; @@ -258,10 +243,10 @@ in { } ''; description = '' - The ${name} package to use. If state version ≥ 19.09 then - this should be a wrapped ${name} package. For earlier state - versions it should be an unwrapped ${name} package. - Set to `null` to disable installing ${name}. + The ${appName} package to use. If state version ≥ 19.09 then + this should be a wrapped ${appName} package. For earlier state + versions it should be an unwrapped ${appName} package. + Set to `null` to disable installing ${appName}. ''; }; @@ -272,7 +257,7 @@ in { The language packs to install. Available language codes can be found on the releases page: `https://releases.mozilla.org/pub/firefox/releases/''${version}/linux-x86_64/xpi/`, - replacing `''${version}` with the version of Firefox you have. + replacing `''${version}` with the version of ${appName} you have. ''; example = [ "en-GB" "de" ]; }; @@ -295,11 +280,7 @@ in { vendorPath = mkOption { internal = true; type = with types; nullOr str; - default = with platforms; - if isDarwin then - darwin.vendorPath or null - else - linux.vendorPath or null; + default = null; example = ".mozilla"; description = "Directory containing the native messaging hosts directory."; @@ -311,24 +292,24 @@ in { default = with platforms; if isDarwin then darwin.configPath else linux.configPath; example = ".mozilla/firefox"; - description = "Directory containing the ${name} configuration files."; + description = "Directory containing the ${appName} configuration files."; }; - nativeMessagingHosts = optionalAttrs (cfg.vendorPath != null) (mkOption { + nativeMessagingHosts = mkOption { inherit visible; type = types.listOf types.package; default = [ ]; description = '' Additional packages containing native messaging hosts that should be - made available to ${name} extensions. + made available to ${appName} extensions. ''; - }); + }; finalPackage = mkOption { inherit visible; type = with types; nullOr package; readOnly = true; - description = "Resulting ${cfg.name} package."; + description = "Resulting ${appName} package."; }; policies = optionalAttrs (wrappedPackageName != null) (mkOption { @@ -368,10 +349,24 @@ in { ''; }; + preConfig = mkOption { + type = types.lines; + default = ""; + description = '' + Extra preferences to add to {file}`user.js`, before + [](#opt-programs.firefox.profiles._name_.settings). + + Use [](#opt-programs.firefox.profiles._name_.extraConfig), unless + you want to overwrite in + [](#opt-programs.firefox.profiles._name_.settings), then use this + option. + ''; + }; + settings = mkOption { type = types.attrsOf (jsonFormat.type // { description = - "${name} preference (int, bool, string, and also attrs, list, float as a JSON string)"; + "${appName} preference (int, bool, string, and also attrs, list, float as a JSON string)"; }); default = { }; example = literalExpression '' @@ -389,9 +384,9 @@ in { } ''; description = '' - Attribute set of ${name} preferences. + Attribute set of ${appName} preferences. - ${name} only supports int, bool, and string types for + ${appName} only supports int, bool, and string types for preferences, but home-manager will automatically convert all other JSON-compatible values into strings. ''; @@ -406,9 +401,9 @@ in { }; userChrome = mkOption { - type = types.lines; + type = types.oneOf [ types.lines types.path ]; default = ""; - description = "Custom ${name} user chrome CSS."; + description = "Custom ${appName} user chrome CSS."; example = '' /* Hide tab bar in FF Quantum */ @-moz-document url(chrome://browser/content/browser.xul), url(chrome://browser/content/browser.xhtml) { @@ -425,9 +420,9 @@ in { }; userContent = mkOption { - type = types.lines; + type = types.oneOf [ types.lines types.path ]; default = ""; - description = "Custom ${name} user content CSS."; + description = "Custom ${appName} user content CSS."; example = '' /* Hide scrollbar in FF Quantum */ *{scrollbar-width:none !important} @@ -435,6 +430,7 @@ in { }; bookmarks = mkOption { + internal = !enableBookmarks; type = let bookmarkSubmodule = types.submodule ({ config, name, ... }: { options = { @@ -547,93 +543,17 @@ in { description = "Whether this is a default profile."; }; - search = { - force = mkOption { - type = with types; bool; - default = false; - description = '' - Whether to force replace the existing search - configuration. This is recommended since ${name} will - replace the symlink for the search configuration on every - launch, but note that you'll lose any existing - configuration by enabling this. - ''; - }; - - default = mkOption { - type = with types; nullOr str; - default = null; - example = "DuckDuckGo"; - description = '' - The default search engine used in the address bar and search bar. - ''; - }; - - privateDefault = mkOption { - type = with types; nullOr str; - default = null; - example = "DuckDuckGo"; - description = '' - The default search engine used in the Private Browsing. - ''; - }; - - order = mkOption { - type = with types; uniq (listOf str); - default = [ ]; - example = [ "DuckDuckGo" "Google" ]; - description = '' - The order the search engines are listed in. Any engines - that aren't included in this list will be listed after - these in an unspecified order. - ''; - }; - - engines = mkOption { - type = with types; attrsOf (attrsOf jsonFormat.type); - default = { }; - example = literalExpression '' - { - "Nix Packages" = { - urls = [{ - template = "https://search.nixos.org/packages"; - params = [ - { name = "type"; value = "packages"; } - { name = "query"; value = "{searchTerms}"; } - ]; - }]; - - icon = "''${pkgs.nixos-icons}/share/icons/hicolor/scalable/apps/nix-snowflake.svg"; - definedAliases = [ "@np" ]; - }; - - "NixOS Wiki" = { - urls = [{ template = "https://wiki.nixos.org/index.php?search={searchTerms}"; }]; - iconUpdateURL = "https://wiki.nixos.org/favicon.png"; - updateInterval = 24 * 60 * 60 * 1000; # every day - definedAliases = [ "@nw" ]; - }; - - "Bing".metaData.hidden = true; - "Google".metaData.alias = "@g"; # builtin engines only support specifying one additional alias - } - ''; - description = '' - Attribute set of search engine configurations. Engines - that only have {var}`metaData` specified will - be treated as builtin to ${name}. - - See [SearchEngine.jsm](https://searchfox.org/mozilla-central/rev/669329e284f8e8e2bb28090617192ca9b4ef3380/toolkit/components/search/SearchEngine.jsm#1138-1177) - in Firefox's source for available options. We maintain a - mapping to let you specify all options in the referenced - link without underscores, but it may fall out of date with - future options. - - Note, {var}`icon` is also a special option - added by Home Manager to make it convenient to specify - absolute icon paths. - ''; - }; + search = mkOption { + type = types.submodule (args: + import ./profiles/search.nix { + inherit (args) config; + inherit lib pkgs appName; + package = cfg.finalPackage; + modulePath = modulePath ++ [ "profiles" name "search" ]; + profilePath = config.path; + }); + default = { }; + description = "Declarative search engine configuration."; }; containersForce = mkOption { @@ -641,7 +561,7 @@ in { default = false; description = '' Whether to force replace the existing containers configuration. - This is recommended since Firefox will replace the symlink on + This is recommended since ${appName} will replace the symlink on every launch, but note that you'll lose any existing configuration by enabling this. ''; @@ -723,41 +643,129 @@ in { for more information. ''; }; - extensions = mkOption { - type = types.listOf types.package; - default = [ ]; - example = literalExpression '' - with pkgs.nur.repos.rycee.firefox-addons; [ - privacy-badger - ] - ''; + type = types.coercedTo (types.listOf types.package) (packages: { + packages = mkIf (builtins.length packages > 0) (warn '' + In order to support declarative extension configuration, + extension installation has been moved from + ${moduleName}.profiles..extensions + to + ${moduleName}.profiles..extensions.packages + '' packages); + }) (types.submodule { + options = { + packages = mkOption { + type = types.listOf types.package; + default = [ ]; + example = literalExpression '' + with pkgs.nur.repos.rycee.firefox-addons; [ + privacy-badger + ] + ''; + description = '' + List of ${name} add-on packages to install for this profile. + Some pre-packaged add-ons are accessible from the Nix User Repository. + Once you have NUR installed run + + ```console + $ nix-env -f '' -qaP -A nur.repos.rycee.firefox-addons + ``` + + to list the available ${name} add-ons. + + Note that it is necessary to manually enable these extensions + inside ${name} after the first installation. + + To automatically enable extensions add + `"extensions.autoDisableScopes" = 0;` + to + [{option}`${moduleName}.profiles..settings`](#opt-${moduleName}.profiles._name_.settings) + ''; + }; + + force = mkOption { + description = '' + Whether to override all previous firefox settings. + + This is required when using `settings`. + ''; + default = false; + example = true; + type = types.bool; + }; + + settings = mkOption { + default = { }; + example = literalExpression '' + { + # Example with uBlock origin's extensionID + "uBlock0@raymondhill.net".settings = { + selectedFilterLists = [ + "ublock-filters" + "ublock-badware" + "ublock-privacy" + "ublock-unbreak" + "ublock-quick-fixes" + ]; + }; + + # Example with Stylus' UUID-form extensionID + "{7a7a4a92-a2a0-41d1-9fd7-1e92480d612d}".settings = { + dbInChromeStorage = true; # required for Stylus + } + } + ''; + description = '' + Attribute set of options for each extension. + The keys of the attribute set consist of the ID of the extension + or its UUID wrapped in curly braces. + ''; + type = types.attrsOf (types.submodule { + options = { + settings = mkOption { + type = types.attrsOf jsonFormat.type; + description = + "Json formatted options for the specified extensionID"; + }; + force = mkOption { + type = types.bool; + default = false; + example = true; + description = '' + Forcibly override any existing configuration for + this extension. + ''; + }; + }; + }); + }; + }; + }); + default = { }; description = '' - List of ${name} add-on packages to install for this profile. - Some pre-packaged add-ons are accessible from the - [Nix User Repository](https://github.com/nix-community/NUR). - Once you have NUR installed run - - ```console - $ nix-env -f '' -qaP -A nur.repos.rycee.firefox-addons - ``` - - to list the available ${name} add-ons. - - Note that it is necessary to manually enable these extensions - inside ${name} after the first installation. - - To automatically enable extensions add - `"extensions.autoDisableScopes" = 0;` - to - [{option}`${moduleName}.profiles..settings`](#opt-${moduleName}.profiles._name_.settings) + Submodule for installing and configuring extensions. + ''; + example = literalExpression '' + { + packages = with pkgs.nur.repos.rycee.firefox-addons; [ + ublock-origin + ]; + settings."uBlock0@raymondhill.net".settings = { + selectedFilterLists = [ + "ublock-filters" + "ublock-badware" + "ublock-privacy" + "ublock-unbreak" + "ublock-quick-fixes" + ]; + }; + } ''; }; - }; })); default = { }; - description = "Attribute set of ${name} profiles."; + description = "Attribute set of ${appName} profiles."; }; enableGnomeExtensions = mkOption { @@ -771,6 +779,14 @@ in { `true`. ''; }; + + pkcs11Modules = mkOption { + type = types.listOf types.package; + default = [ ]; + description = '' + Additional packages to be loaded as PKCS #11 modules in Firefox. + ''; + }; }; config = mkIf cfg.enable ({ @@ -782,7 +798,7 @@ in { catAttrs "name" (filter (a: a.isDefault) (attrValues cfg.profiles)); in { assertion = cfg.profiles == { } || length defaults == 1; - message = "Must have exactly one default ${cfg.name} profile but found " + message = "Must have exactly one default ${appName} profile but found " + toString (length defaults) + optionalString (length defaults > 1) (", namely " + concatStringsSep ", " defaults); }) @@ -804,7 +820,7 @@ in { { assertion = cfg.languagePacks == [ ] || cfg.package != null; message = '' - 'programs.firefox.languagePacks' requires 'programs.firefox.package' + '${moduleName}.languagePacks' requires '${moduleName}.package' to be set to a non-null value. ''; } @@ -812,217 +828,112 @@ in { (mkNoDuplicateAssertion cfg.profiles "profile") ] ++ (mapAttrsToList (_: profile: mkNoDuplicateAssertion profile.containers "container") - cfg.profiles); + cfg.profiles) ++ (mapAttrsToList (profileName: profile: { + assertion = profile.extensions.settings == { } + || profile.extensions.force; + message = '' + Using '${ + lib.showAttrPath + (modulePath ++ [ "profiles" profileName "extensions" "settings" ]) + }' will override all previous extensions settings. + Enable '${ + lib.showAttrPath + (modulePath ++ [ "profiles" profileName "extensions" "force" ]) + }' to acknowledge this. + ''; + }) cfg.profiles); warnings = optional (cfg.enableGnomeExtensions or false) '' Using '${moduleName}.enableGnomeExtensions' has been deprecated and will be removed in the future. Please change to overriding the package configuration using '${moduleName}.package' instead. You can refer to its example for how to do this. + '' ++ optional (cfg.vendorPath != null) '' + Using '${moduleName}.vendorPath' has been deprecated and + will be removed in the future. Native messaging hosts will function normally without specifying this path. ''; home.packages = lib.optional (cfg.finalPackage != null) cfg.finalPackage; + mozilla.firefoxNativeMessagingHosts = cfg.nativeMessagingHosts + # package configured native messaging hosts (entire browser actually) + ++ (lib.optional (cfg.finalPackage != null) cfg.finalPackage); + home.file = mkMerge ([{ "${cfg.configPath}/profiles.ini" = mkIf (cfg.profiles != { }) { text = profilesIni; }; - }] ++ optional (cfg.vendorPath != null) { - "${nativeMessagingHostsPath}" = { - source = - "${nativeMessagingHostsJoined}/lib/mozilla/native-messaging-hosts"; - recursive = true; - }; - } ++ flip mapAttrsToList cfg.profiles (_: profile: { - "${profilesPath}/${profile.path}/.keep".text = ""; + }] ++ flip mapAttrsToList cfg.profiles (_: profile: + # Merge the regular profile settings with extension settings + mkMerge ([{ + "${profilesPath}/${profile.path}/.keep".text = ""; - "${profilesPath}/${profile.path}/chrome/userChrome.css" = - mkIf (profile.userChrome != "") { text = profile.userChrome; }; + "${profilesPath}/${profile.path}/chrome/userChrome.css" = + mkIf (profile.userChrome != "") (let + key = + if builtins.isString profile.userChrome then "text" else "source"; + in { "${key}" = profile.userChrome; }); - "${profilesPath}/${profile.path}/chrome/userContent.css" = - mkIf (profile.userContent != "") { text = profile.userContent; }; + "${profilesPath}/${profile.path}/chrome/userContent.css" = + mkIf (profile.userContent != "") (let + key = if builtins.isString profile.userContent then + "text" + else + "source"; + in { "${key}" = profile.userContent; }); - "${profilesPath}/${profile.path}/user.js" = mkIf (profile.settings != { } - || profile.extraConfig != "" || profile.bookmarks != [ ]) { - text = - mkUserJs profile.settings profile.extraConfig profile.bookmarks; - }; - - "${profilesPath}/${profile.path}/containers.json" = - mkIf (profile.containers != { }) { - text = mkContainersJson profile.containers; - force = profile.containersForce; - }; - - "${profilesPath}/${profile.path}/search.json.mozlz4" = mkIf - (profile.search.default != null || profile.search.privateDefault != null - || profile.search.order != [ ] || profile.search.engines != { }) { - force = profile.search.force; - source = let - settings = { - version = 6; - engines = let - # Map of nice field names to internal field names. - # This is intended to be exhaustive and should be - # updated at every version bump. - internalFieldNames = (genAttrs [ - "name" - "isAppProvided" - "loadPath" - "hasPreferredIcon" - "updateInterval" - "updateURL" - "iconUpdateURL" - "iconURL" - "iconMapObj" - "metaData" - "orderHint" - "definedAliases" - "urls" - ] (name: "_${name}")) // { - searchForm = "__searchForm"; - }; - - processCustomEngineInput = input: - (removeAttrs input [ "icon" ]) - // optionalAttrs (input ? icon) { - # Convenience to specify absolute path to icon - iconURL = "file://${input.icon}"; - } // (optionalAttrs (input ? iconUpdateURL) { - # Convenience to default iconURL to iconUpdateURL so - # the icon is immediately downloaded from the URL - iconURL = input.iconURL or input.iconUpdateURL; - } // { - # Required for custom engine configurations, loadPaths - # are unique identifiers that are generally formatted - # like: [source]/path/to/engine.xml - loadPath = '' - [home-manager]/${moduleName}.profiles.${profile.name}.search.engines."${ - replaceStrings [ "\\" ] [ "\\\\" ] input.name - }"''; - }); - - processEngineInput = name: input: - let - requiredInput = { - inherit name; - isAppProvided = input.isAppProvided or removeAttrs input - [ "metaData" ] == { }; - metaData = input.metaData or { }; - }; - in if requiredInput.isAppProvided then - requiredInput - else - processCustomEngineInput (input // requiredInput); - - buildEngineConfig = name: input: - mapAttrs' (name: value: { - name = internalFieldNames.${name} or name; - inherit value; - }) (processEngineInput name input); - - sortEngineConfigs = configs: - let - buildEngineConfigWithOrder = order: name: - let - config = configs.${name} or { - _name = name; - _isAppProvided = true; - _metaData = { }; - }; - in config // { - _metaData = config._metaData // { inherit order; }; - }; - - engineConfigsWithoutOrder = - attrValues (removeAttrs configs profile.search.order); - - sortedEngineConfigs = - (imap buildEngineConfigWithOrder profile.search.order) - ++ engineConfigsWithoutOrder; - in sortedEngineConfigs; - - engineInput = profile.search.engines // { - # Infer profile.search.default as an app provided - # engine if it's not in profile.search.engines - ${profile.search.default} = - profile.search.engines.${profile.search.default} or { }; - } // { - ${profile.search.privateDefault} = - profile.search.engines.${profile.search.privateDefault} or { }; - }; - in sortEngineConfigs (mapAttrs buildEngineConfig engineInput); - - metaData = optionalAttrs (profile.search.default != null) { - current = profile.search.default; - hash = "@hash@"; - } // optionalAttrs (profile.search.privateDefault != null) { - private = profile.search.privateDefault; - privateHash = "@privateHash@"; - } // { - useSavedOrder = profile.search.order != [ ]; - }; - }; - - # Home Manager doesn't circumvent user consent and isn't acting - # maliciously. We're modifying the search outside of the browser, but - # a claim by Mozilla to remove this would be very anti-user, and - # is unlikely to be an issue for our use case. - disclaimer = appName: - "By modifying this file, I agree that I am doing so " - + "only within ${appName} itself, using official, user-driven search " - + "engine selection processes, and in a way which does not circumvent " - + "user consent. I acknowledge that any attempt to change this file " - + "from outside of ${appName} is a malicious act, and will be responded " - + "to accordingly."; - - salt = if profile.search.default != null then - profile.path + profile.search.default + disclaimer cfg.name - else - null; - - privateSalt = if profile.search.privateDefault != null then - profile.path + profile.search.privateDefault - + disclaimer cfg.name - else - null; - in pkgs.runCommand "search.json.mozlz4" { - nativeBuildInputs = with pkgs; [ mozlz4a openssl ]; - json = builtins.toJSON settings; - inherit salt privateSalt; - } '' - if [[ -n $salt ]]; then - export hash=$(echo -n "$salt" | openssl dgst -sha256 -binary | base64) - export privateHash=$(echo -n "$privateSalt" | openssl dgst -sha256 -binary | base64) - mozlz4a <(substituteStream json search.json.in --subst-var hash --subst-var privateHash) "$out" - else - mozlz4a <(echo "$json") "$out" - fi - ''; + "${profilesPath}/${profile.path}/user.js" = mkIf (profile.preConfig + != "" || profile.settings != { } || profile.extraConfig != "" + || profile.bookmarks != [ ]) { + text = + mkUserJs profile.preConfig profile.settings profile.extraConfig + profile.bookmarks profile.extensions.settings; }; - "${profilesPath}/${profile.path}/extensions" = - mkIf (profile.extensions != [ ]) { - source = let - extensionsEnvPkg = pkgs.buildEnv { - name = "hm-firefox-extensions"; - paths = profile.extensions; - }; - in "${extensionsEnvPkg}/share/mozilla/${extensionPath}"; - recursive = true; - force = true; - }; - })); + "${profilesPath}/${profile.path}/containers.json" = + mkIf (profile.containers != { }) { + text = mkContainersJson profile.containers; + force = profile.containersForce; + }; + + "${profilesPath}/${profile.path}/search.json.mozlz4" = + mkIf (profile.search.enable) { + enable = profile.search.enable; + force = profile.search.force; + source = profile.search.file; + }; + + "${profilesPath}/${profile.path}/extensions" = + mkIf (profile.extensions.packages != [ ]) { + source = let + extensionsEnvPkg = pkgs.buildEnv { + name = "hm-firefox-extensions"; + paths = profile.extensions.packages; + }; + in "${extensionsEnvPkg}/share/mozilla/${extensionPath}"; + recursive = true; + force = true; + }; + }] ++ + # Add extension settings as separate attributes + optional (profile.extensions.settings != { }) (mkMerge (mapAttrsToList + (name: settingConfig: { + "${profilesPath}/${profile.path}/browser-extension-data/${name}/storage.js" = + { + force = settingConfig.force || profile.extensions.force; + text = generators.toJSON { } settingConfig.settings; + }; + }) profile.extensions.settings))))); } // setAttrByPath modulePath { finalPackage = wrapPackage cfg.package; policies = { - ExtensionSettings = listToAttrs (map (lang: - nameValuePair "langpack-${lang}@firefox.mozilla.org" { - installation_mode = "normal_installed"; - install_url = - "https://releases.mozilla.org/pub/firefox/releases/${cfg.package.version}/linux-x86_64/xpi/${lang}.xpi"; - }) cfg.languagePacks); + ExtensionSettings = lib.mkIf (cfg.languagePacks != [ ]) (listToAttrs (map + (lang: + nameValuePair "langpack-${lang}@firefox.mozilla.org" { + installation_mode = "normal_installed"; + install_url = + "https://releases.mozilla.org/pub/firefox/releases/${cfg.package.version}/linux-x86_64/xpi/${lang}.xpi"; + }) cfg.languagePacks)); }; }); } - diff --git a/modules/programs/firefox/profiles/search.nix b/modules/programs/firefox/profiles/search.nix new file mode 100644 index 000000000..f0d5f5a30 --- /dev/null +++ b/modules/programs/firefox/profiles/search.nix @@ -0,0 +1,269 @@ +{ config, lib, pkgs, appName, package, modulePath, profilePath }: + +with lib; + +let + jsonFormat = pkgs.formats.json { }; + + # Map of nice field names to internal field names. + # This is intended to be exhaustive and should be + # updated at every version bump. + internalFieldNames = (genAttrs [ + "name" + "isAppProvided" + "loadPath" + "hasPreferredIcon" + "updateInterval" + "updateURL" + "iconUpdateURL" + "iconURL" + "iconMapObj" + "metaData" + "orderHint" + "definedAliases" + "urls" + ] (name: "_${name}")) // { + searchForm = "__searchForm"; + }; + + processCustomEngineInput = input: + (removeAttrs input [ "icon" ]) // optionalAttrs (input ? icon) { + # Convenience to specify absolute path to icon + iconURL = "file://${input.icon}"; + } // (optionalAttrs (input ? iconUpdateURL) { + # Convenience to default iconURL to iconUpdateURL so + # the icon is immediately downloaded from the URL + iconURL = input.iconURL or input.iconUpdateURL; + } // { + # Required for custom engine configurations, loadPaths + # are unique identifiers that are generally formatted + # like: [source]/path/to/engine.xml + loadPath = "[home-manager]/${ + concatStringsSep "." (map strings.escapeNixIdentifier + (modulePath ++ [ "engines" input.name ])) + }"; + }); + + processEngineInput = name: input: + let + requiredInput = { + inherit name; + isAppProvided = + input.isAppProvided or (removeAttrs input [ "metaData" ] == { }); + metaData = input.metaData or { }; + }; + in if requiredInput.isAppProvided then + requiredInput + else + processCustomEngineInput (input // requiredInput); + + buildEngineConfig = name: input: + mapAttrs' (name: value: { + name = internalFieldNames.${name} or name; + inherit value; + }) (processEngineInput name input); + + sortEngineConfigs = configs: + let + buildEngineConfigWithOrder = order: name: + let + config = configs.${name} or { + _name = name; + _isAppProvided = true; + _metaData = { }; + }; + in config // { _metaData = config._metaData // { inherit order; }; }; + + engineConfigsWithoutOrder = attrValues (removeAttrs configs config.order); + + sortedEngineConfigs = (imap buildEngineConfigWithOrder config.order) + ++ engineConfigsWithoutOrder; + in sortedEngineConfigs; + + engineInput = config.engines // { + # Infer config.default as an app provided + # engine if it's not in config.engines + ${config.default} = config.engines.${config.default} or { }; + } // { + ${config.privateDefault} = config.engines.${config.privateDefault} or { }; + }; + + settings = { + version = 6; + engines = sortEngineConfigs (mapAttrs buildEngineConfig engineInput); + + metaData = optionalAttrs (config.default != null) { + current = config.default; + hash = "@hash@"; + } // optionalAttrs (config.privateDefault != null) { + private = config.privateDefault; + privateHash = "@privateHash@"; + } // { + useSavedOrder = config.order != [ ]; + }; + }; + + # Home Manager doesn't circumvent user consent and isn't acting + # maliciously. We're modifying the search outside of the browser, but + # a claim by Mozilla to remove this would be very anti-user, and + # is unlikely to be an issue for our use case. + disclaimer = "By modifying this file, I agree that I am doing so " + + "only within @appName@ itself, using official, user-driven search " + + "engine selection processes, and in a way which does not circumvent " + + "user consent. I acknowledge that any attempt to change this file " + + "from outside of @appName@ is a malicious act, and will be responded " + + "to accordingly."; + + salt = if config.default != null then + profilePath + config.default + disclaimer + else + null; + + privateSalt = if config.privateDefault != null then + profilePath + config.privateDefault + disclaimer + else + null; + + appNameVariable = if package == null then + "appName=${lib.escapeShellArg appName}" + else '' + applicationIni="$(find ${lib.escapeShellArg package} -maxdepth 3 -path ${ + lib.escapeShellArg package + }'/lib/*/application.ini' -print -quit)" + if test -n "$applicationIni"; then + appName="$(sed -n 's/^Name=\(.*\)$/\1/p' "$applicationIni" | head -n1)" + else + appName=${lib.escapeShellArg appName} + fi + ''; + + file = pkgs.runCommand "search.json.mozlz4" { + nativeBuildInputs = with pkgs; [ mozlz4a openssl ]; + json = builtins.toJSON settings; + inherit salt privateSalt; + } '' + ${appNameVariable} + + salt=''${salt//@appName@/"$appName"} + privateSalt=''${privateSalt//@appName@/"$appName"} + + if [[ -n $salt ]]; then + export hash=$(echo -n "$salt" | openssl dgst -sha256 -binary | base64) + export privateHash=$(echo -n "$privateSalt" | openssl dgst -sha256 -binary | base64) + mozlz4a <(substituteStream json search.json.in --subst-var hash --subst-var privateHash) "$out" + else + mozlz4a <(echo "$json") "$out" + fi + ''; +in { + imports = [ (pkgs.path + "/nixos/modules/misc/meta.nix") ]; + + meta.maintainers = with maintainers; [ kira-bruneau ]; + + options = { + enable = mkOption { + type = with types; bool; + default = config.default != null || config.privateDefault != null + || config.order != [ ] || config.engines != { }; + internal = true; + }; + + force = mkOption { + type = with types; bool; + default = false; + description = '' + Whether to force replace the existing search + configuration. This is recommended since ${appName} will + replace the symlink for the search configuration on every + launch, but note that you'll lose any existing configuration + by enabling this. + ''; + }; + + default = mkOption { + type = with types; nullOr str; + default = null; + example = "DuckDuckGo"; + description = '' + The default search engine used in the address bar and search + bar. + ''; + }; + + privateDefault = mkOption { + type = with types; nullOr str; + default = null; + example = "DuckDuckGo"; + description = '' + The default search engine used in the Private Browsing. + ''; + }; + + order = mkOption { + type = with types; uniq (listOf str); + default = [ ]; + example = [ "DuckDuckGo" "Google" ]; + description = '' + The order the search engines are listed in. Any engines that + aren't included in this list will be listed after these in an + unspecified order. + ''; + }; + + engines = mkOption { + type = with types; attrsOf (attrsOf jsonFormat.type); + default = { }; + example = literalExpression '' + { + "Nix Packages" = { + urls = [{ + template = "https://search.nixos.org/packages"; + params = [ + { name = "type"; value = "packages"; } + { name = "query"; value = "{searchTerms}"; } + ]; + }]; + + icon = "''${pkgs.nixos-icons}/share/icons/hicolor/scalable/apps/nix-snowflake.svg"; + definedAliases = [ "@np" ]; + }; + + "NixOS Wiki" = { + urls = [{ template = "https://wiki.nixos.org/index.php?search={searchTerms}"; }]; + iconUpdateURL = "https://wiki.nixos.org/favicon.png"; + updateInterval = 24 * 60 * 60 * 1000; # every day + definedAliases = [ "@nw" ]; + }; + + "Bing".metaData.hidden = true; + "Google".metaData.alias = "@g"; # builtin engines only support specifying one additional alias + } + ''; + + description = '' + Attribute set of search engine configurations. Engines that + only have {var}`metaData` specified will be treated as builtin + to ${appName}. + + See [SearchEngine.jsm](https://searchfox.org/mozilla-central/rev/669329e284f8e8e2bb28090617192ca9b4ef3380/toolkit/components/search/SearchEngine.jsm#1138-1177) + in ${appName}'s source for available options. We maintain a + mapping to let you specify all options in the referenced link + without underscores, but it may fall out of date with future + options. + + Note, {var}`icon` is also a special option added by Home + Manager to make it convenient to specify absolute icon paths. + ''; + }; + + file = mkOption { + type = with types; path; + default = file; + internal = true; + readOnly = true; + description = '' + Resulting search.json.mozlz4 file. + ''; + }; + }; +} diff --git a/modules/programs/fish.nix b/modules/programs/fish.nix index 8cd7f9f92..1fb313a86 100644 --- a/modules/programs/fish.nix +++ b/modules/programs/fish.nix @@ -66,7 +66,7 @@ let }; onEvent = mkOption { - type = with types; nullOr str; + type = with types; nullOr (either str (listOf str)); default = null; description = '' Tells fish to run this function when the specified named event is @@ -253,6 +253,12 @@ in { ''; }; + generateCompletions = mkEnableOption + "the automatic generation of completions based upon installed man pages" + // { + default = true; + }; + shellAliases = mkOption { type = with types; attrsOf str; default = { }; @@ -390,9 +396,9 @@ in { }; config = mkIf cfg.enable (mkMerge [ - { - home.packages = [ cfg.package ]; + { home.packages = [ cfg.package ]; } + (mkIf cfg.generateCompletions { # Support completion for `man` by building a cache for `apropos`. programs.man.generateCaches = mkDefault true; @@ -456,7 +462,9 @@ in { set fish_complete_path $prev "${config.xdg.dataHome}/fish/home-manager_generated_completions" $post end ''; + }) + { xdg.configFile."fish/config.fish".source = fishIndent "config.fish" '' # ~/.config/fish/config.fish: DO NOT EDIT -- this file has been generated # automatically by home-manager. @@ -503,7 +511,7 @@ in { mods = with def; modifierStr "description" description ++ modifierStr "wraps" wraps - ++ modifierStr "on-event" onEvent + ++ lib.concatMap (modifierStr "on-event") (lib.toList onEvent) ++ modifierStr "on-variable" onVariable ++ modifierStr "on-job-exit" onJobExit ++ modifierStr "on-process-exit" onProcessExit diff --git a/modules/programs/floorp.nix b/modules/programs/floorp.nix new file mode 100644 index 000000000..75616b7ee --- /dev/null +++ b/modules/programs/floorp.nix @@ -0,0 +1,26 @@ +{ lib, ... }: + +with lib; + +let + + modulePath = [ "programs" "floorp" ]; + + mkFirefoxModule = import ./firefox/mkFirefoxModule.nix; + +in { + meta.maintainers = [ hm.maintainers.bricked ]; + + imports = [ + (mkFirefoxModule { + inherit modulePath; + name = "Floorp"; + wrappedPackageName = "floorp"; + unwrappedPackageName = "floorp-unwrapped"; + visible = true; + + platforms.linux = { configPath = ".floorp"; }; + platforms.darwin = { configPath = "Library/Application Support/Floorp"; }; + }) + ]; +} diff --git a/modules/programs/freetube.nix b/modules/programs/freetube.nix index 77700fe55..c2df1163a 100644 --- a/modules/programs/freetube.nix +++ b/modules/programs/freetube.nix @@ -21,7 +21,7 @@ in { options.programs.freetube = { enable = mkEnableOption "FreeTube, a YT client for Windows, Mac, and Linux"; - package = mkPackageOption pkgs "freetube" { }; + package = mkPackageOption pkgs "freetube" { nullable = true; }; settings = mkOption { type = lib.types.attrs; @@ -44,7 +44,7 @@ in { }; config = mkIf cfg.enable { - home.packages = [ cfg.package ]; + home.packages = lib.mkIf (cfg.package != null) [ cfg.package ]; xdg.configFile."FreeTube/hm_settings.db" = { source = pkgs.writeText "hm_settings.db" (settings cfg.settings); diff --git a/modules/programs/fuzzel.nix b/modules/programs/fuzzel.nix index 5057c36d6..95c12c836 100644 --- a/modules/programs/fuzzel.nix +++ b/modules/programs/fuzzel.nix @@ -14,7 +14,7 @@ in { options.programs.fuzzel = { enable = mkEnableOption "fuzzel"; - package = mkPackageOption pkgs "fuzzel" { }; + package = mkPackageOption pkgs "fuzzel" { nullable = true; }; settings = mkOption { type = iniFormat.type; @@ -42,7 +42,7 @@ in { lib.platforms.linux) ]; - home.packages = [ cfg.package ]; + home.packages = lib.mkIf (cfg.package != null) [ cfg.package ]; xdg.configFile."fuzzel/fuzzel.ini" = mkIf (cfg.settings != { }) { source = iniFormat.generate "fuzzel.ini" cfg.settings; diff --git a/modules/programs/fzf.nix b/modules/programs/fzf.nix index 31df95de6..6f45682ca 100644 --- a/modules/programs/fzf.nix +++ b/modules/programs/fzf.nix @@ -45,6 +45,8 @@ in { "This option is no longer supported by fzf.") ]; + meta.maintainers = with lib.maintainers; [ khaneliman ]; + options.programs.fzf = { enable = mkEnableOption "fzf - a command-line fuzzy finder"; @@ -156,29 +158,14 @@ in { }; }; - enableBashIntegration = mkOption { - default = true; - type = types.bool; - description = '' - Whether to enable Bash integration. - ''; - }; + enableBashIntegration = + lib.hm.shell.mkBashIntegrationOption { inherit config; }; - enableZshIntegration = mkOption { - default = true; - type = types.bool; - description = '' - Whether to enable Zsh integration. - ''; - }; + enableFishIntegration = + lib.hm.shell.mkFishIntegrationOption { inherit config; }; - enableFishIntegration = mkOption { - default = true; - type = types.bool; - description = '' - Whether to enable Fish integration. - ''; - }; + enableZshIntegration = + lib.hm.shell.mkZshIntegrationOption { inherit config; }; }; config = mkIf cfg.enable { diff --git a/modules/programs/gallery-dl.nix b/modules/programs/gallery-dl.nix index 4f566e18b..7665d5c08 100644 --- a/modules/programs/gallery-dl.nix +++ b/modules/programs/gallery-dl.nix @@ -14,7 +14,7 @@ in { options.programs.gallery-dl = { enable = mkEnableOption "gallery-dl"; - package = mkPackageOption pkgs "gallery-dl" { }; + package = mkPackageOption pkgs "gallery-dl" { nullable = true; }; settings = mkOption { type = jsonFormat.type; @@ -34,7 +34,7 @@ in { }; config = mkIf cfg.enable { - home.packages = [ cfg.package ]; + home.packages = lib.mkIf (cfg.package != null) [ cfg.package ]; xdg.configFile."gallery-dl/config.json" = mkIf (cfg.settings != { }) { source = jsonFormat.generate "gallery-dl-settings" cfg.settings; diff --git a/modules/programs/gh-dash.nix b/modules/programs/gh-dash.nix index b351bb33a..e1d4aa7ca 100644 --- a/modules/programs/gh-dash.nix +++ b/modules/programs/gh-dash.nix @@ -12,7 +12,7 @@ in { options.programs.gh-dash = { enable = lib.mkEnableOption "GitHub CLI dashboard plugin"; - package = lib.mkPackageOption pkgs "gh-dash" { }; + package = lib.mkPackageOption pkgs "gh-dash" { nullable = true; }; settings = lib.mkOption { type = yamlFormat.type; @@ -32,9 +32,9 @@ in { }; config = lib.mkIf cfg.enable { - home.packages = [ cfg.package ]; + home.packages = lib.mkIf (cfg.package != null) [ cfg.package ]; - programs.gh.extensions = [ cfg.package ]; + programs.gh.extensions = lib.mkIf (cfg.package != null) [ cfg.package ]; xdg.configFile."gh-dash/config.yml".source = yamlFormat.generate "gh-dash-config.yml" cfg.settings; diff --git a/modules/programs/ghostty.nix b/modules/programs/ghostty.nix new file mode 100644 index 000000000..383472efc --- /dev/null +++ b/modules/programs/ghostty.nix @@ -0,0 +1,204 @@ +{ config, lib, pkgs, ... }: +let + cfg = config.programs.ghostty; + + keyValueSettings = { + listsAsDuplicateKeys = true; + mkKeyValue = lib.generators.mkKeyValueDefault { } " = "; + }; + keyValue = pkgs.formats.keyValue keyValueSettings; +in { + meta.maintainers = with lib.maintainers; [ HeitorAugustoLN khaneliman ]; + + options.programs.ghostty = let + mkShellIntegrationOption = option: + option // { + description = '' + ${option.description} + + This 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. + ''; + }; + in { + enable = lib.mkEnableOption "Ghostty"; + + package = lib.mkPackageOption pkgs "ghostty" { + nullable = true; + extraDescription = + "Set programs.ghostty.package to null on platforms where ghostty is not available or marked broken"; + }; + + settings = lib.mkOption { + inherit (keyValue) type; + default = { }; + example = lib.literalExpression '' + { + theme = "catppuccin-mocha"; + font-size = 10; + keybind = [ + "ctrl+h=goto_split:left" + "ctrl+l=goto_split:right" + ]; + } + ''; + 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 = cfg.package != null; + defaultText = + lib.literalMD "`true` if programs.ghostty.package is not null"; + }; + + enableBashIntegration = mkShellIntegrationOption + (lib.hm.shell.mkBashIntegrationOption { inherit config; }); + + enableFishIntegration = mkShellIntegrationOption + (lib.hm.shell.mkFishIntegrationOption { inherit config; }); + + enableZshIntegration = mkShellIntegrationOption + (lib.hm.shell.mkZshIntegrationOption { inherit config; }); + }; + + config = lib.mkIf cfg.enable (lib.mkMerge [ + { + home.packages = lib.optionals (cfg.package != null) [ 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 = let + validate = file: + lib.mkIf (cfg.package != null) "${ + lib.getExe cfg.package + } +validate-config --config-file=${config.xdg.configHome}/ghostty/${file}"; + in lib.mkMerge [ + { + "ghostty/config" = lib.mkIf (cfg.settings != { }) { + source = keyValue.generate "ghostty-config" cfg.settings; + onChange = validate "config"; + }; + } + + (lib.mkIf (cfg.themes != { }) (lib.mapAttrs' (name: value: { + name = "ghostty/themes/${name}"; + value = { + source = keyValue.generate "ghostty-${name}-theme" value; + onChange = validate "themes/${name}"; + }; + }) cfg.themes)) + ]; + } + + (lib.mkIf cfg.installVimSyntax { + assertions = [{ + assertion = cfg.installVimSyntax -> cfg.package != null; + message = + "programs.ghostty.installVimSyntax cannot be enabled when programs.ghostty.package is null"; + }]; + programs.vim.plugins = + lib.optionals (cfg.package != null) [ cfg.package.vim ]; + }) + + (lib.mkIf cfg.installBatSyntax { + assertions = [{ + assertion = cfg.installBatSyntax -> cfg.package != null; + message = + "programs.ghostty.installBatSyntax cannot be enabled when programs.ghostty.package is null"; + }]; + programs.bat = lib.mkIf (cfg.package != null) { + syntaxes.ghostty = { + src = cfg.package; + file = "share/bat/syntaxes/ghostty.sublime-syntax"; + }; + config.map-syntax = + [ "${config.xdg.configHome}/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/modules/programs/git-cliff.nix b/modules/programs/git-cliff.nix index cd7fb529d..ce9e26f39 100644 --- a/modules/programs/git-cliff.nix +++ b/modules/programs/git-cliff.nix @@ -13,7 +13,7 @@ in { options.programs.git-cliff = { enable = mkEnableOption "git-cliff changelog generator"; - package = mkPackageOption pkgs "git-cliff" { }; + package = mkPackageOption pkgs "git-cliff" { nullable = true; }; settings = mkOption { type = tomlFormat.type; @@ -34,7 +34,7 @@ in { }; config = mkIf cfg.enable { - home.packages = [ cfg.package ]; + home.packages = lib.mkIf (cfg.package != null) [ cfg.package ]; xdg.configFile = { "git-cliff/cliff.toml" = mkIf (cfg.settings != { }) { diff --git a/modules/programs/git-credential-oauth.nix b/modules/programs/git-credential-oauth.nix index 4833e8068..499c7c4c1 100644 --- a/modules/programs/git-credential-oauth.nix +++ b/modules/programs/git-credential-oauth.nix @@ -12,13 +12,27 @@ in { enable = lib.mkEnableOption "Git authentication handler for OAuth"; package = lib.mkPackageOption pkgs "git-credential-oauth" { }; + + extraFlags = lib.mkOption { + type = lib.types.listOf lib.types.str; + default = [ ]; + example = lib.literalExpression ''[ "-device" ]''; + description = '' + Extra command-line arguments passed to git-credential-oauth. + + For valid arguments, see {manpage}`git-credential-oauth(1)`. + ''; + }; }; }; config = lib.mkIf cfg.enable { home.packages = [ cfg.package ]; - programs.git.extraConfig.credential.helper = - [ "${cfg.package}/bin/git-credential-oauth" ]; + programs.git.extraConfig.credential.helper = lib.mkAfter [ + ("${cfg.package}/bin/git-credential-oauth" + + lib.optionalString (cfg.extraFlags != [ ]) + " ${lib.strings.concatStringsSep " " cfg.extraFlags}") + ]; }; } diff --git a/modules/programs/git-worktree-switcher.nix b/modules/programs/git-worktree-switcher.nix new file mode 100644 index 000000000..cb38f2e62 --- /dev/null +++ b/modules/programs/git-worktree-switcher.nix @@ -0,0 +1,39 @@ +{ pkgs, config, lib, ... }: + +let + inherit (lib) mkEnableOption mkPackageOption optionalString; + + cfg = config.programs.git-worktree-switcher; + + initScript = shell: + if (shell == "fish") then '' + ${lib.getExe pkgs.git-worktree-switcher} init ${shell} | source + '' else '' + eval "$(${lib.getExe pkgs.git-worktree-switcher} init ${shell})" + ''; +in { + meta.maintainers = with lib.maintainers; [ jiriks74 mateusauler ]; + + options.programs.git-worktree-switcher = { + enable = mkEnableOption "git-worktree-switcher"; + package = mkPackageOption pkgs "git-worktree-switcher" { }; + enableBashIntegration = + lib.hm.shell.mkBashIntegrationOption { inherit config; }; + + enableFishIntegration = + lib.hm.shell.mkFishIntegrationOption { inherit config; }; + + enableZshIntegration = + lib.hm.shell.mkZshIntegrationOption { inherit config; }; + }; + + config = lib.mkIf cfg.enable { + home.packages = [ cfg.package ]; + programs.bash.initExtra = + optionalString cfg.enableBashIntegration (initScript "bash"); + programs.fish.interactiveShellInit = + optionalString cfg.enableFishIntegration (initScript "fish"); + programs.zsh.initExtra = + optionalString cfg.enableZshIntegration (initScript "zsh"); + }; +} diff --git a/modules/programs/git.nix b/modules/programs/git.nix index 07d01ab9d..16fc6a0fa 100644 --- a/modules/programs/git.nix +++ b/modules/programs/git.nix @@ -14,33 +14,6 @@ let supersectionType = attrsOf (either multipleType sectionType); in attrsOf supersectionType; - signModule = types.submodule { - options = { - key = mkOption { - type = types.nullOr types.str; - description = '' - The default GPG signing key fingerprint. - - Set to `null` to let GnuPG decide what signing key - to use depending on commit’s author. - ''; - }; - - signByDefault = mkOption { - type = types.bool; - default = false; - description = "Whether commits and tags should be signed by default."; - }; - - gpgPath = mkOption { - type = types.str; - default = "${pkgs.gnupg}/bin/gpg2"; - defaultText = "\${pkgs.gnupg}/bin/gpg2"; - description = "Path to GnuPG binary to use."; - }; - }; - }; - includeModule = types.submodule ({ config, ... }: { options = { condition = mkOption { @@ -97,7 +70,7 @@ let }); in { - meta.maintainers = [ maintainers.rycee ]; + meta.maintainers = with lib.maintainers; [ khaneliman rycee ]; options = { programs.git = { @@ -132,10 +105,40 @@ in { description = "Git aliases to define."; }; - signing = mkOption { - type = types.nullOr signModule; - default = null; - description = "Options related to signing commits using GnuPG."; + signing = { + key = mkOption { + type = types.nullOr types.str; + default = null; + description = '' + The default signing key fingerprint. + + Set to `null` to let the signer decide what signing key + to use depending on commit’s author. + ''; + }; + + format = mkOption { + type = types.nullOr (types.enum [ "openpgp" "ssh" "x509" ]); + defaultText = literalExpression '' + "openpgp" for state version < 25.05, + undefined for state version ≥ 25.05 + ''; + description = '' + The signing method to use when signing commits and tags. + Valid values are `openpgp` (OpenPGP/GnuPG), `ssh` (SSH), and `x509` (X.509 certificates). + ''; + }; + + signByDefault = mkOption { + type = types.nullOr types.bool; + default = null; + description = "Whether commits and tags should be signed by default."; + }; + + signer = mkOption { + type = types.nullOr types.str; + description = "Path to signer binary to use."; + }; }; extraConfig = mkOption { @@ -214,6 +217,44 @@ in { }; }; + maintenance = { + enable = mkEnableOption "" // { + description = '' + Enable the automatic {command}`git maintenance`. + + If you have SSH remotes, set {option}`programs.git.package` to a + git version with SSH support (eg: `pkgs.gitFull`). + + See . + ''; + }; + + repositories = mkOption { + type = with types; listOf str; + default = [ ]; + description = '' + Repositories on which {command}`git maintenance` should run. + + Should be a list of absolute paths. + ''; + }; + + timers = mkOption { + type = types.attrsOf types.str; + default = { + hourly = "*-*-* 1..23:53:00"; + daily = "Tue..Sun *-*-* 0:53:00"; + weekly = "Mon 0:53:00"; + }; + description = '' + Systemd timers to create for scheduled {command}`git maintenance`. + + Key is passed to `--schedule` argument in {command}`git maintenance run` + and value is passed to `Timer.OnCalendar` in `systemd.user.timers`. + ''; + }; + }; + diff-highlight = { enable = mkEnableOption "" // { description = '' @@ -370,12 +411,45 @@ in { ''; }; }; + + riff = { + enable = mkEnableOption "" // { + description = '' + Enable the riff diff highlighter. + See . + ''; + }; + + package = mkPackageOption pkgs "riffdiff" { }; + + commandLineOptions = mkOption { + type = types.listOf types.str; + default = [ ]; + example = literalExpression ''[ "--no-adds-only-special" ]''; + apply = concatStringsSep " "; + description = '' + Command line arguments to include in the RIFF environment variable. + + Run riff --help for a full list of options + ''; + }; + }; }; }; + imports = [ + (mkRenamedOptionModule [ "programs" "git" "signing" "gpgPath" ] [ + "programs" + "git" + "signing" + "signer" + ]) + ]; + config = mkIf cfg.enable (mkMerge [ { home.packages = [ cfg.package ]; + assertions = [{ assertion = let enabled = [ @@ -383,6 +457,7 @@ in { cfg.diff-so-fancy.enable cfg.difftastic.enable cfg.diff-highlight.enable + cfg.riff.enable ]; in count id enabled <= 1; message = @@ -414,7 +489,7 @@ in { genIdentity = name: account: with account; nameValuePair "sendemail.${name}" (if account.msmtp.enable then { - smtpServer = "${pkgs.msmtp}/bin/msmtp"; + sendmailCmd = "${pkgs.msmtp}/bin/msmtp"; envelopeSender = "auto"; from = "${realName} <${address}>"; } else @@ -439,12 +514,38 @@ in { (filterAttrs hasSmtp config.accounts.email.accounts); } - (mkIf (cfg.signing != null) { - programs.git.iniContent = { - user.signingKey = mkIf (cfg.signing.key != null) cfg.signing.key; - commit.gpgSign = mkDefault cfg.signing.signByDefault; - tag.gpgSign = mkDefault cfg.signing.signByDefault; - gpg.program = cfg.signing.gpgPath; + (mkIf (cfg.signing != { }) { + programs.git = { + signing = { + format = if (versionOlder config.home.stateVersion "25.05") then + (mkOptionDefault "openpgp") + else + (mkOptionDefault null); + signer = let + defaultSigners = { + openpgp = getExe config.programs.gpg.package; + ssh = getExe' pkgs.openssh "ssh-keygen"; + x509 = getExe' config.programs.gpg.package "gpgsm"; + }; + in mkIf (cfg.signing.format != null) + (mkOptionDefault defaultSigners.${cfg.signing.format}); + }; + + iniContent = mkMerge [ + (mkIf (cfg.signing.key != null) { + user.signingKey = mkDefault cfg.signing.key; + }) + (mkIf (cfg.signing.signByDefault != null) { + commit.gpgSign = mkDefault cfg.signing.signByDefault; + tag.gpgSign = mkDefault cfg.signing.signByDefault; + }) + (mkIf (cfg.signing.format != null) { + gpg = { + format = mkDefault cfg.signing.format; + ${cfg.signing.format}.program = mkDefault cfg.signing.signer; + }; + }) + ]; }; }) @@ -501,6 +602,48 @@ in { }; }) + (mkIf cfg.maintenance.enable { + programs.git.iniContent.maintenance.repo = cfg.maintenance.repositories; + + systemd.user.services."git-maintenance@" = { + Unit = { + Description = "Optimize Git repositories data"; + Documentation = [ "man:git-maintenance(1)" ]; + }; + + Service = { + Type = "oneshot"; + ExecStart = let exe = lib.getExe cfg.package; + in '' + "${exe}" for-each-repo --keep-going --config=maintenance.repo maintenance run --schedule=%i + ''; + LockPersonality = "yes"; + MemoryDenyWriteExecute = "yes"; + NoNewPrivileges = "yes"; + RestrictAddressFamilies = "AF_UNIX AF_INET AF_INET6 AF_VSOCK"; + RestrictNamespaces = "yes"; + RestrictRealtime = "yes"; + RestrictSUIDSGID = "yes"; + SystemCallArchitectures = "native"; + SystemCallFilter = "@system-service"; + }; + }; + + systemd.user.timers = let + toSystemdTimer = name: time: + lib.attrsets.nameValuePair "git-maintenance@${name}" { + Unit.Description = "Optimize Git repositories data"; + + Timer = { + OnCalendar = time; + Persistent = true; + }; + + Install.WantedBy = [ "timers.target" ]; + }; + in lib.attrsets.mapAttrs' toSystemdTimer cfg.maintenance.timers; + }) + (mkIf cfg.diff-highlight.enable { programs.git.iniContent = let dhCommand = @@ -559,5 +702,25 @@ in { }; }; }) + + (let riffExe = baseNameOf (getExe cfg.riff.package); + in mkIf cfg.riff.enable { + home.packages = [ cfg.riff.package ]; + + # https://github.com/walles/riff/blob/b17e6f17ce807c8652bc59cd46758661d23ce358/README.md#usage + programs.git.iniContent = { + pager = { + diff = riffExe; + log = riffExe; + show = riffExe; + }; + + interactive.diffFilter = "${riffExe} --color=on"; + }; + }) + + (mkIf (cfg.riff.enable && cfg.riff.commandLineOptions != "") { + home.sessionVariables.RIFF = cfg.riff.commandLineOptions; + }) ]); } diff --git a/modules/programs/gnome-shell.nix b/modules/programs/gnome-shell.nix index 36a57cea9..a91609bf2 100644 --- a/modules/programs/gnome-shell.nix +++ b/modules/programs/gnome-shell.nix @@ -17,7 +17,7 @@ let package = mkOption { type = types.package; - example = "pkgs.gnome.gnome-shell-extensions"; + example = "pkgs.gnome-shell-extensions"; description = '' Package providing a GNOME Shell extension in `$out/share/gnome-shell/extensions/''${id}`. @@ -66,7 +66,7 @@ in { { package = pkgs.gnomeExtensions.dash-to-panel; } { id = "user-theme@gnome-shell-extensions.gcampax.github.com"; - package = pkgs.gnome.gnome-shell-extensions; + package = pkgs.gnome-shell-extensions; } ] ''; @@ -106,7 +106,7 @@ in { programs.gnome-shell.extensions = [{ id = "user-theme@gnome-shell-extensions.gcampax.github.com"; - package = pkgs.gnome.gnome-shell-extensions; + package = pkgs.gnome-shell-extensions; }]; home.packages = [ cfg.theme.package ]; diff --git a/modules/programs/go.nix b/modules/programs/go.nix index 5d150036b..19b63eae3 100644 --- a/modules/programs/go.nix +++ b/modules/programs/go.nix @@ -6,6 +6,8 @@ let cfg = config.programs.go; + modeFileContent = "${cfg.telemetry.mode} ${cfg.telemetry.date}"; + in { meta.maintainers = [ maintainers.rvolosatovs ]; @@ -71,6 +73,31 @@ in { or checksum database. ''; }; + + telemetry = mkOption { + type = types.submodule { + options = { + mode = mkOption { + type = with types; nullOr (enum [ "off" "local" "on" ]); + default = null; + description = "Go telemetry mode to be set."; + }; + + date = mkOption { + type = types.str; + default = "1970-01-01"; + description = '' + The date indicating the date at which the modefile + was updated, in YYYY-MM-DD format. It's used to + reset the timeout before the next telemetry report + is uploaded when telemetry mode is set to "on". + ''; + }; + }; + }; + default = { }; + description = "Options to configure Go telemetry mode."; + }; }; }; @@ -98,5 +125,17 @@ in { (mkIf (cfg.goPrivate != [ ]) { home.sessionVariables.GOPRIVATE = concatStringsSep "," cfg.goPrivate; }) + + (mkIf (cfg.telemetry.mode != null) { + home.file."Library/Application Support/go/telemetry/mode" = { + enable = pkgs.stdenv.hostPlatform.isDarwin; + text = modeFileContent; + }; + + xdg.configFile."go/telemetry/mode" = { + enable = !pkgs.stdenv.hostPlatform.isDarwin; + text = modeFileContent; + }; + }) ]); } diff --git a/modules/programs/gradle.nix b/modules/programs/gradle.nix index 8bf5d7898..f8bba3e46 100644 --- a/modules/programs/gradle.nix +++ b/modules/programs/gradle.nix @@ -50,7 +50,10 @@ in { ''; }; - package = mkPackageOption pkgs "gradle" { example = "pkgs.gradle_7"; }; + package = mkPackageOption pkgs "gradle" { + nullable = true; + example = "pkgs.gradle_7"; + }; settings = mkOption { type = types.submodule { freeformType = settingsFormat.type; }; @@ -95,7 +98,7 @@ in { config = let gradleHome = "${config.home.homeDirectory}/${cfg.home}"; in mkIf cfg.enable { - home.packages = [ cfg.package ]; + home.packages = lib.mkIf (cfg.package != null) [ cfg.package ]; home.file = mkMerge ([{ "${cfg.home}/gradle.properties" = mkIf (cfg.settings != { }) { diff --git a/modules/programs/granted.nix b/modules/programs/granted.nix index a09169250..802cffea1 100644 --- a/modules/programs/granted.nix +++ b/modules/programs/granted.nix @@ -13,13 +13,11 @@ in { options.programs.granted = { enable = mkEnableOption "granted"; - enableZshIntegration = mkOption { - default = true; - type = types.bool; - description = '' - Whether to enable Zsh integration. - ''; - }; + enableZshIntegration = + lib.hm.shell.mkZshIntegrationOption { inherit config; }; + + enableFishIntegration = + lib.hm.shell.mkFishIntegrationOption { inherit config; }; }; config = mkIf cfg.enable { @@ -28,9 +26,15 @@ in { programs.zsh.initExtra = mkIf cfg.enableZshIntegration '' function assume() { export GRANTED_ALIAS_CONFIGURED="true" - source ${package}/bin/.assume-wrapped "$@" + source ${package}/bin/assume "$@" unset GRANTED_ALIAS_CONFIGURED } ''; + + programs.fish.functions.assume = mkIf cfg.enableFishIntegration '' + set -x GRANTED_ALIAS_CONFIGURED "true" + source ${package}/share/assume.fish $argv + set -e GRANTED_ALIAS_CONFIGURED + ''; }; } diff --git a/modules/programs/havoc.nix b/modules/programs/havoc.nix index c83a1c39a..5d48fbac1 100644 --- a/modules/programs/havoc.nix +++ b/modules/programs/havoc.nix @@ -13,7 +13,7 @@ in { options.programs.havoc = { enable = mkEnableOption "Havoc terminal"; - package = mkPackageOption pkgs "havoc" { }; + package = mkPackageOption pkgs "havoc" { nullable = true; }; settings = mkOption { type = iniFormat.type; @@ -54,7 +54,7 @@ in { assertions = [ (hm.assertions.assertPlatform "programs.havoc" pkgs platforms.linux) ]; - home.packages = [ cfg.package ]; + home.packages = lib.mkIf (cfg.package != null) [ cfg.package ]; xdg.configFile."havoc.cfg" = mkIf (cfg.settings != { }) { source = iniFormat.generate "havoc.cfg" cfg.settings; diff --git a/modules/programs/helix.nix b/modules/programs/helix.nix index 01af7b14e..840f5d82f 100644 --- a/modules/programs/helix.nix +++ b/modules/programs/helix.nix @@ -188,7 +188,7 @@ in { nativeBuildInputs = [ pkgs.makeWrapper ]; postBuild = '' wrapProgram $out/bin/hx \ - --prefix PATH : ${lib.makeBinPath cfg.extraPackages} + --suffix PATH : ${lib.makeBinPath cfg.extraPackages} ''; }) ] diff --git a/modules/programs/himalaya.nix b/modules/programs/himalaya.nix index 2d216c3dc..5cba5a2f1 100644 --- a/modules/programs/himalaya.nix +++ b/modules/programs/himalaya.nix @@ -1,12 +1,14 @@ { config, lib, pkgs, ... }: +with lib; + let # aliases inherit (config.programs) himalaya; tomlFormat = pkgs.formats.toml { }; # attrs util that removes entries containing a null value - compactAttrs = lib.filterAttrs (_: val: !isNull val); + compactAttrs = filterAttrs (_: val: !isNull val); # needed for notmuch config, because the DB is here, and not in each # account's dir @@ -35,7 +37,7 @@ let email = account.address; display-name = account.realName; default = account.primary; - folder.alias = { + folder.aliases = { inbox = account.folders.inbox; sent = account.folders.sent; drafts = account.folders.drafts; @@ -44,48 +46,53 @@ let }; signatureConfig = - lib.optionalAttrs (account.signature.showSignature == "append") { + optionalAttrs (account.signature.showSignature == "append") { # TODO: signature cannot be attached yet - # https://todo.sr.ht/~soywod/pimalaya/27 + # https://github.com/pimalaya/himalaya/issues/534 signature = account.signature.text; signature-delim = account.signature.delimiter; }; - imapConfig = lib.optionalAttrs imapEnabled (compactAttrs { - backend = "imap"; - imap.host = account.imap.host; - imap.port = account.imap.port; - imap.encryption = mkEncryptionConfig account.imap.tls; - imap.login = account.userName; - imap.passwd.cmd = builtins.concatStringsSep " " account.passwordCommand; + imapConfig = optionalAttrs imapEnabled (compactAttrs { + backend.type = "imap"; + backend.host = account.imap.host; + backend.port = account.imap.port; + backend.encryption.type = mkEncryptionConfig account.imap.tls; + backend.login = account.userName; + backend.auth.type = "password"; + backend.auth.cmd = + builtins.concatStringsSep " " account.passwordCommand; }); - maildirConfig = lib.optionalAttrs maildirEnabled (compactAttrs { - backend = "maildir"; - maildir.root-dir = account.maildir.absPath; + maildirConfig = optionalAttrs maildirEnabled (compactAttrs { + backend.type = "maildir"; + backend.root-dir = account.maildir.absPath; }); - notmuchConfig = lib.optionalAttrs notmuchEnabled (compactAttrs { - backend = "notmuch"; - notmuch.database-path = maildirBasePath; + notmuchConfig = optionalAttrs notmuchEnabled (compactAttrs { + backend.type = "notmuch"; + backend.db-path = maildirBasePath; }); - smtpConfig = lib.optionalAttrs (!isNull account.smtp) (compactAttrs { - message.send.backend = "smtp"; - smtp.host = account.smtp.host; - smtp.port = account.smtp.port; - smtp.encryption = mkEncryptionConfig account.smtp.tls; - smtp.login = account.userName; - smtp.passwd.cmd = builtins.concatStringsSep " " account.passwordCommand; + smtpConfig = optionalAttrs (!isNull account.smtp) (compactAttrs { + message.send.backend.type = "smtp"; + message.send.backend.host = account.smtp.host; + message.send.backend.port = account.smtp.port; + message.send.backend.encryption.type = + mkEncryptionConfig account.smtp.tls; + message.send.backend.login = account.userName; + message.send.backend.auth.type = "password"; + message.send.backend.auth.cmd = + builtins.concatStringsSep " " account.passwordCommand; }); sendmailConfig = - lib.optionalAttrs (isNull account.smtp && !isNull account.msmtp) { - sender = "sendmail"; - sendmail.cmd = "${pkgs.msmtp}/bin/msmtp"; + optionalAttrs (isNull account.smtp && !isNull account.msmtp) { + message.send.backend.type = "sendmail"; + message.send.backend.cmd = getExe pkgs.msmtp; }; - config = lib.attrsets.mergeAttrsList [ + config = attrsets.mergeAttrsList [ globalConfig signatureConfig imapConfig @@ -95,65 +102,49 @@ let sendmailConfig ]; - in lib.recursiveUpdate config account.himalaya.settings; + in recursiveUpdate config account.himalaya.settings; in { - meta.maintainers = with lib.hm.maintainers; [ soywod toastal ]; + meta.maintainers = with hm.maintainers; [ soywod toastal ]; + + imports = [ + (mkRemovedOptionModule [ "services" "himalaya-watch" "enable" ] '' + services.himalaya-watch has been removed. + + The watch feature moved away from Himalaya scope, and resides + now in its own project called Mirador. Once the v1 released, the + service will land back in nixpkgs and home-manager. + + See . + '') + ]; options = { programs.himalaya = { - enable = lib.mkEnableOption "the email client Himalaya CLI"; - package = lib.mkPackageOption pkgs "himalaya" { }; - settings = lib.mkOption { - type = lib.types.submodule { freeformType = tomlFormat.type; }; + enable = mkEnableOption "the email client Himalaya CLI"; + package = mkPackageOption pkgs "himalaya" { nullable = true; }; + settings = mkOption { + type = types.submodule { freeformType = tomlFormat.type; }; default = { }; description = '' Himalaya CLI global configuration. - See for supported values. + See for supported values. ''; }; }; - services.himalaya-watch = { - enable = lib.mkEnableOption - "the email client Himalaya CLI envelopes watcher service"; - - environment = lib.mkOption { - type = with lib.types; attrsOf str; - default = { }; - example = lib.literalExpression '' - { - "PASSWORD_STORE_DIR" = "~/.password-store"; - } - ''; - description = '' - Extra environment variables to be exported in the service. - ''; - }; - - settings.account = lib.mkOption { - type = with lib.types; nullOr str; - default = null; - example = "personal"; - description = '' - Name of the account the watcher should be started for. - If no account is given, the default one is used. - ''; - }; - }; - - accounts.email.accounts = lib.mkOption { - type = lib.types.attrsOf (lib.types.submodule { + accounts.email.accounts = mkOption { + type = types.attrsOf (types.submodule { options.himalaya = { - enable = lib.mkEnableOption + enable = mkEnableOption "the email client Himalaya CLI for this email account"; - settings = lib.mkOption { - type = lib.types.submodule { freeformType = tomlFormat.type; }; + settings = mkOption { + type = types.submodule { freeformType = tomlFormat.type; }; default = { }; description = '' Himalaya CLI configuration for this email account. - See for supported values. + See for supported values. ''; }; }; @@ -161,41 +152,30 @@ in { }; }; - config = lib.mkIf himalaya.enable { - home.packages = [ himalaya.package ]; + config = mkIf himalaya.enable { + home.packages = lib.mkIf (himalaya.package != null) [ himalaya.package ]; - xdg.configFile."himalaya/config.toml".source = let - enabledAccounts = lib.filterAttrs (_: account: account.himalaya.enable) - config.accounts.email.accounts; - accountsConfig = lib.mapAttrs mkAccountConfig enabledAccounts; - globalConfig = compactAttrs himalaya.settings; - allConfig = globalConfig // { accounts = accountsConfig; }; - in tomlFormat.generate "himalaya-config.toml" allConfig; - systemd.user.services = let - inherit (config.services.himalaya-watch) enable environment settings; - optionalArg = key: - if (key ? settings && !isNull settings."${key}") then - [ "--${key} ${settings."${key}"}" ] - else - [ ]; - in { - himalaya-watch = lib.mkIf enable { - Unit = { - Description = "Email client Himalaya CLI envelopes watcher service"; - After = [ "network.target" ]; + xdg = { + configFile."himalaya/config.toml".source = let + enabledAccounts = filterAttrs (_: account: account.himalaya.enable) + config.accounts.email.accounts; + accountsConfig = mapAttrs mkAccountConfig enabledAccounts; + globalConfig = compactAttrs himalaya.settings; + allConfig = globalConfig // { accounts = accountsConfig; }; + in tomlFormat.generate "himalaya.config.toml" allConfig; + + desktopEntries.himalaya = + mkIf (pkgs.stdenv.hostPlatform.isLinux && (himalaya.package != null)) { + type = "Application"; + name = "himalaya"; + genericName = "Email Client"; + comment = "CLI to manage emails"; + terminal = true; + exec = "himalaya %u"; + categories = [ "Network" ]; + mimeType = [ "x-scheme-handler/mailto" "message/rfc822" ]; + settings = { Keywords = "email"; }; }; - Install = { WantedBy = [ "default.target" ]; }; - Service = { - ExecStart = lib.concatStringsSep " " - ([ "${himalaya.package}/bin/himalaya" "envelopes" "watch" ] - ++ optionalArg "account"); - ExecSearchPath = "/bin"; - Environment = - lib.mapAttrsToList (key: val: "${key}=${val}") environment; - Restart = "always"; - RestartSec = 10; - }; - }; }; }; } diff --git a/modules/programs/hstr.nix b/modules/programs/hstr.nix index e85832174..6dc2c0a33 100644 --- a/modules/programs/hstr.nix +++ b/modules/programs/hstr.nix @@ -16,13 +16,11 @@ in { package = mkPackageOption pkgs "hstr" { }; - enableBashIntegration = mkEnableOption "Bash integration" // { - default = true; - }; + enableBashIntegration = + lib.hm.shell.mkBashIntegrationOption { inherit config; }; - enableZshIntegration = mkEnableOption "Zsh integration" // { - default = true; - }; + enableZshIntegration = + lib.hm.shell.mkZshIntegrationOption { inherit config; }; }; config = mkIf cfg.enable { diff --git a/modules/programs/htop.nix b/modules/programs/htop.nix index 1c569c404..28699e4a1 100644 --- a/modules/programs/htop.nix +++ b/modules/programs/htop.nix @@ -113,7 +113,8 @@ in { enable = mkEnableOption "htop"; settings = mkOption { - type = types.attrs; + type = with types; + attrsOf (oneOf [ bool int str (listOf (oneOf [ int str ])) ]); default = { }; example = literalExpression '' { @@ -165,12 +166,13 @@ in { config = mkIf cfg.enable { lib.htop = { - inherit fields modes leftMeters rightMeters bar text graph led blank; + inherit fields defaultFields modes leftMeters rightMeters bar text graph + led blank; }; home.packages = [ cfg.package ]; - xdg.configFile."htop/htoprc" = let + xdg.configFile."htop" = let defaults = { fields = if isDarwin then remove fields.M_SHARE defaultFields @@ -187,9 +189,9 @@ in { formatOptions = mapAttrsToList formatOption; in mkIf (cfg.settings != { }) { - text = - concatStringsSep "\n" (formatOptions before ++ formatOptions settings) - + "\n"; + source = pkgs.writeTextDir "htoprc" + (concatStringsSep "\n" (formatOptions before ++ formatOptions settings) + + "\n"); }; }; } diff --git a/modules/programs/hyprlock.nix b/modules/programs/hyprlock.nix index 25d871889..a59c133be 100644 --- a/modules/programs/hyprlock.nix +++ b/modules/programs/hyprlock.nix @@ -1,16 +1,14 @@ { config, pkgs, lib, ... }: -with lib; - let cfg = config.programs.hyprlock; in { - meta.maintainers = [ maintainers.khaneliman maintainers.fufexan ]; + meta.maintainers = with lib.maintainers; [ khaneliman fufexan ]; options.programs.hyprlock = { - enable = mkEnableOption "" // { + enable = lib.mkEnableOption "" // { description = '' Whether to enable Hyprlock, Hyprland's GPU-accelerated lock screen utility. @@ -27,7 +25,7 @@ in { ''; }; - package = mkPackageOption pkgs "hyprlock" { }; + package = lib.mkPackageOption pkgs "hyprlock" { nullable = true; }; settings = lib.mkOption { type = with lib.types; @@ -102,21 +100,21 @@ in { importantPrefixes = lib.mkOption { type = with lib.types; listOf str; - default = [ "$" "monitor" "size" ] + default = [ "$" "bezier" "monitor" "size" ] ++ lib.optionals cfg.sourceFirst [ "source" ]; - example = [ "$" "monitor" "size" ]; + example = [ "$" "bezier" "monitor" "size" ]; description = '' List of prefix of attributes to source at the top of the config. ''; }; }; - config = mkIf cfg.enable { - home.packages = [ cfg.package ]; + config = lib.mkIf cfg.enable { + home.packages = lib.mkIf (cfg.package != null) [ cfg.package ]; xdg.configFile."hypr/hyprlock.conf" = let shouldGenerate = cfg.extraConfig != "" || cfg.settings != { }; - in mkIf shouldGenerate { + in lib.mkIf shouldGenerate { text = lib.optionalString (cfg.settings != { }) (lib.hm.generators.toHyprconf { attrs = cfg.settings; diff --git a/modules/programs/i3status.nix b/modules/programs/i3status.nix index 17b1162e8..343418dc6 100644 --- a/modules/programs/i3status.nix +++ b/modules/programs/i3status.nix @@ -130,7 +130,7 @@ in { ''; }; - package = mkPackageOption pkgs "i3status" { }; + package = mkPackageOption pkgs "i3status" { nullable = true; }; }; config = mkIf cfg.enable { @@ -190,7 +190,7 @@ in { }; }; - home.packages = [ cfg.package ]; + home.packages = lib.mkIf (cfg.package != null) [ cfg.package ]; xdg.configFile."i3status/config".text = concatStringsSep "\n" ([ ] ++ optional (cfg.general != { }) (formatModule "general" cfg.general) diff --git a/modules/programs/imv.nix b/modules/programs/imv.nix index 583c2c57c..2cad38134 100644 --- a/modules/programs/imv.nix +++ b/modules/programs/imv.nix @@ -16,7 +16,7 @@ in { enable = mkEnableOption "imv: a command line image viewer intended for use with tiling window managers"; - package = mkPackageOption pkgs "imv" { }; + package = mkPackageOption pkgs "imv" { nullable = true; }; settings = mkOption { default = { }; @@ -38,7 +38,7 @@ in { assertions = [ (hm.assertions.assertPlatform "programs.imv" pkgs platforms.linux) ]; - home.packages = [ cfg.package ]; + home.packages = lib.mkIf (cfg.package != null) [ cfg.package ]; xdg.configFile = mkIf (cfg.settings != { }) { "imv/config".text = toConfig cfg.settings; }; diff --git a/modules/programs/jetbrains-remote.nix b/modules/programs/jetbrains-remote.nix index 4a9c045a9..917fe87cf 100644 --- a/modules/programs/jetbrains-remote.nix +++ b/modules/programs/jetbrains-remote.nix @@ -31,7 +31,7 @@ in { "${ide}/bin/${ide.meta.mainProgram}-remote-dev-server registerBackendLocationForGateway || true"; lines = map mkLine cfg.ides; linesStr = '' - rm $HOME/.cache/JetBrains/RemoteDev/userProvidedDist/_nix_store* + rm $HOME/.cache/JetBrains/RemoteDev/userProvidedDist/_nix_store* || true '' + concatStringsSep "\n" lines; in hm.dag.entryAfter [ "writeBoundary" ] linesStr; }; diff --git a/modules/programs/jqp.nix b/modules/programs/jqp.nix new file mode 100644 index 000000000..e82bccb27 --- /dev/null +++ b/modules/programs/jqp.nix @@ -0,0 +1,33 @@ +{ config, lib, pkgs, ... }: +let + cfg = config.programs.jqp; + + yamlFormat = pkgs.formats.yaml { }; +in { + options.programs.jqp = { + enable = lib.mkEnableOption "jqp, jq playground"; + + package = lib.mkPackageOption pkgs "jqp" { nullable = true; }; + + settings = lib.mkOption { + type = yamlFormat.type; + default = { }; + example = { + theme = { + name = "monokai"; + chromaStyleOverrides = { kc = "#009900 underline"; }; + }; + }; + description = "Jqp configuration"; + }; + }; + config = lib.mkIf cfg.enable { + home = { + packages = lib.mkIf (cfg.package != null) [ cfg.package ]; + + file.".jqp.yaml" = lib.mkIf (cfg.settings != { }) { + source = yamlFormat.generate "jqp-config" cfg.settings; + }; + }; + }; +} diff --git a/modules/programs/jujutsu.nix b/modules/programs/jujutsu.nix index f0e1b4250..7ba71acbc 100644 --- a/modules/programs/jujutsu.nix +++ b/modules/programs/jujutsu.nix @@ -25,7 +25,7 @@ in { enable = mkEnableOption "a Git-compatible DVCS that is both simple and powerful"; - package = mkPackageOption pkgs "jujutsu" { }; + package = mkPackageOption pkgs "jujutsu" { nullable = true; }; ediff = mkOption { type = types.bool; @@ -54,7 +54,7 @@ in { }; config = mkIf cfg.enable { - home.packages = [ cfg.package ]; + home.packages = lib.mkIf (cfg.package != null) [ cfg.package ]; home.file."${configDir}/jj/config.toml" = mkIf (cfg.settings != { }) { source = tomlFormat.generate "jujutsu-config" (cfg.settings diff --git a/modules/programs/k9s.nix b/modules/programs/k9s.nix index 0dd107883..b0d669822 100644 --- a/modules/programs/k9s.nix +++ b/modules/programs/k9s.nix @@ -24,7 +24,7 @@ in { enable = mkEnableOption "k9s - Kubernetes CLI To Manage Your Clusters In Style"; - package = mkPackageOption pkgs "k9s" { }; + package = mkPackageOption pkgs "k9s" { nullable = true; }; settings = mkOption { type = yamlFormat.type; @@ -182,7 +182,7 @@ in { enableXdgConfig = !isDarwin || config.xdg.enable; in mkIf cfg.enable { - home.packages = [ cfg.package ]; + home.packages = lib.mkIf (cfg.package != null) [ cfg.package ]; xdg.configFile = mkIf enableXdgConfig ({ "k9s/config.yaml" = mkIf (cfg.settings != { }) { diff --git a/modules/programs/kakoune.nix b/modules/programs/kakoune.nix index da0af0c06..7aed4125a 100644 --- a/modules/programs/kakoune.nix +++ b/modules/programs/kakoune.nix @@ -622,7 +622,7 @@ in { programs.kakoune = { enable = mkEnableOption "the kakoune text editor"; - package = mkPackageOption pkgs "kakoune-unwrapped" { }; + package = mkPackageOption pkgs "kakoune-unwrapped" { nullable = true; }; config = mkOption { type = types.nullOr configModule; @@ -656,14 +656,40 @@ in { List of kakoune plugins to install. To get a list of supported plugins run: {command}`nix-env -f '' -qaP -A kakounePlugins`. + + Requires `package` to not be set to have effect. + ''; + }; + + colorSchemePackage = mkOption { + type = with types; nullOr package; + default = null; + example = literalExpression "pkgs.kakounePlugins.kakoune-catppuccin"; + description = '' + A kakoune color schemes to add to your colors folder. This works + because kakoune recursively checks + {file}`$XDG_CONFIG_HOME/kak/colors/`. To apply the color scheme use + `programs.kakoune.config.colorScheme = "theme"`. ''; }; }; }; config = mkIf cfg.enable { - home.packages = [ kakouneWithPlugins ]; + warnings = optional (cfg.package == null && cfg.plugins != [ ]) '' + You have configured `plugins` for `kakoune` but have not set `package`. + + The listed plugins will not be installed. + ''; + + home.packages = lib.mkIf (cfg.package != null) [ kakouneWithPlugins ]; home.sessionVariables = mkIf cfg.defaultEditor { EDITOR = "kak"; }; - xdg.configFile."kak/kakrc".source = configFile; + xdg.configFile = mkMerge [ + { "kak/kakrc".source = configFile; } + (mkIf (cfg.colorSchemePackage != null) { + "kak/colors/${cfg.colorSchemePackage.name}".source = + cfg.colorSchemePackage; + }) + ]; }; } diff --git a/modules/programs/keychain.nix b/modules/programs/keychain.nix index 4aeef4132..c428f40cf 100644 --- a/modules/programs/keychain.nix +++ b/modules/programs/keychain.nix @@ -63,37 +63,17 @@ in { ''; }; - enableBashIntegration = mkOption { - default = true; - type = types.bool; - description = '' - Whether to enable Bash integration. - ''; - }; + enableBashIntegration = + lib.hm.shell.mkBashIntegrationOption { inherit config; }; - enableFishIntegration = mkOption { - default = true; - type = types.bool; - description = '' - Whether to enable Fish integration. - ''; - }; + enableFishIntegration = + lib.hm.shell.mkFishIntegrationOption { inherit config; }; - enableZshIntegration = mkOption { - default = true; - type = types.bool; - description = '' - Whether to enable Zsh integration. - ''; - }; + enableNushellIntegration = + lib.hm.shell.mkNushellIntegrationOption { inherit config; }; - enableNushellIntegration = mkOption { - default = true; - type = types.bool; - description = '' - Whether to enable Nushell integration. - ''; - }; + enableZshIntegration = + lib.hm.shell.mkZshIntegrationOption { inherit config; }; enableXsessionIntegration = mkOption { default = true; diff --git a/modules/programs/khal.nix b/modules/programs/khal.nix index a2e28e018..96879c52e 100644 --- a/modules/programs/khal.nix +++ b/modules/programs/khal.nix @@ -168,7 +168,7 @@ in { options.programs.khal = { enable = mkEnableOption "khal, a CLI calendar application"; - package = mkPackageOption pkgs "khal" { }; + package = mkPackageOption pkgs "khal" { nullable = true; }; locale = mkOption { type = lib.types.submodule { options = localeOptions; }; @@ -199,7 +199,7 @@ in { }; config = mkIf cfg.enable { - home.packages = [ cfg.package ]; + home.packages = lib.mkIf (cfg.package != null) [ cfg.package ]; xdg.configFile."khal/config".text = concatStringsSep "\n" ([ "[calendars]" ] ++ mapAttrsToList genCalendarStr khalAccounts ++ [ diff --git a/modules/programs/kitty.nix b/modules/programs/kitty.nix index e9594ec12..cc7e7b4dc 100644 --- a/modules/programs/kitty.nix +++ b/modules/programs/kitty.nix @@ -1,29 +1,34 @@ { config, lib, pkgs, ... }: - -with lib; - let + inherit (lib) + literalExpression mkEnableOption mkIf mkOption optionalString types; + cfg = config.programs.kitty; - eitherStrBoolInt = with types; either str (either bool int); + settingsValueType = with types; oneOf [ str bool int float ]; optionalPackage = opt: - optional (opt != null && opt.package != null) opt.package; + lib.optional (opt != null && opt.package != null) opt.package; - toKittyConfig = generators.toKeyValue { + toKittyConfig = lib.generators.toKeyValue { mkKeyValue = key: value: let value' = - (if isBool value then lib.hm.booleans.yesNo else toString) value; + (if lib.isBool value then lib.hm.booleans.yesNo else toString) value; in "${key} ${value'}"; }; - toKittyKeybindings = generators.toKeyValue { + toKittyKeybindings = lib.generators.toKeyValue { mkKeyValue = key: command: "map ${key} ${command}"; }; - toKittyEnv = - generators.toKeyValue { mkKeyValue = name: value: "env ${name}=${value}"; }; + toKittyActionAliases = lib.generators.toKeyValue { + mkKeyValue = alias_name: action: "action_alias ${alias_name} ${action}"; + }; + + toKittyEnv = lib.generators.toKeyValue { + mkKeyValue = name: value: "env ${name}=${value}"; + }; shellIntegrationInit = { bash = '' @@ -49,33 +54,38 @@ let ''; }; - shellIntegrationDefaultOpt = { - default = !(elem "disabled" (splitString " " cfg.shellIntegration.mode)); - defaultText = literalExpression '' - !(elem "disabled" (splitString " " config.programs.kitty.shellIntegration.mode)) - ''; - }; + mkShellIntegrationOption = option: + option // { + default = (cfg.shellIntegration.mode != null) && !(lib.elem "disabled" + (lib.splitString " " cfg.shellIntegration.mode)); + defaultText = literalExpression '' + (cfg.shellIntegration.mode != null) + && !(elem "disabled" (splitString " " config.programs.kitty.shellIntegration.mode)) + ''; + }; in { imports = [ - (mkChangedOptionModule [ "programs" "kitty" "theme" ] [ + (lib.mkChangedOptionModule [ "programs" "kitty" "theme" ] [ "programs" "kitty" "themeFile" ] (config: - let value = getAttrFromPath [ "programs" "kitty" "theme" ] config; + let value = lib.getAttrFromPath [ "programs" "kitty" "theme" ] config; in if value != null then (let - matching = filter (x: x.name == value) (builtins.fromJSON + matching = lib.filter (x: x.name == value) (builtins.fromJSON (builtins.readFile "${pkgs.kitty-themes}/share/kitty-themes/themes.json")); - in throwIf (length matching == 0) + in lib.throwIf (lib.length matching == 0) "kitty-themes does not contain a theme named ${value}" - strings.removeSuffix ".conf" - (strings.removePrefix "themes/" (head matching).file)) + lib.strings.removeSuffix ".conf" + (lib.strings.removePrefix "themes/" (lib.head matching).file)) else null)) ]; + meta.maintainers = with lib.maintainers; [ khaneliman ]; + options.programs.kitty = { enable = mkEnableOption "Kitty terminal emulator"; @@ -102,7 +112,7 @@ in { }; settings = mkOption { - type = types.attrsOf eitherStrBoolInt; + type = types.attrsOf settingsValueType; default = { }; example = literalExpression '' { @@ -132,11 +142,23 @@ in { }; font = mkOption { - type = types.nullOr hm.types.fontType; + type = types.nullOr lib.hm.types.fontType; default = null; description = "The font to use."; }; + actionAliases = mkOption { + type = types.attrsOf types.str; + default = { }; + description = "Define action aliases."; + example = literalExpression '' + { + "launch_tab" = "launch --cwd=current --type=tab"; + "launch_window" = "launch --cwd=current --type=os-window"; + } + ''; + }; + keybindings = mkOption { type = types.attrsOf types.str; default = { }; @@ -162,31 +184,32 @@ in { shellIntegration = { mode = mkOption { - type = types.str; + type = types.nullOr types.str; default = "no-rc"; example = "no-cursor"; - apply = o: + apply = lib.mapNullable (o: let - modes = splitString " " o; - filtered = filter (m: m != "no-rc") modes; - in concatStringsSep " " (concatLists [ [ "no-rc" ] filtered ]); + modes = lib.splitString " " o; + filtered = lib.filter (m: m != "no-rc") modes; + in lib.concatStringsSep " " + (lib.concatLists [ [ "no-rc" ] filtered ])); description = '' Set the mode of the shell integration. This accepts the same options as the `shell_integration` option of Kitty. Note that - `no-rc` is always implied. See + `no-rc` is always implied, unless this set to `null`. See for more details. ''; }; - enableBashIntegration = mkEnableOption "Kitty Bash integration" - // shellIntegrationDefaultOpt; + enableBashIntegration = mkShellIntegrationOption + (lib.hm.shell.mkBashIntegrationOption { inherit config; }); - enableFishIntegration = mkEnableOption "Kitty fish integration" - // shellIntegrationDefaultOpt; + enableFishIntegration = mkShellIntegrationOption + (lib.hm.shell.mkFishIntegrationOption { inherit config; }); - enableZshIntegration = mkEnableOption "Kitty Z Shell integration" - // shellIntegrationDefaultOpt; + enableZshIntegration = mkShellIntegrationOption + (lib.hm.shell.mkZshIntegrationOption { inherit config; }); }; extraConfig = mkOption { @@ -197,13 +220,22 @@ in { }; config = mkIf cfg.enable { + assertions = [{ + assertion = !(cfg.shellIntegration.mode == null + && (cfg.shellIntegration.enableBashIntegration + || cfg.shellIntegration.enableFishIntegration + || cfg.shellIntegration.enableZshIntegration)); + message = + "Cannot enable shell integration when `programs.kitty.shellIntegration.mode` is `null`"; + }]; + home.packages = [ cfg.package ] ++ optionalPackage cfg.font; xdg.configFile."kitty/kitty.conf" = { text = '' # Generated by Home Manager. # See https://sw.kovidgoyal.net/kitty/conf.html - '' + concatStringsSep "\n" [ + '' + lib.concatStringsSep "\n" [ (optionalString (cfg.font != null) '' font_family ${cfg.font.name} ${optionalString (cfg.font.size != null) @@ -213,16 +245,17 @@ in { (optionalString (cfg.themeFile != null) '' include ${pkgs.kitty-themes}/share/kitty-themes/themes/${cfg.themeFile}.conf '') - '' + (optionalString (cfg.shellIntegration.mode != null) '' # Shell integration is sourced and configured manually shell_integration ${cfg.shellIntegration.mode} - '' + '') (toKittyConfig cfg.settings) + (toKittyActionAliases cfg.actionAliases) (toKittyKeybindings cfg.keybindings) (toKittyEnv cfg.environment) cfg.extraConfig ]; - } // optionalAttrs pkgs.stdenv.hostPlatform.isLinux { + } // lib.optionalAttrs pkgs.stdenv.hostPlatform.isLinux { onChange = '' ${pkgs.procps}/bin/pkill -USR1 -u $USER kitty || true ''; @@ -231,7 +264,7 @@ in { home.activation.checkKittyTheme = mkIf (cfg.themeFile != null) (let themePath = "${pkgs.kitty-themes}/share/kitty-themes/themes/${cfg.themeFile}.conf"; - in hm.dag.entryBefore [ "writeBoundary" ] '' + in lib.hm.dag.entryBefore [ "writeBoundary" ] '' if [[ ! -f "${themePath}" ]]; then errorEcho "kitty-themes does not contain the theme file ${themePath}!" exit 1 @@ -240,7 +273,7 @@ in { xdg.configFile."kitty/macos-launch-services-cmdline" = mkIf (cfg.darwinLaunchOptions != null && pkgs.stdenv.hostPlatform.isDarwin) { - text = concatStringsSep " " cfg.darwinLaunchOptions; + text = lib.concatStringsSep " " cfg.darwinLaunchOptions; }; programs.bash.initExtra = diff --git a/modules/programs/kubecolor.nix b/modules/programs/kubecolor.nix new file mode 100644 index 000000000..bf22232f1 --- /dev/null +++ b/modules/programs/kubecolor.nix @@ -0,0 +1,94 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + cfg = config.programs.kubecolor; + yamlFormat = pkgs.formats.yaml { }; + inherit (pkgs.stdenv.hostPlatform) isDarwin; + +in { + meta.maintainers = with maintainers; [ ajgon ]; + + options.programs.kubecolor = { + enable = mkEnableOption "kubecolor - Colorize your kubectl output"; + + package = mkPackageOption pkgs "kubecolor" { }; + + enableAlias = mkOption { + type = types.bool; + default = false; + description = '' + When set to true, it will create an alias for kubectl pointing to + kubecolor, thus making kubecolor the default kubectl client. + ''; + }; + + settings = mkOption { + type = yamlFormat.type; + default = { }; + example = literalExpression '' + kubectl = lib.getExe pkgs.kubectl + preset = "dark"; + paging = "auto"; + ''; + description = '' + Configuration written to {file}`~/.kube/color.yaml` (Linux) + or {file}`Library/Application Support/kube/color.yaml` (Darwin). + See for supported + values. + ''; + }; + }; + + config = let + preferXdgDirectories = config.home.preferXdgDirectories + && (!isDarwin || config.xdg.enable); + + # https://github.com/kubecolor/kubecolor/pull/145 + configPathSuffix = if cfg.package.pname == "kubecolor" + && lib.strings.toInt (lib.versions.major cfg.package.version) == 0 + && lib.strings.toInt (lib.versions.minor cfg.package.version) < 4 then + "kube/" + else + "kube/color.yaml"; + + in mkIf cfg.enable { + warnings = optional (cfg.package == null && cfg.plugins != [ ]) '' + You have configured `enableAlias` for `kubecolor` but have not set `package`. + + The alias will not be created. + ''; + + home.packages = lib.mkIf (cfg.package != null) [ cfg.package ]; + + home.sessionVariables = if preferXdgDirectories then { + KUBECOLOR_CONFIG = "${config.xdg.configHome}/${configPathSuffix}"; + } else if isDarwin then { + KUBECOLOR_CONFIG = + "${config.home.homeDirectory}/Library/Application Support/${configPathSuffix}"; + } else + { }; + + xdg.configFile = mkIf preferXdgDirectories { + "kube/color.yaml" = mkIf (cfg.settings != { }) { + source = yamlFormat.generate "kubecolor-settings" cfg.settings; + }; + }; + + home.file = mkIf (!preferXdgDirectories) { + "Library/Application Support/kube/color.yaml" = + mkIf (isDarwin && cfg.settings != { }) { + source = yamlFormat.generate "kubecolor-settings" cfg.settings; + }; + ".kube/color.yaml" = mkIf (!isDarwin && cfg.settings != { }) { + source = yamlFormat.generate "kubecolor-settings" cfg.settings; + }; + }; + + home.shellAliases = lib.mkIf (cfg.enableAlias && (cfg.package != null)) { + kubectl = lib.getExe cfg.package; + }; + }; +} diff --git a/modules/programs/lapce.nix b/modules/programs/lapce.nix new file mode 100644 index 000000000..baf6f2404 --- /dev/null +++ b/modules/programs/lapce.nix @@ -0,0 +1,187 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.programs.lapce; + + options = { + enable = mkEnableOption "lapce"; + package = mkPackageOption pkgs "lapce" { nullable = true; }; + channel = mkOption { + type = types.enum [ "stable" "nightly" ]; + default = "stable"; + description = '' + Lapce channel to configure. + Should correspond to the package channel. + This is used to determine the correct configuration and data directories. + ''; + }; + settings = mkOption { + type = settingsFormat.type; + default = { }; + description = '' + Configuration written to {file}`$XDG_CONFIG_HOME/lapce/settings.toml`. + See for schema. + ''; + example = literalExpression '' + { + core = { + custom-titlebar = false; + color-theme = "Custom"; + icon-theme = "Material Icons"; + }; + editor = { + font-family = "FiraCode Nerd Bold Font, monospace"; + font-size = 22; + tab-width = 2; + cursor-surrounding-lines = 4; + render-whitespace = "all"; + bracket-pair-colorization = true; + highlight-matching-brackets = true; + }; + ui = { + font-size = 20; + open-editors-visible = false; + }; + lapce-nix.lsp-path = "$\{pkgs.nil\}/bin/nil"; + } + ''; + }; + plugins = mkOption { + type = types.listOf (types.submodule { + options = { + author = mkOption { + type = types.str; + description = '' + Author of the plugin. + ''; + }; + name = mkOption { + type = types.str; + description = '' + Name of the plugin. + ''; + }; + version = mkOption { + type = types.str; + description = '' + Version of the plugin. + ''; + }; + hash = mkOption { + type = types.str; + description = '' + Hash of the plugin tarball. + To find the hash leave this empty, rebuild and copy the hash from the error message. + ''; + default = ""; + }; + }; + }); + default = [ ]; + description = '' + Plugins to install. + ''; + example = literalExpression '' + [ + { + author = "MrFoxPro"; + name = "lapce-nix"; + version = "0.0.1"; + hash = "sha256-..."; + } + { + author = "dzhou121"; + name = "lapce-rust"; + version = "0.3.1932"; + hash = "sha256-..."; + } + ] + ''; + }; + keymaps = mkOption { + type = settingsFormat.type; + default = [ ]; + description = '' + Keymaps written to {file}`$XDG_CONFIG_HOME/lapce/keymaps.toml`. + See for examples. + ''; + example = literalExpression '' + [ + { + command = "open_log_file"; + key = "Ctrl+Shift+L"; + } + ] + ''; + }; + }; + + settingsFormat = pkgs.formats.toml { }; + + fetchPluginTarballFromRegistry = { author, name, version, hash }: + pkgs.stdenvNoCC.mkDerivation (let + url = + "https://plugins.lapce.dev/api/v1/plugins/${author}/${name}/${version}/download"; + file = "lapce-plugin-${author}-${name}-${version}.tar.zstd"; + in { + name = file; + nativeBuildInputs = [ pkgs.curl pkgs.cacert ]; + dontUnpack = true; + dontBuild = true; + installPhase = '' + runHook preInstall + + url="$(curl ${url})" + curl -L "$url" -o "$out" + + runHook postInstall + ''; + outputHashAlgo = "sha256"; + outputHashMode = "flat"; + outputHash = hash; + inherit meta; + }); + pluginFromRegistry = { author, name, version, hash }@args: + pkgs.stdenvNoCC.mkDerivation { + pname = "lapce-plugin-${author}-${name}"; + inherit version; + src = fetchPluginTarballFromRegistry args; + nativeBuildInputs = [ pkgs.zstd ]; + phases = [ "installPhase" ]; + installPhase = '' + runHook preInstall + + mkdir -p $out + tar -C $out -xvf $src + + runHook postInstall + ''; + }; + pluginsFromRegistry = plugins: + pkgs.linkFarm "lapce-plugins" (builtins.listToAttrs (builtins.map + ({ author, name, version, ... }@plugin: { + name = "${author}-${name}-${version}"; + value = pluginFromRegistry plugin; + }) plugins)); +in { + meta.maintainers = [ hm.maintainers.timon-schelling ]; + + options.programs.lapce = options; + + config = mkIf cfg.enable { + home.packages = lib.mkIf (cfg.package != null) [ cfg.package ]; + + xdg = let dir = "lapce-${cfg.channel}"; + in { + configFile = { + "${dir}/settings.toml".source = + settingsFormat.generate "settings.toml" cfg.settings; + "${dir}/keymaps.toml".source = + settingsFormat.generate "keymaps.toml" { keymaps = cfg.keymaps; }; + }; + dataFile."${dir}/plugins".source = pluginsFromRegistry cfg.plugins; + }; + }; +} diff --git a/modules/programs/lazygit.nix b/modules/programs/lazygit.nix index 0102a22cc..0c355c6dc 100644 --- a/modules/programs/lazygit.nix +++ b/modules/programs/lazygit.nix @@ -11,12 +11,12 @@ let inherit (pkgs.stdenv.hostPlatform) isDarwin; in { - meta.maintainers = [ hm.maintainers.kalhauge ]; + meta.maintainers = [ lib.hm.maintainers.kalhauge lib.maintainers.khaneliman ]; options.programs.lazygit = { enable = mkEnableOption "lazygit, a simple terminal UI for git commands"; - package = mkPackageOption pkgs "lazygit" { }; + package = mkPackageOption pkgs "lazygit" { nullable = true; }; settings = mkOption { type = yamlFormat.type; @@ -45,7 +45,7 @@ in { }; config = mkIf cfg.enable { - home.packages = [ cfg.package ]; + home.packages = lib.mkIf (cfg.package != null) [ cfg.package ]; home.file."Library/Application Support/lazygit/config.yml" = mkIf (cfg.settings != { } && (isDarwin && !config.xdg.enable)) { diff --git a/modules/programs/ledger.nix b/modules/programs/ledger.nix index 1b9178d15..441fc1574 100644 --- a/modules/programs/ledger.nix +++ b/modules/programs/ledger.nix @@ -21,7 +21,7 @@ in { options.programs.ledger = { enable = mkEnableOption "ledger, a double-entry accounting system"; - package = mkPackageOption pkgs "ledger" { }; + package = mkPackageOption pkgs "ledger" { nullable = true; }; settings = mkOption { type = with types; attrsOf (oneOf [ bool int str (listOf str) ]); @@ -59,7 +59,7 @@ in { }; config = mkIf cfg.enable { - home.packages = [ cfg.package ]; + home.packages = lib.mkIf (cfg.package != null) [ cfg.package ]; xdg.configFile."ledger/ledgerrc" = mkIf (cfg.settings != { } || cfg.extraConfig != "") { diff --git a/modules/programs/lesspipe.nix b/modules/programs/lesspipe.nix index a7a51ffe2..a9bca2791 100644 --- a/modules/programs/lesspipe.nix +++ b/modules/programs/lesspipe.nix @@ -2,18 +2,24 @@ with lib; -{ +let + + cfg = config.programs.lesspipe; + +in { meta.maintainers = [ maintainers.rycee ]; options = { programs.lesspipe = { enable = mkEnableOption "lesspipe preprocessor for less"; + + package = mkPackageOption pkgs "lesspipe" { }; }; }; - config = mkIf config.programs.lesspipe.enable { + config = mkIf cfg.enable { home.sessionVariables = { - LESSOPEN = "|${pkgs.lesspipe}/bin/lesspipe.sh %s"; + LESSOPEN = "|${cfg.package}/bin/lesspipe.sh %s"; }; }; } diff --git a/modules/programs/librewolf.nix b/modules/programs/librewolf.nix index d8b6dfabb..86f640c81 100644 --- a/modules/programs/librewolf.nix +++ b/modules/programs/librewolf.nix @@ -14,20 +14,31 @@ let '') prefs)} ''; + modulePath = [ "programs" "librewolf" ]; + + mkFirefoxModule = import ./firefox/mkFirefoxModule.nix; + in { - meta.maintainers = [ maintainers.onny ]; + meta.maintainers = [ maintainers.chayleaf maintainers.onny ]; + + imports = [ + (mkFirefoxModule { + inherit modulePath; + name = "LibreWolf"; + description = "LibreWolf is a privacy enhanced Firefox fork."; + wrappedPackageName = "librewolf"; + unwrappedPackageName = "librewolf-unwrapped"; + + platforms.linux = { configPath = ".librewolf"; }; + platforms.darwin = { + configPath = "Library/Application Support/LibreWolf"; + }; + + enableBookmarks = false; + }) + ]; options.programs.librewolf = { - enable = - mkEnableOption "Librewolf browser, a privacy enhanced Firefox fork"; - - package = mkOption { - type = types.package; - default = pkgs.librewolf; - defaultText = literalExpression "pkgs.librewolf"; - description = "The LibreWolf package to use."; - }; - settings = mkOption { type = with types; attrsOf (either bool (either int str)); default = { }; @@ -38,7 +49,7 @@ in { } ''; description = '' - Attribute set of LibreWolf settings and overrides. Refer to + Attribute set of global LibreWolf settings and overrides. Refer to for details on supported values. ''; @@ -46,14 +57,7 @@ in { }; config = mkIf cfg.enable { - assertions = [ - (lib.hm.assertions.assertPlatform "programs.librewolf" pkgs - lib.platforms.linux) - ]; - - home.packages = [ cfg.package ]; - - home.file.".librewolf/librewolf.overrides.cfg".text = - mkOverridesFile cfg.settings; + home.file.".librewolf/librewolf.overrides.cfg" = + lib.mkIf (cfg.settings != { }) { text = mkOverridesFile cfg.settings; }; }; } diff --git a/modules/programs/looking-glass-client.nix b/modules/programs/looking-glass-client.nix index 1c14282b9..c17802441 100644 --- a/modules/programs/looking-glass-client.nix +++ b/modules/programs/looking-glass-client.nix @@ -11,7 +11,7 @@ in { options.programs.looking-glass-client = { enable = mkEnableOption "looking-glass-client"; - package = mkPackageOption pkgs "looking-glass-client" { }; + package = mkPackageOption pkgs "looking-glass-client" { nullable = true; }; settings = mkOption { type = settingsFormat.type; @@ -50,7 +50,7 @@ in { platforms.linux) ]; - home.packages = [ cfg.package ]; + home.packages = lib.mkIf (cfg.package != null) [ cfg.package ]; xdg.configFile."looking-glass/client.ini" = mkIf (cfg.settings != { }) { source = diff --git a/modules/programs/lsd.nix b/modules/programs/lsd.nix index 0053a494f..fecff3c6e 100644 --- a/modules/programs/lsd.nix +++ b/modules/programs/lsd.nix @@ -1,7 +1,5 @@ { config, lib, pkgs, ... }: -with lib; - let cfg = config.programs.lsd; @@ -21,17 +19,17 @@ in { meta.maintainers = [ ]; options.programs.lsd = { - enable = mkEnableOption "lsd"; + enable = lib.mkEnableOption "lsd"; - enableAliases = mkOption { + enableAliases = lib.mkOption { default = false; - type = types.bool; + type = lib.types.bool; description = '' Whether to enable recommended lsd aliases. ''; }; - settings = mkOption { + settings = lib.mkOption { type = yamlFormat.type; default = { }; example = { @@ -46,7 +44,7 @@ in { ''; }; - colors = mkOption { + colors = lib.mkOption { type = yamlFormat.type; default = { }; example = { @@ -65,33 +63,61 @@ in { automatically set to `"custom"`. ''; }; + + icons = lib.mkOption { + type = yamlFormat.type; + default = { }; + example = { + name = { + ".trash" = ""; + ".cargo" = ""; + }; + extension = { + "go" = ""; + "hs" = ""; + }; + filetype = { + "dir" = "📂"; + "file" = "📄"; + }; + }; + description = '' + Configuration written to {file}`$XDG_CONFIG_HOME/lsd/icons.yaml`. See + for + details. + ''; + }; }; - config = mkIf cfg.enable { + config = lib.mkIf cfg.enable { home.packages = [ pkgs.lsd ]; - programs.bash.shellAliases = mkIf cfg.enableAliases aliases; + programs.bash.shellAliases = lib.mkIf cfg.enableAliases aliases; - programs.zsh.shellAliases = mkIf cfg.enableAliases aliases; + programs.zsh.shellAliases = lib.mkIf cfg.enableAliases aliases; - programs.fish = mkMerge [ - (mkIf (!config.programs.fish.preferAbbrs) { - shellAliases = mkIf cfg.enableAliases aliases; + programs.fish = lib.mkMerge [ + (lib.mkIf (!config.programs.fish.preferAbbrs) { + shellAliases = lib.mkIf cfg.enableAliases aliases; }) - (mkIf config.programs.fish.preferAbbrs { - shellAbbrs = mkIf cfg.enableAliases aliases; + (lib.mkIf config.programs.fish.preferAbbrs { + shellAbbrs = lib.mkIf cfg.enableAliases aliases; }) ]; programs.lsd = - mkIf (cfg.colors != { }) { settings.color.theme = "custom"; }; + lib.mkIf (cfg.colors != { }) { settings.color.theme = "custom"; }; - xdg.configFile."lsd/colors.yaml" = mkIf (cfg.colors != { }) { + xdg.configFile."lsd/colors.yaml" = lib.mkIf (cfg.colors != { }) { source = yamlFormat.generate "lsd-colors" cfg.colors; }; - xdg.configFile."lsd/config.yaml" = mkIf (cfg.settings != { }) { + xdg.configFile."lsd/icons.yaml" = lib.mkIf (cfg.icons != { }) { + source = yamlFormat.generate "lsd-icons" cfg.icons; + }; + + xdg.configFile."lsd/config.yaml" = lib.mkIf (cfg.settings != { }) { source = yamlFormat.generate "lsd-config" cfg.settings; }; }; diff --git a/modules/programs/mangohud.nix b/modules/programs/mangohud.nix index f0e35a3a3..035a4744b 100644 --- a/modules/programs/mangohud.nix +++ b/modules/programs/mangohud.nix @@ -13,7 +13,7 @@ let int = toString option; float = int; path = int; - bool = "false"; + bool = "0"; # "on/off" opts are disabled with `=0` string = option; list = concatStringsSep "," (lists.forEach option (x: toString x)); }.${builtins.typeOf option}; @@ -68,7 +68,7 @@ in { { mpv = { no_display = true; - } + }; } ''; description = '' diff --git a/modules/programs/mbsync-accounts.nix b/modules/programs/mbsync-accounts.nix index abe5a8ca8..8dc03b122 100644 --- a/modules/programs/mbsync-accounts.nix +++ b/modules/programs/mbsync-accounts.nix @@ -225,6 +225,8 @@ in { default = { }; example = literalExpression '' { + TLSType = "IMAP"; + TLSVersions = [ "+1.3" "+1.2" "-1.1" ]; PipelineDepth = 10; Timeout = 60; }; diff --git a/modules/programs/mbsync.nix b/modules/programs/mbsync.nix index 3437602e9..f9dffd2f4 100644 --- a/modules/programs/mbsync.nix +++ b/modules/programs/mbsync.nix @@ -30,7 +30,7 @@ let genTlsConfig = tls: { - SSLType = if !tls.enable then + TLSType = if !tls.enable then "None" else if tls.useStartTls then "STARTTLS" @@ -267,7 +267,7 @@ in { programs.notmuch.new.ignore = [ ".uidvalidity" ".mbsyncstate" ]; - home.file.".mbsyncrc".text = let + xdg.configFile."isyncrc".text = let accountsConfig = map genAccountConfig mbsyncAccounts; # Only generate this kind of Group configuration if there are ANY accounts # that do NOT have a per-account groups/channels option(s) specified. @@ -288,7 +288,8 @@ in { createMaildir = hm.dag.entryBetween [ "linkGeneration" ] [ "writeBoundary" ] '' run mkdir -m700 -p $VERBOSE_ARG ${ - concatMapStringsSep " " (a: a.maildir.absPath) mbsyncAccounts + concatMapStringsSep " " (a: escapeShellArg a.maildir.absPath) + mbsyncAccounts } ''; }; diff --git a/modules/programs/mcfly.nix b/modules/programs/mcfly.nix index d0dddba21..cf115129d 100644 --- a/modules/programs/mcfly.nix +++ b/modules/programs/mcfly.nix @@ -109,29 +109,14 @@ in { ''; }; - enableBashIntegration = mkOption { - default = true; - type = types.bool; - description = '' - Whether to enable Bash integration. - ''; - }; + enableBashIntegration = + lib.hm.shell.mkBashIntegrationOption { inherit config; }; - enableZshIntegration = mkOption { - default = true; - type = types.bool; - description = '' - Whether to enable Zsh integration. - ''; - }; + enableFishIntegration = + lib.hm.shell.mkFishIntegrationOption { inherit config; }; - enableFishIntegration = mkOption { - default = true; - type = types.bool; - description = '' - Whether to enable Fish integration. - ''; - }; + enableZshIntegration = + lib.hm.shell.mkZshIntegrationOption { inherit config; }; }; config = mkIf cfg.enable (mkMerge [ diff --git a/modules/programs/micro.nix b/modules/programs/micro.nix index bf34f8e62..acd768679 100644 --- a/modules/programs/micro.nix +++ b/modules/programs/micro.nix @@ -15,7 +15,7 @@ in { programs.micro = { enable = mkEnableOption "micro, a terminal-based text editor"; - package = mkPackageOption pkgs "micro" { }; + package = mkPackageOption pkgs "micro" { nullable = true; }; settings = mkOption { type = jsonFormat.type; @@ -37,7 +37,7 @@ in { }; config = mkIf cfg.enable { - home.packages = [ cfg.package ]; + home.packages = lib.mkIf (cfg.package != null) [ cfg.package ]; xdg.configFile."micro/settings.json".source = jsonFormat.generate "micro-settings" cfg.settings; diff --git a/modules/programs/mise.nix b/modules/programs/mise.nix index 404f1bf9c..3ab263526 100644 --- a/modules/programs/mise.nix +++ b/modules/programs/mise.nix @@ -21,6 +21,7 @@ in { "enableBashIntegration" "enableZshIntegration" "enableFishIntegration" + "enableNushellIntegration" "settings" ]; @@ -28,19 +29,19 @@ in { programs.mise = { enable = mkEnableOption "mise"; - package = mkPackageOption pkgs "mise" { }; + package = mkPackageOption pkgs "mise" { nullable = true; }; - enableBashIntegration = mkEnableOption "Bash Integration" // { - default = true; - }; + enableBashIntegration = + lib.hm.shell.mkBashIntegrationOption { inherit config; }; - enableZshIntegration = mkEnableOption "Zsh Integration" // { - default = true; - }; + enableFishIntegration = + lib.hm.shell.mkFishIntegrationOption { inherit config; }; - enableFishIntegration = mkEnableOption "Fish Integration" // { - default = true; - }; + enableZshIntegration = + lib.hm.shell.mkZshIntegrationOption { inherit config; }; + + enableNushellIntegration = + lib.hm.shell.mkNushellIntegrationOption { inherit config; }; globalConfig = mkOption { type = tomlFormat.type; @@ -82,7 +83,15 @@ in { }; config = mkIf cfg.enable { - home.packages = [ cfg.package ]; + warnings = optional (cfg.package == null && (cfg.enableBashIntegration + || cfg.enableZshIntegration || cfg.enableFishIntegration + || cfg.enableNushellIntegration)) '' + You have enabled shell integration for `mise` but have not set `package`. + + The shell integration will not be added. + ''; + + home.packages = lib.mkIf (cfg.package != null) [ cfg.package ]; xdg.configFile = { "mise/config.toml" = mkIf (cfg.globalConfig != { }) { @@ -106,6 +115,16 @@ in { fish.interactiveShellInit = mkIf cfg.enableFishIntegration '' ${getExe cfg.package} activate fish | source ''; + + nushell = mkIf cfg.enableNushellIntegration { + extraEnv = '' + let mise_path = $nu.default-config-dir | path join mise.nu + ^mise activate nu | save $mise_path --force + ''; + extraConfig = '' + use ($nu.default-config-dir | path join mise.nu) + ''; + }; }; }; } diff --git a/modules/programs/mods.nix b/modules/programs/mods.nix new file mode 100644 index 000000000..95e5559bc --- /dev/null +++ b/modules/programs/mods.nix @@ -0,0 +1,77 @@ +{ config, lib, pkgs, ... }: + +with lib; +let + cfg = config.programs.mods; + yamlFormat = pkgs.formats.yaml { }; +in { + meta.maintainers = [ hm.maintainers.ipsavitsky ]; + + options.programs.mods = { + enable = mkEnableOption "mods"; + + package = mkOption { + type = types.package; + default = pkgs.mods; + defaultText = literalExpression "pkgs.mods"; + description = "The mods package to install"; + }; + + settings = mkOption { + type = yamlFormat.type; + default = { }; + example = '' + { + default-model = "llama3.2"; + apis = { + ollama = { + base-url = "http://localhost:11434/api"; + models = { + "llama3.2" = { + max-input-chars = 650000; + }; + }; + }; + }; + } + ''; + description = '' + Configuration written to + {file}`$XDG_CONFIG_HOME/mods/mods.yml`. + + See for the full + list of options. + ''; + }; + + enableBashIntegration = + lib.hm.shell.mkBashIntegrationOption { inherit config; }; + + enableZshIntegration = + lib.hm.shell.mkZshIntegrationOption { inherit config; }; + + enableFishIntegration = + lib.hm.shell.mkFishIntegrationOption { inherit config; }; + }; + + config = mkIf cfg.enable { + home.packages = [ cfg.package ]; + + xdg.configFile."mods/mods.yml" = mkIf (cfg.settings != { }) { + source = yamlFormat.generate "mods.yml" cfg.settings; + }; + + programs.bash.initExtra = mkIf cfg.enableBashIntegration (mkOrder 200 '' + source <(${cfg.package}/bin/mods completion bash) + ''); + + programs.zsh.initExtra = mkIf cfg.enableZshIntegration (mkOrder 200 '' + source <(${cfg.package}/bin/mods completion zsh) + ''); + + programs.fish.interactiveShellInit = mkIf cfg.enableFishIntegration + (mkOrder 200 '' + ${cfg.package}/bin/mods completion fish | source + ''); + }; +} diff --git a/modules/programs/mpv.nix b/modules/programs/mpv.nix index f2664e71a..b62208763 100644 --- a/modules/programs/mpv.nix +++ b/modules/programs/mpv.nix @@ -55,10 +55,8 @@ let mpvPackage = if cfg.scripts == [ ] then cfg.package - else if hasAttr "wrapMpv" pkgs then - pkgs.wrapMpv pkgs.mpv-unwrapped { scripts = cfg.scripts; } else - pkgs.mpv.override { scripts = cfg.scripts; }; + pkgs.mpv.override { inherit (cfg) scripts; }; in { options = { @@ -69,7 +67,7 @@ in { type = types.package; default = pkgs.mpv; example = literalExpression - "pkgs.wrapMpv (pkgs.mpv-unwrapped.override { vapoursynthSupport = true; }) { youtubeSupport = true; }"; + "pkgs.mpv-unwrapped.wrapper { mpv = pkgs.mpv-unwrapped.override { vapoursynthSupport = true; }; youtubeSupport = true; }"; description = '' Package providing mpv. ''; @@ -130,6 +128,19 @@ in { ''; }; + includes = mkOption { + type = types.listOf types.str; + default = [ ]; + example = literalExpression '' + [ + "~/path/to/config.inc"; + "~/path/to/conditional.inc"; + ] + ''; + description = + "List of configuration files to include at the end of mpv.conf."; + }; + profiles = mkOption { description = '' Sub-configuration options for specific profiles written to @@ -207,6 +218,14 @@ in { home.packages = [ mpvPackage ]; programs.mpv.finalPackage = mpvPackage; } + + (mkIf (cfg.includes != [ ]) { + xdg.configFile."mpv/mpv.conf" = { + text = lib.mkAfter + (concatMapStringsSep "\n" (x: "include=${x}") cfg.includes); + }; + }) + (mkIf (cfg.config != { } || cfg.profiles != { }) { xdg.configFile."mpv/mpv.conf".text = '' ${optionalString (cfg.defaultProfiles != [ ]) diff --git a/modules/programs/mr.nix b/modules/programs/mr.nix index 507189769..140aff32d 100644 --- a/modules/programs/mr.nix +++ b/modules/programs/mr.nix @@ -17,7 +17,7 @@ in { enable = mkEnableOption "mr, a tool to manage all your version control repositories"; - package = mkPackageOption pkgs "mr" { }; + package = mkPackageOption pkgs "mr" { nullable = true; }; settings = mkOption { type = iniFormat.type; @@ -42,7 +42,7 @@ in { }; config = mkIf cfg.enable { - home.packages = [ cfg.package ]; + home.packages = lib.mkIf (cfg.package != null) [ cfg.package ]; home.file.".mrconfig".source = iniFormat.generate ".mrconfig" cfg.settings; }; } diff --git a/modules/programs/mu.nix b/modules/programs/mu.nix index 4d051d4da..fdb85f85a 100644 --- a/modules/programs/mu.nix +++ b/modules/programs/mu.nix @@ -9,17 +9,23 @@ let # Used to generate command line arguments that mu can operate with. genCmdMaildir = path: "--maildir=" + path; - # Takes the list of accounts with mu.enable = true, and generates a - # command-line flag for initializing the mu database. - myAddresses = let + # Sorted list of personal email addresses to register + sortedAddresses = let # Set of email account sets where mu.enable = true. muAccounts = filter (a: a.mu.enable) (attrValues config.accounts.email.accounts); addrs = map (a: a.address) muAccounts; # Construct list of lists containing email aliases, and flatten - aliases = flatten (map (a: a.aliases) muAccounts); - # Prefix --my-address= to each account's address AND all defined aliases - addMyAddress = map (addr: "--my-address=" + addr) (addrs ++ aliases); + aliases = map (alias: alias.address or alias) + (flatten (map (a: a.aliases) muAccounts)); + # Sort the list + in sort lessThan (addrs ++ aliases); + + # Takes the list of accounts with mu.enable = true, and generates a + # command-line flag for initializing the mu database. + myAddresses = let + # Prefix --my-address= to each account's address and all defined aliases + addMyAddress = map (addr: "--my-address=" + addr) sortedAddresses; in concatStringsSep " " addMyAddress; in { @@ -31,6 +37,16 @@ in { package = mkPackageOption pkgs "mu" { }; + home = mkOption { + type = types.path; + default = config.xdg.cacheHome + "/mu"; + defaultText = literalExpression ''config.xdg.cacheHome + "/mu"''; + example = "\${config.home.homeDirectory}/Maildir/.mu"; + description = '' + Directory to store Mu's database. + ''; + }; + # No options/config file present for mu, and program author will not be # adding one soon. See https://github.com/djcb/mu/issues/882 for more # information about this. @@ -46,17 +62,24 @@ in { config = mkIf cfg.enable { home.packages = [ cfg.package ]; + home.sessionVariables.MUHOME = cfg.home; + home.activation.runMuInit = let maildirOption = genCmdMaildir config.accounts.email.maildirBasePath; - dbLocation = config.xdg.cacheHome + "/mu"; + muExe = getExe cfg.package; + gawkExe = getExe pkgs.gawk; in hm.dag.entryAfter [ "writeBoundary" ] '' - # If the database directory exists, then `mu init` should NOT be run. + # If the database directory exists and registered personal addresses remain the same, + # then `mu init` should NOT be run. # In theory, mu is the only thing that creates that directory, and it is # only created during the initial index. - if [[ ! -d "${dbLocation}" ]]; then - run ${ - getExe cfg.package - } init ${maildirOption} ${myAddresses} $VERBOSE_ARG; + MU_SORTED_ADDRS=$((${muExe} info store | ${gawkExe} '/personal-address/{print $4}' | LC_ALL=C sort | paste -sd ' ') || exit 0) + if [[ ! -d "${cfg.home}" || ! "$MU_SORTED_ADDRS" = "${ + concatStringsSep " " sortedAddresses + }" ]]; then + run ${muExe} init ${maildirOption} --muhome "${ + escapeShellArg cfg.home + }" ${myAddresses} $VERBOSE_ARG; fi ''; }; diff --git a/modules/programs/navi.nix b/modules/programs/navi.nix index aff50b5c7..e8399fd1c 100644 --- a/modules/programs/navi.nix +++ b/modules/programs/navi.nix @@ -7,7 +7,7 @@ let yamlFormat = pkgs.formats.yaml { }; - configDir = if pkgs.stdenv.isDarwin then + configDir = if pkgs.stdenv.isDarwin && !config.xdg.enable then "Library/Application Support" else config.xdg.configHome; @@ -47,17 +47,14 @@ in { ''; }; - enableBashIntegration = mkEnableOption "Bash integration" // { - default = true; - }; + enableBashIntegration = + lib.hm.shell.mkBashIntegrationOption { inherit config; }; - enableZshIntegration = mkEnableOption "Zsh integration" // { - default = true; - }; + enableFishIntegration = + lib.hm.shell.mkFishIntegrationOption { inherit config; }; - enableFishIntegration = mkEnableOption "Fish integration" // { - default = true; - }; + enableZshIntegration = + lib.hm.shell.mkZshIntegrationOption { inherit config; }; }; config = mkIf cfg.enable { diff --git a/modules/programs/neomutt.nix b/modules/programs/neomutt.nix index 588b801e4..13ee897f1 100644 --- a/modules/programs/neomutt.nix +++ b/modules/programs/neomutt.nix @@ -123,14 +123,18 @@ let "smime" ]; in with types; either (enum menus) (listOf (enum menus)); - default = "index"; + default = [ "index" ]; description = "Select the menu to bind the command to."; }; key = mkOption { type = types.str; example = ""; - description = "The key to bind."; + description = '' + The key to bind. + + If you want to bind '\Cp' for example, which would be Ctrl + 'p', you need to escape twice: '\\Cp'! + ''; }; action = mkOption { @@ -368,7 +372,12 @@ in { sort = mkOption { # allow users to choose any option from sortOptions, or any option prefixed with "reverse-" type = types.enum - (sortOptions ++ (map (option: "reverse-" + option) sortOptions)); + (builtins.concatMap (_pre: map (_opt: _pre + _opt) sortOptions) [ + "" + "reverse-" + "last-" + "reverse-last-" + ]); default = "threads"; description = "Sorting method on messages."; }; diff --git a/modules/programs/neovide.nix b/modules/programs/neovide.nix index 3b40fb3eb..74d1a8e7b 100644 --- a/modules/programs/neovide.nix +++ b/modules/programs/neovide.nix @@ -11,7 +11,7 @@ in { options.programs.neovide = { enable = lib.mkEnableOption "Neovide, No Nonsense Neovim Client in Rust"; - package = lib.mkPackageOption pkgs "neovide" { }; + package = lib.mkPackageOption pkgs "neovide" { nullable = true; }; settings = lib.mkOption { type = settingsFormat.type; @@ -45,7 +45,7 @@ in { }; config = lib.mkIf cfg.enable { - home.packages = [ cfg.package ]; + home.packages = lib.mkIf (cfg.package != null) [ cfg.package ]; xdg.configFile."neovide/config.toml".source = settingsFormat.generate "config.toml" cfg.settings; }; diff --git a/modules/programs/neovim.nix b/modules/programs/neovim.nix index 8632a7ec8..af7a1a1f0 100644 --- a/modules/programs/neovim.nix +++ b/modules/programs/neovim.nix @@ -1,8 +1,8 @@ { config, lib, pkgs, ... }: -with lib; - let + inherit (lib) + literalExpression mkEnableOption mkIf mkOption mkRemovedOptionModule types; cfg = config.programs.neovim; @@ -55,7 +55,7 @@ let }; }; - allPlugins = cfg.plugins ++ optional cfg.coc.enable { + allPlugins = cfg.plugins ++ lib.optional cfg.coc.enable { type = "viml"; plugin = cfg.coc.package; config = cfg.coc.pluginConfig; @@ -95,6 +95,8 @@ in { '') ]; + meta.maintainers = with lib.maintainers; [ khaneliman ]; + options = { programs.neovim = { enable = mkEnableOption "Neovim"; @@ -153,15 +155,14 @@ in { # In case we get a plain list, we need to turn it into a function, # as expected by the function in nixpkgs. # The only way to do so is to call `const`, which will ignore its input. - type = with types; - let fromType = listOf package; - in coercedTo fromType (flip warn const '' - Assigning a plain list to extraPython3Packages is deprecated. - Please assign a function taking a package set as argument, so - extraPython3Packages = [ pkgs.python3Packages.xxx ]; - should become - extraPython3Packages = ps: [ ps.xxx ]; - '') (functionTo fromType); + type = let fromType = types.listOf types.package; + in types.coercedTo fromType (lib.flip lib.warn lib.const '' + Assigning a plain list to extraPython3Packages is deprecated. + Please assign a function taking a package set as argument, so + extraPython3Packages = [ pkgs.python3Packages.xxx ]; + should become + extraPython3Packages = ps: [ ps.xxx ]; + '') (types.functionTo fromType); default = _: [ ]; defaultText = literalExpression "ps: [ ]"; example = @@ -178,15 +179,14 @@ in { # Lua packageset to evaluate the function that this option was set to. # This ensures that we always use the same Lua version as the Neovim package. extraLuaPackages = mkOption { - type = with types; - let fromType = listOf package; - in coercedTo fromType (flip warn const '' - Assigning a plain list to extraLuaPackages is deprecated. - Please assign a function taking a package set as argument, so - extraLuaPackages = [ pkgs.lua51Packages.xxx ]; - should become - extraLuaPackages = ps: [ ps.xxx ]; - '') (functionTo fromType); + type = let fromType = types.listOf types.package; + in types.coercedTo fromType (lib.flip lib.warn lib.const '' + Assigning a plain list to extraLuaPackages is deprecated. + Please assign a function taking a package set as argument, so + extraLuaPackages = [ pkgs.lua51Packages.xxx ]; + should become + extraLuaPackages = ps: [ ps.xxx ]; + '') (types.functionTo fromType); default = _: [ ]; defaultText = literalExpression "ps: [ ]"; example = literalExpression "luaPkgs: with luaPkgs; [ luautf8 ]"; @@ -398,6 +398,13 @@ in { customRC = cfg.extraConfig; }; + wrappedNeovim' = pkgs.wrapNeovimUnstable cfg.package (neovimConfig // { + wrapperArgs = + (lib.escapeShellArgs (neovimConfig.wrapperArgs ++ cfg.extraWrapperArgs)) + + " " + extraMakeWrapperArgs + " " + extraMakeWrapperLuaCArgs + " " + + extraMakeWrapperLuaArgs; + wrapRc = false; + }); in mkIf cfg.enable { programs.neovim.generatedConfigViml = neovimConfig.neovimRcContent; @@ -407,7 +414,7 @@ in { concatConfigs = lib.concatMapStrings (p: p.config); configsOnly = lib.foldl (acc: p: if p.config != null then acc ++ [ p.config ] else acc) [ ]; - in mapAttrs (name: vals: lib.concatStringsSep "\n" (configsOnly vals)) + in lib.mapAttrs (name: vals: lib.concatStringsSep "\n" (configsOnly vals)) grouped; home.packages = [ cfg.finalPackage ]; @@ -416,34 +423,25 @@ in { home.shellAliases = mkIf cfg.vimdiffAlias { vimdiff = "nvim -d"; }; - xdg.configFile = - let hasLuaConfig = hasAttr "lua" config.programs.neovim.generatedConfigs; - in mkMerge ( - # writes runtime - (map (x: x.runtime) pluginsNormalized) ++ [{ - "nvim/init.lua" = let - luaRcContent = - lib.optionalString (neovimConfig.neovimRcContent != "") - "vim.cmd [[source ${ - pkgs.writeText "nvim-init-home-manager.vim" - neovimConfig.neovimRcContent - }]]" + config.programs.neovim.extraLuaConfig - + lib.optionalString hasLuaConfig - config.programs.neovim.generatedConfigs.lua; - in mkIf (luaRcContent != "") { text = luaRcContent; }; + xdg.configFile = let + hasLuaConfig = lib.hasAttr "lua" config.programs.neovim.generatedConfigs; + in lib.mkMerge ( + # writes runtime + (map (x: x.runtime) pluginsNormalized) ++ [{ + "nvim/init.lua" = let + luaRcContent = lib.optionalString (wrappedNeovim'.initRc != "") + "vim.cmd [[source ${ + pkgs.writeText "nvim-init-home-manager.vim" wrappedNeovim'.initRc + }]]" + config.programs.neovim.extraLuaConfig + + lib.optionalString hasLuaConfig + config.programs.neovim.generatedConfigs.lua; + in mkIf (luaRcContent != "") { text = luaRcContent; }; - "nvim/coc-settings.json" = mkIf cfg.coc.enable { - source = jsonFormat.generate "coc-settings.json" cfg.coc.settings; - }; - }]); + "nvim/coc-settings.json" = mkIf cfg.coc.enable { + source = jsonFormat.generate "coc-settings.json" cfg.coc.settings; + }; + }]); - programs.neovim.finalPackage = pkgs.wrapNeovimUnstable cfg.package - (neovimConfig // { - wrapperArgs = (lib.escapeShellArgs - (neovimConfig.wrapperArgs ++ cfg.extraWrapperArgs)) + " " - + extraMakeWrapperArgs + " " + extraMakeWrapperLuaCArgs + " " - + extraMakeWrapperLuaArgs; - wrapRc = false; - }); + programs.neovim.finalPackage = wrappedNeovim'; }; } diff --git a/modules/programs/nh.nix b/modules/programs/nh.nix new file mode 100644 index 000000000..7e6e993fd --- /dev/null +++ b/modules/programs/nh.nix @@ -0,0 +1,89 @@ +{ config, osConfig, lib, pkgs, ... }: + +let + + cfg = config.programs.nh; + +in { + meta.maintainers = with lib.maintainers; [ johnrtitor ]; + + options.programs.nh = { + enable = lib.mkEnableOption "nh, yet another Nix CLI helper"; + + package = lib.mkPackageOption pkgs "nh" { }; + + flake = lib.mkOption { + type = lib.types.nullOr lib.types.singleLineStr; + default = null; + description = '' + The path that will be used for the {env}`FLAKE` environment variable. + + {env}`FLAKE` is used by nh as the default flake for performing actions, + like {command}`nh os switch`. + ''; + }; + + clean = { + enable = lib.mkEnableOption '' + periodic garbage collection for user profile and nix store with nh clean + user''; + + dates = lib.mkOption { + type = lib.types.singleLineStr; + default = "weekly"; + description = '' + How often cleanup is performed. + + The format is described in {manpage}`systemd.time(7)`. + ''; + }; + + extraArgs = lib.mkOption { + type = lib.types.singleLineStr; + default = ""; + example = "--keep 5 --keep-since 3d"; + description = '' + Options given to nh clean when the service is run automatically. + + See `nh clean all --help` for more information. + ''; + }; + }; + }; + + config = { + warnings = (lib.optional + (cfg.clean.enable && osConfig != null && osConfig.nix.gc.automatic) + "programs.nh.clean.enable and nix.gc.automatic (system-wide in configuration.nix) are both enabled. Please use one or the other to avoid conflict.") + ++ (lib.optional (cfg.clean.enable && config.nix.gc.automatic) + "programs.nh.clean.enable and nix.gc.automatic (Home-Manager) are both enabled. Please use one or the other to avoid conflict."); + + home = lib.mkIf cfg.enable { + packages = [ cfg.package ]; + sessionVariables = lib.mkIf (cfg.flake != null) { FLAKE = cfg.flake; }; + }; + + systemd.user = lib.mkIf cfg.clean.enable { + services.nh-clean = { + Unit.Description = "Nh clean (user)"; + + Service = { + Type = "oneshot"; + ExecStart = + "${lib.getExe cfg.package} clean user ${cfg.clean.extraArgs}"; + }; + }; + + timers.nh-clean = { + Unit.Description = "Run nh clean"; + + Timer = { + OnCalendar = cfg.clean.dates; + Persistent = true; + }; + + Install.WantedBy = [ "timers.target" ]; + }; + }; + }; +} diff --git a/modules/programs/nheko.nix b/modules/programs/nheko.nix index 1bf1ae706..0e858b30e 100644 --- a/modules/programs/nheko.nix +++ b/modules/programs/nheko.nix @@ -24,7 +24,7 @@ in { options.programs.nheko = { enable = mkEnableOption "Qt desktop client for Matrix"; - package = mkPackageOption pkgs "nheko" { }; + package = mkPackageOption pkgs "nheko" { nullable = true; }; settings = mkOption { type = iniFmt.type; @@ -64,7 +64,7 @@ in { }; config = mkIf cfg.enable { - home.packages = [ cfg.package ]; + home.packages = lib.mkIf (cfg.package != null) [ cfg.package ]; home.file."${configDir}/nheko/nheko.conf" = mkIf (cfg.settings != { }) { text = '' diff --git a/modules/programs/nix-index.nix b/modules/programs/nix-index.nix index cdf3151c6..f483cd2bc 100644 --- a/modules/programs/nix-index.nix +++ b/modules/programs/nix-index.nix @@ -1,7 +1,8 @@ { config, lib, pkgs, ... }: let cfg = config.programs.nix-index; in { - meta.maintainers = with lib.hm.maintainers; [ ambroisie ]; + meta.maintainers = + [ lib.hm.maintainers.ambroisie lib.maintainers.khaneliman ]; options.programs.nix-index = with lib; { enable = mkEnableOption "nix-index, a file database for nixpkgs"; @@ -13,17 +14,14 @@ in { description = "Package providing the {command}`nix-index` tool."; }; - enableBashIntegration = mkEnableOption "Bash integration" // { - default = true; - }; + enableBashIntegration = + lib.hm.shell.mkBashIntegrationOption { inherit config; }; - enableZshIntegration = mkEnableOption "Zsh integration" // { - default = true; - }; + enableFishIntegration = + lib.hm.shell.mkFishIntegrationOption { inherit config; }; - enableFishIntegration = mkEnableOption "Fish integration" // { - default = true; - }; + enableZshIntegration = + lib.hm.shell.mkZshIntegrationOption { inherit config; }; }; config = lib.mkIf cfg.enable { diff --git a/modules/programs/nix-your-shell.nix b/modules/programs/nix-your-shell.nix new file mode 100644 index 000000000..adace4e15 --- /dev/null +++ b/modules/programs/nix-your-shell.nix @@ -0,0 +1,53 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + cfg = config.programs.nix-your-shell; + +in { + meta.maintainers = [ maintainers.terlar ]; + + options.programs.nix-your-shell = { + enable = mkEnableOption '' + {command}`nix-your-shell`, a wrapper for `nix develop` or `nix-shell` + to retain the same shell inside the new environment''; + + package = mkPackageOption pkgs "nix-your-shell" { }; + + enableFishIntegration = + lib.hm.shell.mkFishIntegrationOption { inherit config; }; + + enableNushellIntegration = + lib.hm.shell.mkNushellIntegrationOption { inherit config; }; + + enableZshIntegration = + lib.hm.shell.mkZshIntegrationOption { inherit config; }; + }; + + config = mkIf cfg.enable { + home.packages = [ cfg.package ]; + + programs = { + fish.interactiveShellInit = mkIf cfg.enableFishIntegration '' + ${cfg.package}/bin/nix-your-shell fish | source + ''; + + nushell = mkIf cfg.enableNushellIntegration { + extraEnv = '' + mkdir ${config.xdg.cacheHome}/nix-your-shell + ${cfg.package}/bin/nix-your-shell nu | save --force ${config.xdg.cacheHome}/nix-your-shell/init.nu + ''; + + extraConfig = '' + source ${config.xdg.cacheHome}/nix-your-shell/init.nu + ''; + }; + + zsh.initExtra = mkIf cfg.enableZshIntegration '' + ${cfg.package}/bin/nix-your-shell zsh | source /dev/stdin + ''; + }; + }; +} diff --git a/modules/programs/notmuch.nix b/modules/programs/notmuch.nix index a3d679b23..071f08558 100644 --- a/modules/programs/notmuch.nix +++ b/modules/programs/notmuch.nix @@ -37,8 +37,9 @@ let in { name = catAttrs "realName" primary; primary_email = catAttrs "address" primary; - other_email = catAttrs "aliases" primary ++ catAttrs "address" secondaries - ++ catAttrs "aliases" secondaries; + other_email = map (email: email.address or email) (flatten + (catAttrs "aliases" primary ++ catAttrs "address" secondaries + ++ catAttrs "aliases" secondaries)); }; search = { exclude_tags = cfg.search.excludeTags; }; diff --git a/modules/programs/nushell.nix b/modules/programs/nushell.nix index 2ebd9554c..f18f6abff 100644 --- a/modules/programs/nushell.nix +++ b/modules/programs/nushell.nix @@ -1,9 +1,7 @@ { config, lib, pkgs, ... }: - -with lib; - let - + inherit (lib) types; + inherit (lib.hm.nushell) isNushellInline toNushell; cfg = config.programs.nushell; configDir = if pkgs.stdenv.isDarwin && !config.xdg.enable then @@ -14,13 +12,13 @@ let linesOrSource = name: types.submodule ({ config, ... }: { options = { - text = mkOption { + text = lib.mkOption { type = types.lines; default = if config.source != null then builtins.readFile config.source else ""; - defaultText = literalExpression + defaultText = lib.literalExpression "if source is defined, the content of source, otherwise empty"; description = '' Text of the nushell {file}`${name}` file. @@ -28,7 +26,7 @@ let ''; }; - source = mkOption { + source = lib.mkOption { type = types.nullOr types.path; default = null; description = '' @@ -39,38 +37,29 @@ let }; }); in { - meta.maintainers = [ maintainers.Philipp-M ]; - - imports = [ - (mkRemovedOptionModule [ "programs" "nushell" "settings" ] '' - Please use - - 'programs.nushell.configFile' and 'programs.nushell.envFile' - - instead. - '') + meta.maintainers = with lib.maintainers; [ + Philipp-M + joaquintrinanes + aidalgol ]; options.programs.nushell = { - enable = mkEnableOption "nushell"; + enable = lib.mkEnableOption "nushell"; - package = mkOption { - type = types.package; - default = pkgs.nushell; - defaultText = literalExpression "pkgs.nushell"; - description = "The package to use for nushell."; - }; + package = lib.mkPackageOption pkgs "nushell" { nullable = true; }; - configFile = mkOption { + configFile = lib.mkOption { type = types.nullOr (linesOrSource "config.nu"); default = null; - example = literalExpression '' - { text = ''' - let $config = { - filesize_metric: false - table_mode: rounded - use_ls_colors: true + example = lib.literalExpression '' + { + text = ''' + const NU_LIB_DIRS = $NU_LIB_DIRS ++ ''${ + lib.hm.nushell.toNushell (lib.concatStringsSep ":" [ ./scripts ]) } + $env.config.filesize_metric = false + $env.config.table_mode = 'rounded' + $env.config.use_ls_colors = true '''; } ''; @@ -81,7 +70,7 @@ in { ''; }; - envFile = mkOption { + envFile = lib.mkOption { type = types.nullOr (linesOrSource "env.nu"); default = null; example = '' @@ -94,7 +83,7 @@ in { ''; }; - loginFile = mkOption { + loginFile = lib.mkOption { type = types.nullOr (linesOrSource "login.nu"); default = null; example = '' @@ -110,7 +99,7 @@ in { ''; }; - extraConfig = mkOption { + extraConfig = lib.mkOption { type = types.lines; default = ""; description = '' @@ -118,7 +107,7 @@ in { ''; }; - extraEnv = mkOption { + extraEnv = lib.mkOption { type = types.lines; default = ""; description = '' @@ -126,7 +115,7 @@ in { ''; }; - extraLogin = mkOption { + extraLogin = lib.mkOption { type = types.lines; default = ""; description = '' @@ -134,60 +123,153 @@ in { ''; }; - shellAliases = mkOption { + plugins = lib.mkOption { + type = types.listOf types.package; + default = [ ]; + example = lib.literalExpression "[ pkgs.nushellPlugins.formats ]"; + description = '' + A list of nushell plugins to write to the plugin registry file. + ''; + }; + + settings = lib.mkOption { + type = types.attrsOf lib.hm.types.nushellValue; + default = { }; + example = { + show_banner = false; + history.format = "sqlite"; + }; + description = '' + Nushell settings. These will be flattened and assigned one by one to `$env.config` to avoid overwriting the default or existing options. + + For example: + ```nix + { + show_banner = false; + completions.external = { + enable = true; + max_results = 200; + }; + } + ``` + becomes: + ```nushell + $env.config.completions.external.enable = true + $env.config.completions.external.max_results = 200 + $env.config.show_banner = false + ``` + ''; + }; + + shellAliases = lib.mkOption { type = types.attrsOf types.str; default = { }; - example = { ll = "ls -l"; }; + example = { + ll = "ls -l"; + g = "git"; + }; description = '' An attribute set that maps aliases (the top level attribute names in this option) to command strings or directly to build outputs. ''; }; - environmentVariables = mkOption { - type = types.attrsOf types.str; + environmentVariables = lib.mkOption { + type = types.attrsOf lib.hm.types.nushellValue; default = { }; - example = { FOO = "BAR"; }; + example = lib.literalExpression '' + { + FOO = "BAR"; + LIST_VALUE = [ "foo" "bar" ]; + PROMPT_COMMAND = lib.hm.nushell.mkNushellInline '''{|| "> "}'''; + ENV_CONVERSIONS.PATH = { + from_string = lib.hm.nushell.mkNushellInline "{|s| $s | split row (char esep) }"; + to_string = lib.hm.nushell.mkNushellInline "{|v| $v | str join (char esep) }"; + }; + } + ''; description = '' - An attribute set that maps an environment variable to a shell interpreted string. + Environment variables to be set. + + Inline values can be set with `lib.hm.nushell.mkNushellInline`. ''; }; }; - config = mkIf cfg.enable { - home.packages = [ cfg.package ]; + config = lib.mkIf cfg.enable { + warnings = lib.optional (cfg.package == null && cfg.plugins != [ ]) '' + You have configured `plugins` for `nushell` but have not set `package`. - home.file = mkMerge [ + The listed plugins will not be installed. + ''; + + home.packages = lib.mkIf (cfg.package != null) [ cfg.package ]; + + home.file = lib.mkMerge [ (let writeConfig = cfg.configFile != null || cfg.extraConfig != "" - || aliasesStr != ""; + || aliasesStr != "" || cfg.settings != { }; - aliasesStr = concatStringsSep "\n" - (mapAttrsToList (k: v: "alias ${k} = ${v}") cfg.shellAliases); - in mkIf writeConfig { - "${configDir}/config.nu".text = mkMerge [ - (mkIf (cfg.configFile != null) cfg.configFile.text) + aliasesStr = lib.concatLines + (lib.mapAttrsToList (k: v: "alias ${toNushell { } k} = ${v}") + cfg.shellAliases); + in lib.mkIf writeConfig { + "${configDir}/config.nu".text = lib.mkMerge [ + (let + hasEnvVars = cfg.environmentVariables != { }; + envVarsStr = '' + load-env ${toNushell { } cfg.environmentVariables} + ''; + in lib.mkIf hasEnvVars envVarsStr) + (let + flattenSettings = let + joinDot = a: b: "${if a == "" then "" else "${a}."}${b}"; + unravel = prefix: value: + if lib.isAttrs value && !isNushellInline value then + lib.concatMap (key: unravel (joinDot prefix key) value.${key}) + (builtins.attrNames value) + else + [ (lib.nameValuePair prefix value) ]; + in unravel ""; + mkLine = { name, value }: '' + $env.config.${name} = ${toNushell { } value} + ''; + settingsLines = + lib.concatMapStrings mkLine (flattenSettings cfg.settings); + + in lib.mkIf (cfg.settings != { }) settingsLines) + (lib.mkIf (cfg.configFile != null) cfg.configFile.text) cfg.extraConfig aliasesStr ]; }) - (let - envVarsStr = concatStringsSep "\n" - (mapAttrsToList (k: v: "$env.${k} = ${v}") cfg.environmentVariables); - in mkIf (cfg.envFile != null || cfg.extraEnv != "" || envVarsStr != "") { - "${configDir}/env.nu".text = mkMerge [ - (mkIf (cfg.envFile != null) cfg.envFile.text) + (lib.mkIf (cfg.envFile != null || cfg.extraEnv != "") { + "${configDir}/env.nu".text = lib.mkMerge [ + (lib.mkIf (cfg.envFile != null) cfg.envFile.text) cfg.extraEnv - envVarsStr ]; }) - (mkIf (cfg.loginFile != null || cfg.extraLogin != "") { - "${configDir}/login.nu".text = mkMerge [ - (mkIf (cfg.loginFile != null) cfg.loginFile.text) + (lib.mkIf (cfg.loginFile != null || cfg.extraLogin != "") { + "${configDir}/login.nu".text = lib.mkMerge [ + (lib.mkIf (cfg.loginFile != null) cfg.loginFile.text) cfg.extraLogin ]; }) + + (let + msgPackz = pkgs.runCommand "nushellMsgPackz" { } '' + mkdir -p "$out" + ${lib.getExe cfg.package} \ + --plugin-config "$out/plugin.msgpackz" \ + --commands '${ + lib.concatStringsSep "; " + (map (plugin: "plugin add ${lib.getExe plugin}") cfg.plugins) + }' + ''; + in lib.mkIf ((cfg.package != null) && (cfg.plugins != [ ])) { + "${configDir}/plugin.msgpackz".source = "${msgPackz}/plugin.msgpackz"; + }) ]; }; } diff --git a/modules/programs/oh-my-posh.nix b/modules/programs/oh-my-posh.nix index 8c46a1c69..be406e662 100644 --- a/modules/programs/oh-my-posh.nix +++ b/modules/programs/oh-my-posh.nix @@ -47,37 +47,17 @@ in { ''; }; - enableBashIntegration = mkOption { - type = types.bool; - default = true; - description = '' - Whether to enable Bash integration. - ''; - }; + enableBashIntegration = + lib.hm.shell.mkBashIntegrationOption { inherit config; }; - enableZshIntegration = mkOption { - type = types.bool; - default = true; - description = '' - Whether to enable Zsh integration. - ''; - }; + enableFishIntegration = + lib.hm.shell.mkFishIntegrationOption { inherit config; }; - enableFishIntegration = mkOption { - type = types.bool; - default = true; - description = '' - Whether to enable Fish integration. - ''; - }; + enableNushellIntegration = + lib.hm.shell.mkNushellIntegrationOption { inherit config; }; - enableNushellIntegration = mkOption { - type = types.bool; - default = true; - description = '' - Whether to enable Nushell integration. - ''; - }; + enableZshIntegration = + lib.hm.shell.mkZshIntegrationOption { inherit config; }; }; config = mkIf cfg.enable { diff --git a/modules/programs/opam.nix b/modules/programs/opam.nix index 34338514a..6027737cd 100644 --- a/modules/programs/opam.nix +++ b/modules/programs/opam.nix @@ -19,29 +19,14 @@ in { description = "Opam package to install."; }; - enableBashIntegration = mkOption { - default = true; - type = types.bool; - description = '' - Whether to enable Bash integration. - ''; - }; + enableBashIntegration = + lib.hm.shell.mkBashIntegrationOption { inherit config; }; - enableZshIntegration = mkOption { - default = true; - type = types.bool; - description = '' - Whether to enable Zsh integration. - ''; - }; + enableFishIntegration = + lib.hm.shell.mkFishIntegrationOption { inherit config; }; - enableFishIntegration = mkOption { - default = true; - type = types.bool; - description = '' - Whether to enable Fish integration. - ''; - }; + enableZshIntegration = + lib.hm.shell.mkZshIntegrationOption { inherit config; }; }; config = mkIf cfg.enable { diff --git a/modules/programs/openstackclient.nix b/modules/programs/openstackclient.nix index 98d68a2f2..c7ee7d636 100644 --- a/modules/programs/openstackclient.nix +++ b/modules/programs/openstackclient.nix @@ -9,7 +9,7 @@ in { options.programs.openstackclient = { enable = lib.mkEnableOption "OpenStack command-line client"; - package = lib.mkPackageOption pkgs "openstackclient" { }; + package = lib.mkPackageOption pkgs "openstackclient" { nullable = true; }; clouds = lib.mkOption { type = lib.types.submodule { freeformType = yamlFormat.type; }; @@ -58,7 +58,7 @@ in { }; config = lib.mkIf cfg.enable { - home.packages = [ cfg.package ]; + home.packages = lib.mkIf (cfg.package != null) [ cfg.package ]; xdg.configFile."openstack/clouds.yaml".source = yamlFormat.generate "openstackclient-clouds-yaml-${config.home.username}" { diff --git a/modules/programs/papis.nix b/modules/programs/papis.nix index 837bfc274..1b8ae1377 100644 --- a/modules/programs/papis.nix +++ b/modules/programs/papis.nix @@ -19,7 +19,7 @@ in { options.programs.papis = { enable = mkEnableOption "papis"; - package = mkPackageOption pkgs "papis" { }; + package = mkPackageOption pkgs "papis" { nullable = true; }; settings = mkOption { type = with types; attrsOf (oneOf [ bool int str ]); @@ -86,7 +86,7 @@ in { (", namely " + concatStringsSep "," defaultLibraries); }]; - home.packages = [ cfg.package ]; + home.packages = lib.mkIf (cfg.package != null) [ cfg.package ]; xdg.configFile."papis/config" = mkIf (cfg.libraries != { }) { text = generators.toINI { } settingsIni; }; diff --git a/modules/programs/password-store.nix b/modules/programs/password-store.nix index 203eaa349..c57b7a857 100644 --- a/modules/programs/password-store.nix +++ b/modules/programs/password-store.nix @@ -7,7 +7,7 @@ let cfg = config.programs.password-store; in { - meta.maintainers = with maintainers; [ pacien ]; + meta.maintainers = with maintainers; [ euxane ]; options.programs.password-store = { enable = mkEnableOption "Password store"; diff --git a/modules/programs/pay-respects.nix b/modules/programs/pay-respects.nix new file mode 100644 index 000000000..8802ad25e --- /dev/null +++ b/modules/programs/pay-respects.nix @@ -0,0 +1,57 @@ +{ config, lib, pkgs, ... }: +let + inherit (lib) mkEnableOption mkPackageOption getExe optionalString mkIf; + + cfg = config.programs.pay-respects; + payRespectsCmd = getExe cfg.package; +in { + meta.maintainers = [ lib.hm.maintainers.ALameLlama ]; + + options.programs.pay-respects = { + enable = mkEnableOption "pay-respects"; + + package = mkPackageOption pkgs "pay-respects" { }; + + enableBashIntegration = + lib.hm.shell.mkBashIntegrationOption { inherit config; }; + + enableFishIntegration = + lib.hm.shell.mkFishIntegrationOption { inherit config; }; + + enableNushellIntegration = + lib.hm.shell.mkNushellIntegrationOption { inherit config; }; + + enableZshIntegration = + lib.hm.shell.mkZshIntegrationOption { inherit config; }; + }; + + config = mkIf cfg.enable { + home.packages = [ cfg.package ]; + + programs = { + bash.initExtra = '' + ${optionalString cfg.enableBashIntegration '' + eval "$(${payRespectsCmd} bash --alias)" + ''} + ''; + + zsh.initExtra = '' + ${optionalString cfg.enableZshIntegration '' + eval "$(${payRespectsCmd} zsh --alias)" + ''} + ''; + + fish.interactiveShellInit = '' + ${optionalString cfg.enableFishIntegration '' + ${payRespectsCmd} fish --alias | source + ''} + ''; + + nushell.extraConfig = '' + ${optionalString cfg.enableNushellIntegration '' + ${payRespectsCmd} nushell --alias [] + ''} + ''; + }; + }; +} diff --git a/modules/programs/pazi.nix b/modules/programs/pazi.nix index 9e603df23..848dfa309 100644 --- a/modules/programs/pazi.nix +++ b/modules/programs/pazi.nix @@ -12,29 +12,14 @@ in { options.programs.pazi = { enable = mkEnableOption "pazi"; - enableBashIntegration = mkOption { - default = true; - type = types.bool; - description = '' - Whether to enable Bash integration. - ''; - }; + enableBashIntegration = + lib.hm.shell.mkBashIntegrationOption { inherit config; }; - enableZshIntegration = mkOption { - default = true; - type = types.bool; - description = '' - Whether to enable Zsh integration. - ''; - }; + enableFishIntegration = + lib.hm.shell.mkFishIntegrationOption { inherit config; }; - enableFishIntegration = mkOption { - default = true; - type = types.bool; - description = '' - Whether to enable Fish integration. - ''; - }; + enableZshIntegration = + lib.hm.shell.mkZshIntegrationOption { inherit config; }; }; config = mkIf cfg.enable { diff --git a/modules/programs/pls.nix b/modules/programs/pls.nix index b9f509a76..8abb82618 100644 --- a/modules/programs/pls.nix +++ b/modules/programs/pls.nix @@ -9,7 +9,7 @@ let aliases = { ls = "${cfg.package}/bin/pls"; ll = - "${cfg.package}/bin/pls -d perms -d user -d group -d size -d mtime -d git"; + "${cfg.package}/bin/pls -d perm -d user -d group -d size -d mtime -d git"; }; in { diff --git a/modules/programs/poetry.nix b/modules/programs/poetry.nix index d297f0c78..54fa2abb3 100644 --- a/modules/programs/poetry.nix +++ b/modules/programs/poetry.nix @@ -20,6 +20,7 @@ in { enable = mkEnableOption "poetry"; package = mkPackageOption pkgs "poetry" { + nullable = true; example = "pkgs.poetry.withPlugins (ps: with ps; [ poetry-plugin-up ])"; extraDescription = "May be used to install custom poetry plugins."; }; @@ -45,7 +46,7 @@ in { }; config = lib.mkIf cfg.enable { - home.packages = [ cfg.package ]; + home.packages = lib.mkIf (cfg.package != null) [ cfg.package ]; home.file."${configDir}/pypoetry/config.toml" = lib.mkIf (cfg.settings != { }) { diff --git a/modules/programs/pqiv.nix b/modules/programs/pqiv.nix index a99b28de8..27594c4f6 100644 --- a/modules/programs/pqiv.nix +++ b/modules/programs/pqiv.nix @@ -65,7 +65,7 @@ in { home.packages = [ cfg.package ]; xdg.configFile."pqivrc" = - mkIf (cfg.settings != { } && cfg.extraConfig != "") { + mkIf (cfg.settings != { } || cfg.extraConfig != "") { text = lib.concatLines [ (generators.toINI { mkKeyValue = key: value: diff --git a/modules/programs/pyenv.nix b/modules/programs/pyenv.nix index c2273c676..1ff1f2832 100644 --- a/modules/programs/pyenv.nix +++ b/modules/programs/pyenv.nix @@ -19,29 +19,14 @@ in { description = "The package to use for pyenv."; }; - enableBashIntegration = lib.mkOption { - type = lib.types.bool; - default = true; - description = '' - Whether to enable pyenv's Bash integration. - ''; - }; + enableBashIntegration = + lib.hm.shell.mkBashIntegrationOption { inherit config; }; - enableZshIntegration = lib.mkOption { - type = lib.types.bool; - default = true; - description = '' - Whether to enable pyenv's Zsh integration. - ''; - }; + enableFishIntegration = + lib.hm.shell.mkFishIntegrationOption { inherit config; }; - enableFishIntegration = lib.mkOption { - type = lib.types.bool; - default = true; - description = '' - Whether to enable pyenv's Fish integration. - ''; - }; + enableZshIntegration = + lib.hm.shell.mkZshIntegrationOption { inherit config; }; rootDirectory = lib.mkOption { type = lib.types.path; diff --git a/modules/programs/ranger.nix b/modules/programs/ranger.nix index 63d33fad3..378db5f3b 100644 --- a/modules/programs/ranger.nix +++ b/modules/programs/ranger.nix @@ -142,7 +142,7 @@ in { config = mkIf cfg.enable (mkMerge [ { programs.ranger.finalPackage = cfg.package.overrideAttrs (oldAttrs: { - propagatedBuildInputs = oldAttrs.propagatedBuildInputs + propagatedBuildInputs = (oldAttrs.propagatedBuildInputs or [ ]) ++ cfg.extraPackages; }); diff --git a/modules/programs/rbenv.nix b/modules/programs/rbenv.nix index e740c5602..11b48abf4 100644 --- a/modules/programs/rbenv.nix +++ b/modules/programs/rbenv.nix @@ -55,17 +55,14 @@ in { ''; }; - enableBashIntegration = mkEnableOption "Bash integration" // { - default = true; - }; + enableBashIntegration = + lib.hm.shell.mkBashIntegrationOption { inherit config; }; - enableZshIntegration = mkEnableOption "Zsh integration" // { - default = true; - }; + enableFishIntegration = + lib.hm.shell.mkFishIntegrationOption { inherit config; }; - enableFishIntegration = mkEnableOption "Fish integration" // { - default = true; - }; + enableZshIntegration = + lib.hm.shell.mkZshIntegrationOption { inherit config; }; }; config = mkIf cfg.enable { diff --git a/modules/programs/rio.nix b/modules/programs/rio.nix index 5a5ce6fa3..927cb406b 100644 --- a/modules/programs/rio.nix +++ b/modules/programs/rio.nix @@ -12,7 +12,7 @@ in { ''; }; - package = lib.mkPackageOption pkgs "rio" { }; + package = lib.mkPackageOption pkgs "rio" { nullable = true; }; settings = lib.mkOption { type = settingsFormat.type; @@ -27,7 +27,7 @@ in { config = lib.mkIf cfg.enable (lib.mkMerge [ { - home.packages = [ cfg.package ]; + home.packages = lib.mkIf (cfg.package != null) [ cfg.package ]; } # Only manage configuration if not empty diff --git a/modules/programs/ripgrep.nix b/modules/programs/ripgrep.nix index cbd73bd15..3154a770d 100644 --- a/modules/programs/ripgrep.nix +++ b/modules/programs/ripgrep.nix @@ -2,17 +2,16 @@ with lib; -let - cfg = config.programs.ripgrep; - configPath = "${config.xdg.configHome}/ripgrep/ripgreprc"; +let cfg = config.programs.ripgrep; in { - meta.maintainers = [ hm.maintainers.pedorich-n ]; + meta.maintainers = + [ lib.maintainers.khaneliman lib.hm.maintainers.pedorich-n ]; options = { programs.ripgrep = { enable = mkEnableOption "Ripgrep"; - package = mkPackageOption pkgs "ripgrep" { }; + package = mkPackageOption pkgs "ripgrep" { nullable = true; }; arguments = mkOption { type = with types; listOf str; @@ -30,8 +29,9 @@ in { }; config = mkIf cfg.enable { - home = mkMerge [ - { packages = [ cfg.package ]; } + home = let configPath = "${config.xdg.configHome}/ripgrep/ripgreprc"; + in mkMerge [ + { packages = lib.mkIf (cfg.package != null) [ cfg.package ]; } (mkIf (cfg.arguments != [ ]) { file."${configPath}".text = lib.concatLines cfg.arguments; diff --git a/modules/programs/rofi-pass.nix b/modules/programs/rofi-pass.nix index f1de580fb..d5208d504 100644 --- a/modules/programs/rofi-pass.nix +++ b/modules/programs/rofi-pass.nix @@ -12,8 +12,10 @@ in { options.programs.rofi.pass = { enable = mkEnableOption "rofi integration with password-store"; - package = - mkPackageOption pkgs "rofi-pass" { example = "pkgs.rofi-pass-wayland"; }; + package = mkPackageOption pkgs "rofi-pass" { + nullable = true; + example = "pkgs.rofi-pass-wayland"; + }; stores = mkOption { type = types.listOf types.str; @@ -40,7 +42,7 @@ in { }; config = mkIf cfg.enable { - home.packages = [ cfg.package ]; + home.packages = lib.mkIf (cfg.package != null) [ cfg.package ]; xdg.configFile."rofi-pass/config".text = optionalString (cfg.stores != [ ]) ("root=" + (concatStringsSep ":" cfg.stores) + "\n") + cfg.extraConfig diff --git a/modules/programs/ruff.nix b/modules/programs/ruff.nix index e1490089a..4ae80ebda 100644 --- a/modules/programs/ruff.nix +++ b/modules/programs/ruff.nix @@ -15,7 +15,7 @@ in { enable = mkEnableOption "ruff, an extremely fast Python linter and code formatter, written in Rust"; - package = mkPackageOption pkgs "ruff" { }; + package = mkPackageOption pkgs "ruff" { nullable = true; }; settings = mkOption { type = settingsFormat.type; @@ -37,7 +37,7 @@ in { }; config = mkIf cfg.enable { - home.packages = [ cfg.package ]; + home.packages = lib.mkIf (cfg.package != null) [ cfg.package ]; xdg.configFile."ruff/ruff.toml".source = settingsFormat.generate "ruff.toml" cfg.settings; diff --git a/modules/programs/sagemath.nix b/modules/programs/sagemath.nix index 70efaca56..7d34adc49 100644 --- a/modules/programs/sagemath.nix +++ b/modules/programs/sagemath.nix @@ -12,11 +12,11 @@ in { options.programs.sagemath = { enable = mkEnableOption "SageMath, a mathematics software system"; - package = mkOption { - type = types.package; - default = pkgs.sage; - defaultText = literalExpression "pkgs.sage"; - description = "The SageMath package to use."; + package = lib.mkPackageOption pkgs "sage" { + nullable = true; + extraDescription = '' + The SageMath package to use. + ''; }; configDir = mkOption { @@ -52,9 +52,10 @@ in { }; config = lib.mkIf cfg.enable { - home.packages = [ cfg.package ]; + home.packages = lib.mkIf (cfg.package != null) [ cfg.package ]; home.file."${cfg.configDir}/init.sage".text = cfg.initScript; + home.sessionVariables = { DOT_SAGE = cfg.dataDir; SAGE_STARTUP_FILE = "${cfg.configDir}/init.sage"; diff --git a/modules/programs/sapling.nix b/modules/programs/sapling.nix index d2a4b4319..4e27aaa82 100644 --- a/modules/programs/sapling.nix +++ b/modules/programs/sapling.nix @@ -15,7 +15,7 @@ in { programs.sapling = { enable = mkEnableOption "Sapling"; - package = mkPackageOption pkgs "sapling" { }; + package = mkPackageOption pkgs "sapling" { nullable = true; }; userName = mkOption { type = types.str; @@ -48,7 +48,7 @@ in { config = mkIf cfg.enable (mkMerge [ { - home.packages = [ cfg.package ]; + home.packages = lib.mkIf (cfg.package != null) [ cfg.package ]; programs.sapling.iniContent.ui = { username = cfg.userName + " <" + cfg.userEmail + ">"; diff --git a/modules/programs/sbt.nix b/modules/programs/sbt.nix index de14bc6f3..622768298 100644 --- a/modules/programs/sbt.nix +++ b/modules/programs/sbt.nix @@ -130,6 +130,20 @@ in { ''; }; + pluginsExtra = mkOption { + type = types.listOf (types.str); + default = [ ]; + example = literalExpression '' + [ + "addDependencyTreePlugin" + ] + ''; + description = '' + A list of extra commands to put in plugins conf file. + Use it in last resort when you can't use the `plugins` option. + ''; + }; + credentials = mkOption { type = types.listOf (sbtTypes.credential); default = [ ]; @@ -183,9 +197,10 @@ in { config = mkIf cfg.enable (mkMerge [ { home.packages = [ cfg.package ]; } - (mkIf (cfg.plugins != [ ]) { + (mkIf (cfg.plugins != [ ] || cfg.pluginsExtra != [ ]) { home.file."${cfg.baseUserConfigPath}/1.0/plugins/plugins.sbt".text = - concatStrings (map renderPlugin cfg.plugins); + concatStrings (map renderPlugin cfg.plugins) + + concatStringsSep "\n" cfg.pluginsExtra + "\n"; }) (mkIf (cfg.credentials != [ ]) { diff --git a/modules/programs/scmpuff.nix b/modules/programs/scmpuff.nix index a85ae8d9c..f9ff922a9 100644 --- a/modules/programs/scmpuff.nix +++ b/modules/programs/scmpuff.nix @@ -16,29 +16,14 @@ in { description = "Package providing the {command}`scmpuff` tool."; }; - enableBashIntegration = mkOption { - default = true; - type = types.bool; - description = '' - Whether to enable Bash integration. - ''; - }; + enableBashIntegration = + lib.hm.shell.mkBashIntegrationOption { inherit config; }; - enableZshIntegration = mkOption { - default = true; - type = types.bool; - description = '' - Whether to enable Zsh integration. - ''; - }; + enableFishIntegration = + lib.hm.shell.mkFishIntegrationOption { inherit config; }; - enableFishIntegration = mkOption { - default = true; - type = types.bool; - description = '' - Whether to enable fish integration. - ''; - }; + enableZshIntegration = + lib.hm.shell.mkZshIntegrationOption { inherit config; }; enableAliases = mkOption { default = true; diff --git a/modules/programs/sftpman.nix b/modules/programs/sftpman.nix index c6978f80a..3a8ba5ee6 100644 --- a/modules/programs/sftpman.nix +++ b/modules/programs/sftpman.nix @@ -73,7 +73,7 @@ in { enable = mkEnableOption "sftpman, an application that handles sshfs/sftp file systems mounting"; - package = mkPackageOption pkgs "sftpman" { }; + package = mkPackageOption pkgs "sftpman" { nullable = true; }; defaultSshKey = mkOption { type = types.nullOr types.str; @@ -107,7 +107,7 @@ in { }) ]; - home.packages = [ cfg.package ]; + home.packages = lib.mkIf (cfg.package != null) [ cfg.package ]; xdg.configFile = mapAttrs' (name: value: nameValuePair "sftpman/mounts/${name}.json" { diff --git a/modules/programs/skim.nix b/modules/programs/skim.nix index 2bb17d1b9..0f47a00bf 100644 --- a/modules/programs/skim.nix +++ b/modules/programs/skim.nix @@ -83,29 +83,14 @@ in { ''; }; - enableBashIntegration = mkOption { - default = true; - type = types.bool; - description = '' - Whether to enable Bash integration. - ''; - }; + enableBashIntegration = + lib.hm.shell.mkBashIntegrationOption { inherit config; }; - enableZshIntegration = mkOption { - default = true; - type = types.bool; - description = '' - Whether to enable Zsh integration. - ''; - }; + enableFishIntegration = + lib.hm.shell.mkFishIntegrationOption { inherit config; }; - enableFishIntegration = mkOption { - default = true; - type = types.bool; - description = '' - Whether to enable Fish integration. - ''; - }; + enableZshIntegration = + lib.hm.shell.mkZshIntegrationOption { inherit config; }; }; config = mkIf cfg.enable { diff --git a/modules/programs/sm64ex.nix b/modules/programs/sm64ex.nix index 23b75808f..a005484c2 100644 --- a/modules/programs/sm64ex.nix +++ b/modules/programs/sm64ex.nix @@ -34,11 +34,7 @@ in { options.programs.sm64ex = { enable = mkEnableOption "sm64ex"; - package = mkOption { - type = types.package; - default = pkgs.sm64ex; - description = "The sm64ex package to use."; - }; + package = lib.mkPackageOption pkgs "sm64ex" { nullable = true; }; region = mkOption { type = types.nullOr (types.enum [ "us" "eu" "jp" ]); @@ -120,7 +116,7 @@ in { configFile = optionals (cfg.settings != null) (concatStringsSep "\n" ((mapAttrsToList mkConfig cfg.settings))); in mkIf cfg.enable { - home.packages = [ package ]; + home.packages = lib.mkIf (cfg.package != null) [ cfg.package ]; xdg.dataFile."sm64pc/sm64config.txt" = mkIf (cfg.settings != null) { text = configFile; }; diff --git a/modules/programs/spotify-player.nix b/modules/programs/spotify-player.nix index 83eefe12d..bc401fda6 100644 --- a/modules/programs/spotify-player.nix +++ b/modules/programs/spotify-player.nix @@ -1,22 +1,22 @@ { config, lib, pkgs, ... }: let - inherit (lib) - mkEnableOption mkPackageOption mkOption types literalExpression mkIf; + inherit (lib) mkEnableOption mkPackageOption mkOption literalExpression mkIf; + inherit (lib.types) listOf; cfg = config.programs.spotify-player; tomlFormat = pkgs.formats.toml { }; - + tomlType = tomlFormat.type; in { meta.maintainers = with lib.hm.maintainers; [ diniamo ]; options.programs.spotify-player = { enable = mkEnableOption "spotify-player"; - package = mkPackageOption pkgs "spotify-player" { }; + package = mkPackageOption pkgs "spotify-player" { nullable = true; }; settings = mkOption { - type = tomlFormat.type; + type = tomlType; default = { }; example = literalExpression '' { @@ -43,7 +43,7 @@ in { }; themes = mkOption { - type = types.listOf tomlFormat.type; + type = listOf tomlType; default = [ ]; example = literalExpression '' [ @@ -94,7 +94,7 @@ in { }; keymaps = mkOption { - type = types.listOf tomlFormat.type; + type = listOf tomlType; default = [ ]; example = literalExpression '' [ @@ -129,10 +129,40 @@ in { for the full list of options. ''; }; + + actions = mkOption { + type = listOf tomlType; + default = [ ]; + example = literalExpression '' + [ + { + action = "GoToArtist"; + key_sequence = "g A"; + } + { + action = "GoToAlbum"; + key_sequence = "g B"; + target = "PlayingTrack"; + } + { + action = "ToggleLiked"; + key_sequence = "C-l"; + } + ] + ''; + description = '' + Configuration written to the `actions` field of + {file}`$XDG_CONFIG_HOME/spotify-player/keymap.toml`. + + See + + for the full list of options. + ''; + }; }; config = mkIf cfg.enable { - home.packages = [ cfg.package ]; + home.packages = lib.mkIf (cfg.package != null) [ cfg.package ]; xdg.configFile = { "spotify-player/app.toml" = mkIf (cfg.settings != { }) { @@ -146,7 +176,7 @@ in { "spotify-player/keymap.toml" = mkIf (cfg.keymaps != [ ]) { source = tomlFormat.generate "spotify-player-keymap" { - inherit (cfg) keymaps; + inherit (cfg) keymaps actions; }; }; }; diff --git a/modules/programs/starship.nix b/modules/programs/starship.nix index 9ccff7fcf..bb1c87b9c 100644 --- a/modules/programs/starship.nix +++ b/modules/programs/starship.nix @@ -10,6 +10,8 @@ let starshipCmd = "${config.home.profileDirectory}/bin/starship"; + initFish = + if cfg.enableInteractive then "interactiveShellInit" else "shellInitLast"; in { meta.maintainers = [ ]; @@ -51,24 +53,30 @@ in { ''; }; - enableBashIntegration = mkEnableOption "Bash integration" // { - default = true; - }; + enableBashIntegration = + lib.hm.shell.mkBashIntegrationOption { inherit config; }; - enableZshIntegration = mkEnableOption "Zsh integration" // { - default = true; - }; + enableFishIntegration = + lib.hm.shell.mkFishIntegrationOption { inherit config; }; - enableFishIntegration = mkEnableOption "Fish integration" // { - default = true; - }; + enableIonIntegration = + lib.hm.shell.mkIonIntegrationOption { inherit config; }; - enableIonIntegration = mkEnableOption "Ion integration" // { - default = true; - }; + enableNushellIntegration = + lib.hm.shell.mkNushellIntegrationOption { inherit config; }; - enableNushellIntegration = mkEnableOption "Nushell integration" // { + enableZshIntegration = + lib.hm.shell.mkZshIntegrationOption { inherit config; }; + + enableInteractive = mkOption { + type = types.bool; default = true; + description = '' + Only enable starship when the shell is interactive. This option is only + valid for the Fish shell. + + Some plugins require this to be set to `false` to function correctly. + ''; }; enableTransience = mkOption { @@ -104,9 +112,9 @@ in { fi ''; - programs.fish.interactiveShellInit = mkIf cfg.enableFishIntegration '' + programs.fish.${initFish} = mkIf cfg.enableFishIntegration '' if test "$TERM" != "dumb" - eval (${starshipCmd} init fish) + ${starshipCmd} init fish | source ${lib.optionalString cfg.enableTransience "enable_transience"} end ''; diff --git a/modules/programs/swayimg.nix b/modules/programs/swayimg.nix new file mode 100644 index 000000000..aac56ece3 --- /dev/null +++ b/modules/programs/swayimg.nix @@ -0,0 +1,53 @@ +{ config, lib, pkgs, ... }: + +let + cfg = config.programs.swayimg; + iniFormat = pkgs.formats.ini { }; +in { + meta.maintainers = with lib.maintainers; [ dod-101 ]; + + options.programs.swayimg = { + enable = lib.mkEnableOption "swayimg"; + package = lib.mkOption { + type = lib.types.package; + default = pkgs.swayimg; + defaultText = lib.literalExpression "pkgs.swayimg"; + description = "The swayimg package to install"; + }; + settings = lib.mkOption { + type = iniFormat.type; + default = { }; + description = '' + Configuration written to + {file}`$XDG_CONFIG_HOME/swayimg/config`. See for a list of available options. + ''; + example = lib.literalExpression '' + { + viewer = { + window = "#10000010"; + scale = "fill"; + }; + "info.viewer" = { + top_left = "+name,+format"; + }; + "keys.viewer" = { + "Shift+r" = "rand_file"; + }; + } + ''; + }; + }; + + config = lib.mkIf cfg.enable { + assertions = [ + (lib.hm.assertions.assertPlatform "programs.swayimg" pkgs + lib.platforms.linux) + ]; + + home.packages = [ cfg.package ]; + + xdg.configFile."swayimg/config" = lib.mkIf (cfg.settings != { }) { + source = iniFormat.generate "config" cfg.settings; + }; + }; +} diff --git a/modules/programs/swaylock.nix b/modules/programs/swaylock.nix index be577ea80..dcfd30c7e 100644 --- a/modules/programs/swaylock.nix +++ b/modules/programs/swaylock.nix @@ -33,10 +33,10 @@ in { ''; }; - package = mkPackageOption pkgs "swaylock" { }; + package = mkPackageOption pkgs "swaylock" { nullable = true; }; settings = mkOption { - type = with types; attrsOf (oneOf [ bool float int str ]); + type = with types; attrsOf (oneOf [ bool float int path str ]); default = { }; description = '' Default arguments to {command}`swaylock`. An empty set @@ -59,7 +59,7 @@ in { lib.platforms.linux) ]; - home.packages = [ cfg.package ]; + home.packages = lib.mkIf (cfg.package != null) [ cfg.package ]; xdg.configFile."swaylock/config" = mkIf (cfg.settings != { }) { text = concatStrings (mapAttrsToList (n: v: diff --git a/modules/programs/swayr.nix b/modules/programs/swayr.nix index 250a3e01f..c45ed0634 100644 --- a/modules/programs/swayr.nix +++ b/modules/programs/swayr.nix @@ -6,8 +6,10 @@ let cfg = config.programs.swayr; tomlFormat = pkgs.formats.toml { }; configFile = tomlFormat.generate "config.toml" cfg.settings; - finalConfig = pkgs.writeText "swayr.toml" - ((builtins.readFile configFile) + cfg.extraConfig); + extraConfigFile = pkgs.writeText "extra-config.toml" cfg.extraConfig; + finalConfig = pkgs.runCommand "swayr.toml" { } '' + cat ${configFile} ${extraConfigFile} > $out + ''; in { meta.maintainers = [ lib.hm.maintainers."9p4" ]; diff --git a/modules/programs/taskwarrior.nix b/modules/programs/taskwarrior.nix index 9b5af43ee..8efeb1366 100644 --- a/modules/programs/taskwarrior.nix +++ b/modules/programs/taskwarrior.nix @@ -23,9 +23,6 @@ let formatPair = key: value: if isAttrs value then formatSet key value else formatLine key value; - - homeConf = "${config.xdg.configHome}/task/home-manager-taskrc"; - userConf = "${config.xdg.configHome}/task/taskrc"; in { options = { programs.taskwarrior = { @@ -85,13 +82,18 @@ in { ''; }; - package = - mkPackageOption pkgs "taskwarrior" { example = "pkgs.taskwarrior3"; }; + package = mkPackageOption pkgs "taskwarrior" { + nullable = true; + example = "pkgs.taskwarrior3"; + }; }; }; - config = mkIf cfg.enable { - home.packages = [ cfg.package ]; + config = let + homeConf = "${config.xdg.configHome}/task/home-manager-taskrc"; + userConf = "${config.xdg.configHome}/task/taskrc"; + in mkIf cfg.enable { + home.packages = lib.mkIf (cfg.package != null) [ cfg.package ]; home.file."${homeConf}".text = '' data.location=${cfg.dataLocation} diff --git a/modules/programs/tealdeer.nix b/modules/programs/tealdeer.nix index d9318d102..6efc5aa3a 100644 --- a/modules/programs/tealdeer.nix +++ b/modules/programs/tealdeer.nix @@ -77,9 +77,14 @@ in { Configuration written to {file}`$XDG_CONFIG_HOME/tealdeer/config.toml` on Linux or {file}`$HOME/Library/Application Support/tealdeer/config.toml` on Darwin. - See for more information. + See for more information. ''; }; + + enableAutoUpdates = mkEnableOption "Auto updates" // { + default = true; + example = false; + }; }; config = mkIf cfg.enable { @@ -89,5 +94,10 @@ in { mkIf (cfg.settings != null && cfg.settings != { }) { source = tomlFormat.generate "tealdeer-config" cfg.settings; }; + + services.tldr-update = mkIf cfg.enableAutoUpdates { + enable = true; + package = pkgs.tealdeer; + }; }; } diff --git a/modules/programs/thefuck.nix b/modules/programs/thefuck.nix index ab56ea016..79b1f9462 100644 --- a/modules/programs/thefuck.nix +++ b/modules/programs/thefuck.nix @@ -13,33 +13,17 @@ with lib; enableInstantMode = mkEnableOption "thefuck's experimental instant mode"; - enableBashIntegration = mkOption { - default = true; - type = types.bool; - description = '' - Whether to enable Bash integration. - ''; - }; + enableBashIntegration = + lib.hm.shell.mkBashIntegrationOption { inherit config; }; - enableFishIntegration = mkEnableOption "Fish integration" // { - default = true; - }; + enableFishIntegration = + lib.hm.shell.mkFishIntegrationOption { inherit config; }; - enableZshIntegration = mkOption { - default = true; - type = types.bool; - description = '' - Whether to enable Zsh integration. - ''; - }; + enableNushellIntegration = + lib.hm.shell.mkNushellIntegrationOption { inherit config; }; - enableNushellIntegration = mkOption { - default = true; - type = types.bool; - description = '' - Whether to enable Nushell integration. - ''; - }; + enableZshIntegration = + lib.hm.shell.mkZshIntegrationOption { inherit config; }; }; config = let diff --git a/modules/programs/thunderbird.nix b/modules/programs/thunderbird.nix index 2001e806f..48587c308 100644 --- a/modules/programs/thunderbird.nix +++ b/modules/programs/thunderbird.nix @@ -12,6 +12,11 @@ let "Thunderbird preference (int, bool, string, and also attrs, list, float as a JSON string)"; }; + # The extensions path shared by all profiles. + extensionPath = "extensions/{ec8030f7-c20a-464f-9b0e-13a3a9e97384}"; + + moduleName = "programs.thunderbird"; + enabledAccounts = attrValues (filterAttrs (_: a: a.thunderbird.enable) config.accounts.email.accounts); @@ -32,7 +37,8 @@ let profilesIni = foldl recursiveUpdate { General = { StartWithLastProfile = 1; - Version = 2; + } // lib.optionalAttrs (cfg.profileVersion != null) { + Version = cfg.profileVersion; }; } (flip map profilesWithId (profile: { "Profile${profile.id}" = { @@ -43,16 +49,25 @@ let }; })); + getId = account: address: + if address == account.address then + account.id + else + (builtins.hashString "sha256" (if (builtins.isString address) then + address + else + (address.address + address.realName))); + toThunderbirdIdentity = account: address: # For backwards compatibility, the primary address reuses the account ID. let - id = if address == account.address then - account.id - else - builtins.hashString "sha256" address; + id = getId account address; + addressIsString = builtins.isString address; in { - "mail.identity.id_${id}.fullName" = account.realName; - "mail.identity.id_${id}.useremail" = address; + "mail.identity.id_${id}.fullName" = + if addressIsString then account.realName else address.realName; + "mail.identity.id_${id}.useremail" = + if addressIsString then address else address.address; "mail.identity.id_${id}.valid" = true; "mail.identity.id_${id}.htmlSigText" = if account.signature.showSignature == "none" then @@ -71,6 +86,8 @@ let "mail.identity.id_${id}.openpgp_key_id" = account.gpg.key; "mail.identity.id_${id}.protectSubject" = true; "mail.identity.id_${id}.sign_mail" = account.gpg.signByDefault; + } // optionalAttrs (account.smtp != null) { + "mail.identity.id_${id}.smtpServer" = "smtp_${account.id}"; } // account.thunderbird.perIdentitySettings id; toThunderbirdAccount = account: profile: @@ -79,9 +96,7 @@ let addresses = [ account.address ] ++ account.aliases; in { "mail.account.account_${id}.identities" = concatStringsSep "," - ([ "id_${id}" ] - ++ map (address: "id_${builtins.hashString "sha256" address}") - account.aliases); + (map (address: "id_${getId account address}") addresses); "mail.account.account_${id}.server" = "server_${id}"; } // optionalAttrs account.primary { "mail.accountmanager.defaultaccount" = "account_${id}"; @@ -103,7 +118,6 @@ let "mail.server.server_${id}.type" = "imap"; "mail.server.server_${id}.userName" = account.userName; } // optionalAttrs (account.smtp != null) { - "mail.identity.id_${id}.smtpServer" = "smtp_${id}"; "mail.smtpserver.smtp_${id}.authMethod" = 3; "mail.smtpserver.smtp_${id}.hostname" = account.smtp.host; "mail.smtpserver.smtp_${id}.port" = @@ -121,6 +135,18 @@ let (builtins.map (address: toThunderbirdIdentity account address) addresses) // account.thunderbird.settings id; + toThunderbirdFeed = feed: profile: + let id = feed.id; + in { + "mail.account.account_${id}.server" = "server_${id}"; + "mail.server.server_${id}.name" = feed.name; + "mail.server.server_${id}.type" = "rss"; + "mail.server.server_${id}.directory" = + "${thunderbirdProfilesPath}/${profile.name}/Mail/Feeds-${id}"; + "mail.server.server_${id}.directory-rel" = "[ProfD]Mail/Feeds-${id}"; + "mail.server.server_${id}.hostname" = "Feeds-${id}"; + }; + mkUserJs = prefs: extraPrefs: '' // Generated by Home Manager. @@ -144,6 +170,23 @@ in { description = "The Thunderbird package to use."; }; + profileVersion = mkOption { + internal = true; + type = types.nullOr types.ints.unsigned; + default = if isDarwin then null else 2; + description = "profile version, set null for nix-darwin"; + }; + + nativeMessagingHosts = mkOption { + visible = true; + type = types.listOf types.package; + default = [ ]; + description = '' + Additional packages containing native messaging hosts that should be + made available to Thunderbird extensions. + ''; + }; + profiles = mkOption { type = with types; attrsOf (submodule ({ config, name, ... }: { @@ -165,6 +208,25 @@ in { ''; }; + feedAccounts = mkOption { + type = types.attrsOf (submodule ({ config, name, ... }: { + options = { + name = mkOption { + type = types.str; + default = name; + readOnly = true; + description = "This feed account's name."; + }; + }; + })); + default = { }; + description = '' + Attribute set of feed accounts. Feeds themselves have to be + managed through Thunderbird's settings. This option allows + feeds to coexist with declaratively managed email accounts. + ''; + }; + settings = mkOption { type = thunderbirdJson; default = { }; @@ -225,6 +287,42 @@ in { Extra preferences to add to {file}`user.js`. ''; }; + + search = mkOption { + type = types.submodule (args: + import ./firefox/profiles/search.nix { + inherit (args) config; + inherit lib pkgs; + appName = "Thunderbird"; + package = cfg.package; + modulePath = + [ "programs" "thunderbird" "profiles" name "search" ]; + profilePath = name; + }); + default = { }; + description = "Declarative search engine configuration."; + }; + + extensions = mkOption { + type = types.listOf types.package; + default = [ ]; + example = literalExpression '' + [ + pkgs.some-thunderbird-extension + ] + ''; + description = '' + List of ${name} add-on packages to install for this profile. + + Note that it is necessary to manually enable extensions + inside ${name} after the first installation. + + To automatically enable extensions add + `"extensions.autoDisableScopes" = 0;` + to + [{option}`${moduleName}.profiles..settings`](#opt-${moduleName}.profiles._name_.settings) + ''; + }; }; })); description = "Attribute set of Thunderbird profiles."; @@ -260,7 +358,17 @@ in { accounts.email.accounts = mkOption { type = with types; - attrsOf (submodule { + attrsOf (submodule ({ config, ... }: { + config.thunderbird = { + settings = lib.mkIf (config.flavor == "gmail.com") (id: { + "mail.server.server_${id}.authMethod" = + mkOptionDefault 10; # 10 = OAuth2 + "mail.server.server_${id}.socketType" = + mkOptionDefault 3; # SSL/TLS + "mail.server.server_${id}.is_gmail" = + mkOptionDefault true; # handle labels, trash, etc + }); + }; options.thunderbird = { enable = mkEnableOption "the Thunderbird mail client for this account"; @@ -311,7 +419,7 @@ in { ''; }; }; - }); + })); }; }; @@ -344,19 +452,16 @@ in { this module to manage your accounts and profiles by setting 'programs.thunderbird.package' to a dummy value, for example using 'pkgs.runCommand'. - - Note that this module requires you to set the following environment - variables when using an installation of Thunderbird that is not provided - by Nix: - - export MOZ_LEGACY_PROFILES=1 - export MOZ_ALLOW_DOWNGRADE=1 ''; home.packages = [ cfg.package ] ++ optional (any (p: p.withExternalGnupg) (attrValues cfg.profiles)) pkgs.gpgme; + mozilla.thunderbirdNativeMessagingHosts = [ + cfg.package # package configured native messaging hosts (entire mail app actually) + ] ++ cfg.nativeMessagingHosts; # user configured native messaging hosts + home.file = mkMerge ([{ "${thunderbirdConfigPath}/profiles.ini" = mkIf (cfg.profiles != { }) { text = generators.toINI { } profilesIni; }; @@ -368,11 +473,17 @@ in { mkIf (profile.userContent != "") { text = profile.userContent; }; "${thunderbirdProfilesPath}/${name}/user.js" = let - accounts = filter (a: + emailAccounts = filter (a: a.thunderbird.profiles == [ ] || any (p: p == name) a.thunderbird.profiles) enabledAccountsWithId; - smtp = filter (a: a.smtp != null) accounts; + smtp = filter (a: a.smtp != null) emailAccounts; + + feedAccounts = + map (f: f // { id = builtins.hashString "sha256" f.name; }) + (attrValues profile.feedAccounts); + + accounts = emailAccounts ++ feedAccounts; in { text = mkUserJs (builtins.foldl' (a: b: a // b) { } ([ cfg.settings @@ -390,9 +501,29 @@ in { { "mail.openpgp.allow_external_gnupg" = profile.withExternalGnupg; } profile.settings - ] ++ (map (a: toThunderbirdAccount a profile) accounts))) + ] ++ (map (a: toThunderbirdAccount a profile) emailAccounts) + ++ (map (f: toThunderbirdFeed f profile) feedAccounts))) profile.extraConfig; }; + + "${thunderbirdProfilesPath}/${name}/search.json.mozlz4" = + mkIf (profile.search.enable) { + enable = profile.search.enable; + force = profile.search.force; + source = profile.search.file; + }; + + "${thunderbirdProfilesPath}/${name}/extensions" = + mkIf (profile.extensions != [ ]) { + source = let + extensionsEnvPkg = pkgs.buildEnv { + name = "hm-thunderbird-extensions"; + paths = profile.extensions; + }; + in "${extensionsEnvPkg}/share/mozilla/${extensionPath}"; + recursive = true; + force = true; + }; })); }; } diff --git a/modules/programs/tmux.nix b/modules/programs/tmux.nix index b68fd8d5e..ff3a3322f 100644 --- a/modules/programs/tmux.nix +++ b/modules/programs/tmux.nix @@ -95,6 +95,7 @@ let ''} set -g mouse ${boolToStr cfg.mouse} + set -g focus-events ${boolToStr cfg.focusEvents} setw -g aggressive-resize ${boolToStr cfg.aggressiveResize} setw -g clock-mode-style ${if cfg.clock24 then "24" else "12"} set -s escape-time ${toString cfg.escapeTime} @@ -191,6 +192,15 @@ in { ''; }; + focusEvents = mkOption { + default = false; + type = types.bool; + description = '' + On supported terminals, request focus events and pass them through to + applications running in tmux. + ''; + }; + historyLimit = mkOption { default = 2000; example = 5000; @@ -239,7 +249,7 @@ in { sensibleOnTop = mkOption { type = types.bool; - default = true; + default = false; description = '' Run the sensible plugin at the top of the configuration. It is possible to override the sensible settings using the @@ -274,7 +284,7 @@ in { shell = mkOption { default = defaultShell; - example = "\${pkgs.zsh}/bin/zsh"; + example = literalExpression "${pkgs.zsh}/bin/zsh"; type = with types; nullOr str; description = "Set the default-shell tmux variable."; }; diff --git a/modules/programs/todoman.nix b/modules/programs/todoman.nix new file mode 100644 index 000000000..2e7ebf6a2 --- /dev/null +++ b/modules/programs/todoman.nix @@ -0,0 +1,62 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + cfg = config.programs.todoman; + + format = pkgs.formats.keyValue { }; + +in { + + meta.maintainers = [ hm.maintainers.mikilio ]; + + options.programs.todoman = { + enable = lib.mkEnableOption "todoman"; + + glob = mkOption { + type = types.str; + default = "*"; + description = '' + The glob expansion which matches all directories relevant. + ''; + example = "*/*"; + }; + + extraConfig = mkOption { + type = types.lines; + default = ""; + description = '' + Text for configuration of todoman. + The syntax is Python. + + See [docs](`https://todoman.readthedocs.io/en/stable/man.html#id5`). + for the full list of options. + ''; + example = '' + date_format = "%Y-%m-%d"; + time_format = "%H:%M"; + default_list = "Personal"; + default_due = 48; + ''; + }; + }; + + config = mkIf cfg.enable { + assertions = [{ + assertion = config.accounts.calendar ? basePath; + message = '' + A base directory for calendars must be specified via + `accounts.calendar.basePath` to generate config for todoman + ''; + }]; + + home.packages = [ pkgs.todoman ]; + + xdg.configFile."todoman/config.py".text = lib.concatLines [ + ''path = "${config.accounts.calendar.basePath}/${cfg.glob}"'' + cfg.extraConfig + ]; + }; +} diff --git a/modules/programs/tofi.nix b/modules/programs/tofi.nix index acc1a994d..b6e46a6cb 100644 --- a/modules/programs/tofi.nix +++ b/modules/programs/tofi.nix @@ -12,7 +12,7 @@ in { options.programs.tofi = { enable = mkEnableOption "Tofi, a tiny dynamic menu for Wayland"; - package = mkPackageOption pkgs "tofi" { }; + package = mkPackageOption pkgs "tofi" { nullable = true; }; settings = mkOption { type = with types; @@ -46,7 +46,7 @@ in { assertions = [ (hm.assertions.assertPlatform "programs.tofi" pkgs platforms.linux) ]; - home.packages = [ cfg.package ]; + home.packages = lib.mkIf (cfg.package != null) [ cfg.package ]; xdg.configFile."tofi/config" = mkIf (cfg.settings != { }) { text = let diff --git a/modules/programs/vifm.nix b/modules/programs/vifm.nix new file mode 100644 index 000000000..aef2c1f16 --- /dev/null +++ b/modules/programs/vifm.nix @@ -0,0 +1,33 @@ +{ config, lib, pkgs, ... }: + +let + + inherit (lib) mkIf mkOption types; + + cfg = config.programs.vifm; + +in { + meta.maintainers = [ lib.hm.maintainers.aabccd021 ]; + + options.programs.vifm = { + enable = lib.mkEnableOption "vifm, a Vim-like file manager"; + + package = lib.mkPackageOption pkgs "vifm" { nullable = true; }; + + extraConfig = mkOption { + type = types.lines; + default = ""; + example = "mark h ~/"; + description = '' + Extra lines added to the {file}`$XDG_CONFIG_HOME/vifm/vifmrc` file. + ''; + }; + }; + + config = mkIf cfg.enable { + home.packages = lib.mkIf (cfg.package != null) [ cfg.package ]; + + xdg.configFile."vifm/vifmrc" = + mkIf (cfg.extraConfig != "") { text = cfg.extraConfig; }; + }; +} diff --git a/modules/programs/vim-vint.nix b/modules/programs/vim-vint.nix index 9565a8cb3..655c00937 100644 --- a/modules/programs/vim-vint.nix +++ b/modules/programs/vim-vint.nix @@ -14,7 +14,7 @@ in { options = { programs.vim-vint = { enable = mkEnableOption "the Vint linter for Vimscript"; - package = mkPackageOption pkgs "vim-vint" { }; + package = mkPackageOption pkgs "vim-vint" { nullable = true; }; settings = mkOption { type = yamlFormat.type; @@ -28,7 +28,7 @@ in { }; config = mkIf cfg.enable { - home.packages = [ cfg.package ]; + home.packages = lib.mkIf (cfg.package != null) [ cfg.package ]; xdg.configFile.".vintrc.yaml".source = yamlFormat.generate "vim-vint-config" cfg.settings; diff --git a/modules/programs/vinegar.nix b/modules/programs/vinegar.nix new file mode 100644 index 000000000..cb088d89c --- /dev/null +++ b/modules/programs/vinegar.nix @@ -0,0 +1,50 @@ +{ config, lib, pkgs, ... }: +let toml = pkgs.formats.toml { }; +in { + meta.maintainers = with lib.maintainers; [ HeitorAugustoLN ]; + + options.programs.vinegar = { + enable = lib.mkEnableOption "Vinegar"; + + package = lib.mkPackageOption pkgs "vinegar" { nullable = true; }; + + settings = lib.mkOption { + type = lib.types.attrsOf toml.type; + default = { }; + example = { + env.WINEFSYNC = "1"; + + studio = { + dxvk = false; + renderer = "Vulkan"; + + fflags.DFIntTaskSchedulerTargetFps = 144; + + env = { + DXVK_HUD = "0"; + MANGOHUD = "1"; + }; + }; + }; + description = '' + Configuration written to {file}`$XDG_CONFIG_HOME/vinegar/config.toml`. + + See for more information. + ''; + }; + }; + + config = let cfg = config.programs.vinegar; + in lib.mkIf cfg.enable { + assertions = [ + (lib.hm.assertions.assertPlatform "programs.vinegar" pkgs + lib.platforms.linux) + ]; + + home.packages = lib.mkIf (cfg.package != null) [ cfg.package ]; + + xdg.configFile."vinegar/config.toml" = lib.mkIf (cfg.settings != { }) { + source = toml.generate "vinegar-config.toml" cfg.settings; + }; + }; +} diff --git a/modules/programs/vscode.nix b/modules/programs/vscode.nix index f77937d66..d90c5dd14 100644 --- a/modules/programs/vscode.nix +++ b/modules/programs/vscode.nix @@ -16,6 +16,8 @@ let "vscode-insiders" = "Code - Insiders"; "vscodium" = "VSCodium"; "openvscode-server" = "OpenVSCode Server"; + "windsurf" = "Windsurf"; + "cursor" = "Cursor"; }.${vscodePname}; extensionDir = { @@ -23,6 +25,8 @@ let "vscode-insiders" = "vscode-insiders"; "vscodium" = "vscode-oss"; "openvscode-server" = "openvscode-server"; + "windsurf" = "windsurf"; + "cursor" = "cursor"; }.${vscodePname}; userDir = if pkgs.stdenv.hostPlatform.isDarwin then @@ -30,66 +34,45 @@ let else "${config.xdg.configHome}/${configDir}/User"; - configFilePath = "${userDir}/settings.json"; - tasksFilePath = "${userDir}/tasks.json"; - keybindingsFilePath = "${userDir}/keybindings.json"; + configFilePath = name: + "${userDir}/${ + optionalString (name != "default") "profiles/${name}/" + }settings.json"; + tasksFilePath = name: + "${userDir}/${ + optionalString (name != "default") "profiles/${name}/" + }tasks.json"; + keybindingsFilePath = name: + "${userDir}/${ + optionalString (name != "default") "profiles/${name}/" + }keybindings.json"; - snippetDir = "${userDir}/snippets"; + snippetDir = name: + "${userDir}/${ + optionalString (name != "default") "profiles/${name}/" + }snippets"; # TODO: On Darwin where are the extensions? extensionPath = ".${extensionDir}/extensions"; - extensionJson = pkgs.vscode-utils.toExtensionJson cfg.extensions; - extensionJsonFile = pkgs.writeTextFile { - name = "extensions-json"; - destination = "/share/vscode/extensions/extensions.json"; - text = extensionJson; - }; + extensionJson = ext: pkgs.vscode-utils.toExtensionJson ext; + extensionJsonFile = name: text: + pkgs.writeTextFile { + inherit text; + name = "extensions-json-${name}"; + destination = "/share/vscode/extensions/extensions.json"; + }; - mergedUserSettings = cfg.userSettings - // optionalAttrs (!cfg.enableUpdateCheck) { "update.mode" = "none"; } - // optionalAttrs (!cfg.enableExtensionUpdateCheck) { + mergedUserSettings = + userSettings: enableUpdateCheck: enableExtensionUpdateCheck: + userSettings + // optionalAttrs (enableUpdateCheck == false) { "update.mode" = "none"; } + // optionalAttrs (enableExtensionUpdateCheck == false) { "extensions.autoCheckUpdates" = false; }; -in { - imports = [ - (mkChangedOptionModule [ "programs" "vscode" "immutableExtensionsDir" ] [ - "programs" - "vscode" - "mutableExtensionsDir" - ] (config: !config.programs.vscode.immutableExtensionsDir)) - ]; - - options = { - programs.vscode = { - enable = mkEnableOption "Visual Studio Code"; - - package = mkOption { - type = types.package; - default = pkgs.vscode; - defaultText = literalExpression "pkgs.vscode"; - example = literalExpression "pkgs.vscodium"; - description = '' - Version of Visual Studio Code to install. - ''; - }; - - enableUpdateCheck = mkOption { - type = types.bool; - default = true; - description = '' - Whether to enable update checks/notifications. - ''; - }; - - enableExtensionUpdateCheck = mkOption { - type = types.bool; - default = true; - description = '' - Whether to enable update notifications for extensions. - ''; - }; + profileType = types.submodule { + options = { userSettings = mkOption { type = jsonFormat.type; default = { }; @@ -182,16 +165,6 @@ in { ''; }; - mutableExtensionsDir = mkOption { - type = types.bool; - default = true; - example = false; - description = '' - Whether extensions can be installed or updated manually - or by Visual Studio Code. - ''; - }; - languageSnippets = mkOption { type = jsonFormat.type; default = { }; @@ -219,45 +192,207 @@ in { }; description = "Defines global user snippets."; }; + + enableUpdateCheck = mkOption { + type = types.nullOr types.bool; + default = null; + description = '' + Whether to enable update checks/notifications. + Can only be set for the default profile, but + it applies to all profiles. + ''; + }; + + enableExtensionUpdateCheck = mkOption { + type = types.nullOr types.bool; + default = null; + description = '' + Whether to enable update notifications for extensions. + Can only be set for the default profile, but + it applies to all profiles. + ''; + }; + }; + }; + defaultProfile = if cfg.profiles ? default then cfg.profiles.default else { }; + allProfilesExceptDefault = removeAttrs cfg.profiles [ "default" ]; +in { + imports = [ + (mkChangedOptionModule [ "programs" "vscode" "immutableExtensionsDir" ] [ + "programs" + "vscode" + "mutableExtensionsDir" + ] (config: !config.programs.vscode.immutableExtensionsDir)) + ] ++ map (v: + mkRenamedOptionModule [ "programs" "vscode" v ] [ + "programs" + "vscode" + "profiles" + "default" + v + ]) [ + "enableUpdateCheck" + "enableExtensionUpdateCheck" + "userSettings" + "userTasks" + "keybindings" + "extensions" + "languageSnippets" + "globalSnippets" + ]; + + options.programs.vscode = { + enable = mkEnableOption "Visual Studio Code"; + + package = mkOption { + type = types.package; + default = pkgs.vscode; + defaultText = literalExpression "pkgs.vscode"; + example = literalExpression "pkgs.vscodium"; + description = '' + Version of Visual Studio Code to install. + ''; + }; + + mutableExtensionsDir = mkOption { + type = types.bool; + default = allProfilesExceptDefault == { }; + example = false; + description = '' + Whether extensions can be installed or updated manually + or by Visual Studio Code. Mutually exclusive to + programs.vscode.profiles. + ''; + }; + + profiles = mkOption { + type = types.attrsOf profileType; + default = { }; + description = '' + A list of all VSCode profiles. Mutually exclusive + to programs.vscode.mutableExtensionsDir + ''; }; }; config = mkIf cfg.enable { + warnings = [ + (mkIf (allProfilesExceptDefault != { } && cfg.mutableExtensionsDir) + "programs.vscode.mutableExtensionsDir can be used only if no profiles apart from default are set.") + (mkIf ((filterAttrs (n: v: + (v ? enableExtensionUpdateCheck || v ? enableUpdateCheck) + && (v.enableExtensionUpdateCheck != null || v.enableUpdateCheck + != null)) allProfilesExceptDefault) != { }) + "The option programs.vscode.profiles.*.enableExtensionUpdateCheck and option programs.vscode.profiles.*.enableUpdateCheck is invalid for all profiles except default.") + ]; + home.packages = [ cfg.package ]; - home.file = mkMerge [ - (mkIf (mergedUserSettings != { }) { - "${configFilePath}".source = - jsonFormat.generate "vscode-user-settings" mergedUserSettings; - }) - (mkIf (cfg.userTasks != { }) { - "${tasksFilePath}".source = - jsonFormat.generate "vscode-user-tasks" cfg.userTasks; - }) - (mkIf (cfg.keybindings != [ ]) - (let dropNullFields = filterAttrs (_: v: v != null); - in { - "${keybindingsFilePath}".source = - jsonFormat.generate "vscode-keybindings" - (map dropNullFields cfg.keybindings); - })) - (mkIf (cfg.extensions != [ ]) (let - subDir = "share/vscode/extensions"; + # The file `${userDir}/globalStorage/storage.json` needs to be writable by VSCode, + # since it contains other data, such as theme backgrounds, recently opened folders, etc. + # A caveat of adding profiles this way is, VSCode has to be closed + # when this file is being written, since the file is loaded into RAM + # and overwritten on closing VSCode. + home.activation.vscodeProfiles = hm.dag.entryAfter [ "writeBoundary" ] (let + modifyGlobalStorage = + pkgs.writeShellScript "vscode-global-storage-modify" '' + PATH=${makeBinPath [ pkgs.jq ]}''${PATH:+:}$PATH + file="${userDir}/globalStorage/storage.json" + + if [ -f "$file" ]; then + existing_profiles=$(jq '.userDataProfiles // [] | map({ (.name): .location }) | add // {}' "$file") + file_write="" + profiles=(${ + escapeShellArgs + (flatten (mapAttrsToList (n: v: n) allProfilesExceptDefault)) + }) + + for profile in "''${profiles[@]}"; do + if [[ "$(echo $existing_profiles | jq --arg profile $profile 'has ($profile)')" != "true" ]] || [[ "$(echo $existing_profiles | jq --arg profile $profile 'has ($profile)')" == "true" && "$(echo $existing_profiles | jq --arg profile $profile '.[$profile]')" != "\"$profile\"" ]]; then + file_write="$file_write$([ "$file_write" != "" ] && echo "...")$profile" + fi + done + else + for profile in "''${profiles[@]}"; do + file_write="$file_write$([ "$file_write" != "" ] && echo "...")$profile" + done + + echo "{}" > "$file" + fi + + if [ "$file_write" != "" ]; then + userDataProfiles=$(jq ".userDataProfiles += $(echo $file_write | jq -R 'split("...") | map({ name: ., location: . })')" "$file") + echo $userDataProfiles > "$file" + fi + ''; + in modifyGlobalStorage.outPath); + + home.file = mkMerge (flatten [ + (mapAttrsToList (n: v: [ + (mkIf ((mergedUserSettings v.userSettings v.enableUpdateCheck + v.enableExtensionUpdateCheck) != { }) { + "${configFilePath n}".source = + jsonFormat.generate "vscode-user-settings" + (mergedUserSettings v.userSettings v.enableUpdateCheck + v.enableExtensionUpdateCheck); + }) + + (mkIf (v.userTasks != { }) { + "${tasksFilePath n}".source = + jsonFormat.generate "vscode-user-tasks" v.userTasks; + }) + + (mkIf (v.keybindings != [ ]) { + "${keybindingsFilePath n}".source = + jsonFormat.generate "vscode-keybindings" + (map (filterAttrs (_: v: v != null)) v.keybindings); + }) + + (mkIf (v.languageSnippets != { }) (mapAttrs' (language: snippet: + nameValuePair "${snippetDir n}/${language}.json" { + source = + jsonFormat.generate "user-snippet-${language}.json" snippet; + }) v.languageSnippets)) + + (mkIf (v.globalSnippets != { }) { + "${snippetDir n}/global.code-snippets".source = + jsonFormat.generate "user-snippet-global.code-snippets" + v.globalSnippets; + }) + ]) cfg.profiles) + + # We write extensions.json for all profiles, except the default profile, + # since that is handled by code below. + (mkIf (allProfilesExceptDefault != { }) (mapAttrs' (n: v: + nameValuePair "${userDir}/profiles/${n}/extensions.json" { + source = "${ + extensionJsonFile n (extensionJson v.extensions) + }/share/vscode/extensions/extensions.json"; + }) allProfilesExceptDefault)) + + (mkIf (cfg.profiles != { }) (let # Adapted from https://discourse.nixos.org/t/vscode-extensions-setup/1801/2 + subDir = "share/vscode/extensions"; toPaths = ext: map (k: { "${extensionPath}/${k}".source = "${ext}/${subDir}/${k}"; }) (if ext ? vscodeExtUniqueId then [ ext.vscodeExtUniqueId ] else builtins.attrNames (builtins.readDir (ext + "/${subDir}"))); - in if cfg.mutableExtensionsDir then - mkMerge (concatMap toPaths cfg.extensions - ++ lib.optional (lib.versionAtLeast vscodeVersion "1.74.0") { + in if (cfg.mutableExtensionsDir && allProfilesExceptDefault == { }) then + # Mutable extensions dir can only occur when only default profile is set. + # Force regenerating extensions.json using the below method, + # causes VSCode to create the extensions.json with all the extensions + # in the extension directory, which includes extensions from other profiles. + 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; + text = extensionJson defaultProfile.extensions; onChange = '' run rm $VERBOSE_ARG -f ${extensionPath}/{extensions.json,.init-default-profile-extensions} verboseEcho "Regenerating VSCode extensions.json" @@ -269,25 +404,14 @@ in { "${extensionPath}".source = let combinedExtensionsDrv = pkgs.buildEnv { name = "vscode-extensions"; - paths = cfg.extensions - ++ lib.optional (lib.versionAtLeast vscodeVersion "1.74.0") - extensionJsonFile; + paths = (flatten (mapAttrsToList (n: v: v.extensions) cfg.profiles)) + ++ optional + (versionAtLeast vscodeVersion "1.74.0" && defaultProfile != { }) + (extensionJsonFile "default" + (extensionJson defaultProfile.extensions)); }; in "${combinedExtensionsDrv}/${subDir}"; })) - - (mkIf (cfg.globalSnippets != { }) - (let globalSnippets = "${snippetDir}/global.code-snippets"; - in { - "${globalSnippets}".source = - jsonFormat.generate "user-snippet-global.code-snippets" - cfg.globalSnippets; - })) - - (lib.mapAttrs' (language: snippet: - lib.nameValuePair "${snippetDir}/${language}.json" { - source = jsonFormat.generate "user-snippet-${language}.json" snippet; - }) cfg.languageSnippets) - ]; + ]); }; } diff --git a/modules/programs/vscode/haskell.nix b/modules/programs/vscode/haskell.nix index 63ecd18e2..450c748e4 100644 --- a/modules/programs/vscode/haskell.nix +++ b/modules/programs/vscode/haskell.nix @@ -52,12 +52,12 @@ in { }; config = mkIf cfg.enable { - programs.vscode.userSettings = mkIf cfg.hie.enable { + programs.vscode.profiles.default.userSettings = mkIf cfg.hie.enable { "languageServerHaskell.enableHIE" = true; "languageServerHaskell.hieExecutablePath" = cfg.hie.executablePath; }; - programs.vscode.extensions = + programs.vscode.profiles.default.extensions = [ pkgs.vscode-extensions.justusadam.language-haskell ] ++ lib.optional cfg.hie.enable pkgs.vscode-extensions.alanz.vscode-hie-server; diff --git a/modules/programs/watson.nix b/modules/programs/watson.nix index c842c519a..1f9864559 100644 --- a/modules/programs/watson.nix +++ b/modules/programs/watson.nix @@ -26,17 +26,14 @@ in { description = "Package providing the {command}`watson`."; }; - enableBashIntegration = mkEnableOption "watson's bash integration" // { - default = true; - }; + enableBashIntegration = + lib.hm.shell.mkBashIntegrationOption { inherit config; }; - enableZshIntegration = mkEnableOption "watson's zsh integration" // { - default = true; - }; + enableFishIntegration = + lib.hm.shell.mkFishIntegrationOption { inherit config; }; - enableFishIntegration = mkEnableOption "watson's fish integration" // { - default = true; - }; + enableZshIntegration = + lib.hm.shell.mkZshIntegrationOption { inherit config; }; settings = mkOption { type = iniFormat.type; diff --git a/modules/programs/waybar.nix b/modules/programs/waybar.nix index 72d247323..0d7294d03 100644 --- a/modules/programs/waybar.nix +++ b/modules/programs/waybar.nix @@ -2,7 +2,8 @@ let inherit (lib) - all filterAttrs hasAttr isStorePath literalExpression optionalAttrs types; + all filterAttrs hasAttr isStorePath literalExpression optional optionalAttrs + types; inherit (lib.options) mkEnableOption mkOption; inherit (lib.modules) mkIf mkMerge; @@ -24,7 +25,7 @@ let options = { layer = mkOption { - type = nullOr (enum [ "top" "bottom" ]); + type = nullOr (enum [ "top" "bottom" "overlay" ]); default = null; description = '' Decide if the bar is displayed in front (`"top"`) @@ -142,7 +143,7 @@ let }; }; in { - meta.maintainers = with lib.maintainers; [ berbiche ]; + meta.maintainers = with lib.maintainers; [ berbiche khaneliman ]; options.programs.waybar = with lib.types; { enable = mkEnableOption "Waybar"; @@ -197,8 +198,9 @@ in { systemd.enable = mkEnableOption "Waybar systemd integration"; systemd.target = mkOption { - type = str; - default = "graphical-session.target"; + type = nullOr str; + default = config.wayland.systemd.target; + defaultText = literalExpression "config.wayland.systemd.target"; example = "sway-session.target"; description = '' The systemd target that will automatically start the Waybar service. @@ -209,6 +211,17 @@ in { ''; }; + systemd.enableInspect = mkOption { + type = bool; + default = false; + example = true; + description = '' + Inspect objects and find their CSS classes, experiment with live CSS styles, and lookup the current value of CSS properties. + + See + ''; + }; + style = mkOption { type = nullOr (either path lines); default = null; @@ -308,8 +321,13 @@ in { Description = "Highly customizable Wayland bar for Sway and Wlroots based compositors."; Documentation = "https://github.com/Alexays/Waybar/wiki"; - PartOf = [ "graphical-session.target" ]; - After = [ "graphical-session-pre.target" ]; + PartOf = [ cfg.systemd.target ]; + After = [ cfg.systemd.target ]; + ConditionEnvironment = "WAYLAND_DISPLAY"; + X-Restart-Triggers = optional (settings != [ ]) + "${config.xdg.configFile."waybar/config".source}" + ++ optional (cfg.style != null) + "${config.xdg.configFile."waybar/style.css".source}"; }; Service = { @@ -317,9 +335,12 @@ in { ExecReload = "${pkgs.coreutils}/bin/kill -SIGUSR2 $MAINPID"; Restart = "on-failure"; KillMode = "mixed"; + } // optionalAttrs cfg.systemd.enableInspect { + Environment = [ "GTK_DEBUG=interactive" ]; }; - Install = { WantedBy = [ cfg.systemd.target ]; }; + Install.WantedBy = + lib.optional (cfg.systemd.target != null) cfg.systemd.target; }; }) ]); diff --git a/modules/programs/wezterm.nix b/modules/programs/wezterm.nix index bd3be4686..c1478d64a 100644 --- a/modules/programs/wezterm.nix +++ b/modules/programs/wezterm.nix @@ -1,18 +1,17 @@ { config, lib, pkgs, ... }: -with lib; - let + inherit (lib) literalExpression mkIf mkEnableOption mkOption types; cfg = config.programs.wezterm; + tomlFormat = pkgs.formats.toml { }; shellIntegrationStr = '' source "${cfg.package}/etc/profile.d/wezterm.sh" ''; - in { - meta.maintainers = [ hm.maintainers.blmhemu ]; + meta.maintainers = [ lib.hm.maintainers.blmhemu lib.maintainers.khaneliman ]; options.programs.wezterm = { enable = mkEnableOption "wezterm"; @@ -83,13 +82,11 @@ in { ''; }; - enableBashIntegration = mkEnableOption "WezTerm's Bash integration" // { - default = true; - }; + enableBashIntegration = + lib.hm.shell.mkBashIntegrationOption { inherit config; }; - enableZshIntegration = mkEnableOption "WezTerm's Zsh integration" // { - default = true; - }; + enableZshIntegration = + lib.hm.shell.mkZshIntegrationOption { inherit config; }; }; config = mkIf cfg.enable { @@ -104,8 +101,8 @@ in { ${cfg.extraConfig} ''; - } // mapAttrs' (name: value: - nameValuePair "wezterm/colors/${name}.toml" { + } // lib.mapAttrs' (name: value: + lib.nameValuePair "wezterm/colors/${name}.toml" { source = tomlFormat.generate "${name}.toml" { colors = value; }; }) cfg.colorSchemes; diff --git a/modules/programs/wlogout.nix b/modules/programs/wlogout.nix index b01f8a0ae..6b318e109 100644 --- a/modules/programs/wlogout.nix +++ b/modules/programs/wlogout.nix @@ -72,7 +72,7 @@ in { options.programs.wlogout = with lib.types; { enable = mkEnableOption "wlogout"; - package = mkPackageOption pkgs "wlogout" { }; + package = mkPackageOption pkgs "wlogout" { nullable = true; }; layout = mkOption { type = listOf wlogoutLayoutConfig; @@ -132,7 +132,7 @@ in { lib.platforms.linux) ]; - home.packages = [ cfg.package ]; + home.packages = lib.mkIf (cfg.package != null) [ cfg.package ]; xdg.configFile."wlogout/layout" = mkIf (cfg.layout != [ ]) { source = pkgs.writeText "wlogout/layout" layoutContent; diff --git a/modules/programs/wofi.nix b/modules/programs/wofi.nix index 1317716ed..c2ea4e4d6 100644 --- a/modules/programs/wofi.nix +++ b/modules/programs/wofi.nix @@ -17,7 +17,7 @@ in { enable = mkEnableOption "wofi: a launcher/menu program for wlroots based wayland compositors such as sway"; - package = mkPackageOption pkgs "wofi" { }; + package = mkPackageOption pkgs "wofi" { nullable = true; }; settings = mkOption { default = { }; @@ -58,7 +58,7 @@ in { assertions = [ (hm.assertions.assertPlatform "programs.wofi" pkgs platforms.linux) ]; - home.packages = [ cfg.package ]; + home.packages = lib.mkIf (cfg.package != null) [ cfg.package ]; xdg.configFile = mkMerge [ (mkIf (cfg.settings != { }) { diff --git a/modules/programs/wpaperd.nix b/modules/programs/wpaperd.nix deleted file mode 100644 index 655024a06..000000000 --- a/modules/programs/wpaperd.nix +++ /dev/null @@ -1,49 +0,0 @@ -{ config, lib, pkgs, ... }: - -with lib; - -let - cfg = config.programs.wpaperd; - tomlFormat = pkgs.formats.toml { }; -in { - meta.maintainers = [ hm.maintainers.Avimitin ]; - - options.programs.wpaperd = { - enable = mkEnableOption "wpaperd"; - - package = mkPackageOption pkgs "wpaperd" { }; - - settings = mkOption { - type = tomlFormat.type; - default = { }; - example = literalExpression '' - { - eDP-1 = { - path = "/home/foo/Pictures/Wallpaper"; - apply-shadow = true; - }; - DP-2 = { - path = "/home/foo/Pictures/Anime"; - sorting = "descending"; - }; - } - ''; - description = '' - Configuration written to - {file}`$XDG_CONFIG_HOME/wpaperd/wallpaper.toml`. - See - for the full list of options. - ''; - }; - }; - - config = mkIf cfg.enable { - home.packages = [ cfg.package ]; - - xdg.configFile = { - "wpaperd/wallpaper.toml" = mkIf (cfg.settings != { }) { - source = tomlFormat.generate "wpaperd-wallpaper" cfg.settings; - }; - }; - }; -} diff --git a/modules/programs/xplr.nix b/modules/programs/xplr.nix index bd9222954..ddbbc1133 100644 --- a/modules/programs/xplr.nix +++ b/modules/programs/xplr.nix @@ -9,7 +9,7 @@ let version = '${cfg.package.version}' ''; - # If `value` is a Nix store path, create the symlink `/nix/store/newhash/${name}/*` + # If `value` is a Nix store path, create the symlink `/nix/store/newhash/${name}/*` # to `/nix/store/oldhash/*` and returns `/nix/store/newhash`. wrapPlugin = name: value: if lib.isStorePath value then @@ -49,7 +49,7 @@ in { options.programs.xplr = { enable = mkEnableOption "xplr, terminal UI based file explorer"; - package = mkPackageOption pkgs "xplr" { }; + package = mkPackageOption pkgs "xplr" { nullable = true; }; plugins = mkOption { type = with types; nullOr (attrsOf (either package str)); @@ -58,7 +58,7 @@ in { description = '' An attribute set of plugin paths to be added to the [package.path] of the {file}`~/config/xplr/init.lua` configuration file. - Must be a package or string representing the plugin directory's path. + Must be a package or string representing the plugin directory's path. If the path string is not absolute, it will be relative to {file}`$XDG_CONFIG_HOME/xplr/init.lua`. ''; example = literalExpression '' @@ -91,7 +91,7 @@ in { }; config = mkIf cfg.enable { - home.packages = [ cfg.package ]; + home.packages = lib.mkIf (cfg.package != null) [ cfg.package ]; xdg.configFile."xplr/init.lua".source = pkgs.writeText "init.lua" configFile; diff --git a/modules/programs/yambar.nix b/modules/programs/yambar.nix index f4e0a434a..efda8f19e 100644 --- a/modules/programs/yambar.nix +++ b/modules/programs/yambar.nix @@ -11,7 +11,7 @@ in { options.programs.yambar = { enable = lib.mkEnableOption "Yambar"; - package = lib.mkPackageOption pkgs "yambar" { }; + package = lib.mkPackageOption pkgs "yambar" { nullable = true; }; settings = lib.mkOption { type = yamlFormat.type; @@ -46,7 +46,7 @@ in { lib.platforms.linux) ]; - home.packages = [ cfg.package ]; + home.packages = lib.mkIf (cfg.package != null) [ cfg.package ]; xdg.configFile."yambar/config.yml" = lib.mkIf (cfg.settings != { }) { source = yamlFormat.generate "config.yml" cfg.settings; diff --git a/modules/programs/yazi.nix b/modules/programs/yazi.nix index d7b880200..be77188b9 100644 --- a/modules/programs/yazi.nix +++ b/modules/programs/yazi.nix @@ -1,53 +1,20 @@ { config, lib, pkgs, ... }: - -with lib; - let + inherit (lib) + literalExpression mapAttrsToList mkEnableOption mkIf mkOption optionalString + types; + cfg = config.programs.yazi; tomlFormat = pkgs.formats.toml { }; - - bashIntegration = '' - function ${cfg.shellWrapperName}() { - local tmp="$(mktemp -t "yazi-cwd.XXXXX")" - yazi "$@" --cwd-file="$tmp" - if cwd="$(cat -- "$tmp")" && [ -n "$cwd" ] && [ "$cwd" != "$PWD" ]; then - builtin cd -- "$cwd" - fi - rm -f -- "$tmp" - } - ''; - - fishIntegration = '' - function ${cfg.shellWrapperName} - set tmp (mktemp -t "yazi-cwd.XXXXX") - yazi $argv --cwd-file="$tmp" - if set cwd (cat -- "$tmp"); and [ -n "$cwd" ]; and [ "$cwd" != "$PWD" ] - builtin cd -- "$cwd" - end - rm -f -- "$tmp" - end - ''; - - nushellIntegration = '' - def --env ${cfg.shellWrapperName} [...args] { - let tmp = (mktemp -t "yazi-cwd.XXXXX") - yazi ...$args --cwd-file $tmp - let cwd = (open $tmp) - if $cwd != "" and $cwd != $env.PWD { - cd $cwd - } - rm -fp $tmp - } - ''; in { - meta.maintainers = with maintainers; [ xyenon eljamm ]; + meta.maintainers = with lib.maintainers; [ eljamm khaneliman xyenon ]; options.programs.yazi = { enable = mkEnableOption "yazi"; - package = mkPackageOption pkgs "yazi" { }; + package = lib.mkPackageOption pkgs "yazi" { nullable = true; }; - shellWrapperName = mkOption { + shellWrapperName = lib.mkOption { type = types.str; default = "yy"; example = "y"; @@ -56,29 +23,33 @@ in { ''; }; - enableBashIntegration = mkEnableOption "Bash integration"; + enableBashIntegration = + lib.hm.shell.mkBashIntegrationOption { inherit config; }; - enableZshIntegration = mkEnableOption "Zsh integration"; + enableFishIntegration = + lib.hm.shell.mkFishIntegrationOption { inherit config; }; - enableFishIntegration = mkEnableOption "Fish integration"; + enableNushellIntegration = + lib.hm.shell.mkNushellIntegrationOption { inherit config; }; - enableNushellIntegration = mkEnableOption "Nushell integration"; + enableZshIntegration = + lib.hm.shell.mkZshIntegrationOption { inherit config; }; keymap = mkOption { type = tomlFormat.type; default = { }; example = literalExpression '' { - input.keymap = [ - { exec = "close"; on = [ "" ]; } - { exec = "close --submit"; on = [ "" ]; } - { exec = "escape"; on = [ "" ]; } - { exec = "backspace"; on = [ "" ]; } + input.prepend_keymap = [ + { run = "close"; on = [ "" ]; } + { run = "close --submit"; on = [ "" ]; } + { run = "escape"; on = [ "" ]; } + { run = "backspace"; on = [ "" ]; } ]; - manager.keymap = [ - { exec = "escape"; on = [ "" ]; } - { exec = "quit"; on = [ "q" ]; } - { exec = "close"; on = [ "" ]; } + manager.prepend_keymap = [ + { run = "escape"; on = [ "" ]; } + { run = "quit"; on = [ "q" ]; } + { run = "close"; on = [ "" ]; } ]; } ''; @@ -101,7 +72,7 @@ in { }; manager = { show_hidden = false; - sort_by = "modified"; + sort_by = "mtime"; sort_dir_first = true; sort_reverse = true; }; @@ -126,7 +97,7 @@ in { { fg = "#7AD9E5"; mime = "image/*"; } { fg = "#F3D398"; mime = "video/*"; } { fg = "#F3D398"; mime = "audio/*"; } - { fg = "#CD9EFC"; mime = "application/x-bzip"; } + { fg = "#CD9EFC"; mime = "application/bzip"; } ]; }; } @@ -188,17 +159,51 @@ in { }; config = mkIf cfg.enable { - home.packages = [ cfg.package ]; + home.packages = lib.mkIf (cfg.package != null) [ cfg.package ]; - programs.bash.initExtra = mkIf cfg.enableBashIntegration bashIntegration; + programs = let + bashIntegration = '' + function ${cfg.shellWrapperName}() { + local tmp="$(mktemp -t "yazi-cwd.XXXXX")" + yazi "$@" --cwd-file="$tmp" + if cwd="$(cat -- "$tmp")" && [ -n "$cwd" ] && [ "$cwd" != "$PWD" ]; then + builtin cd -- "$cwd" + fi + rm -f -- "$tmp" + } + ''; - programs.zsh.initExtra = mkIf cfg.enableZshIntegration bashIntegration; + fishIntegration = '' + set -l tmp (mktemp -t "yazi-cwd.XXXXX") + command yazi $argv --cwd-file="$tmp" + if set cwd (cat -- "$tmp"); and [ -n "$cwd" ]; and [ "$cwd" != "$PWD" ] + builtin cd -- "$cwd" + end + rm -f -- "$tmp" + ''; - programs.fish.interactiveShellInit = - mkIf cfg.enableFishIntegration fishIntegration; + nushellIntegration = '' + def --env ${cfg.shellWrapperName} [...args] { + let tmp = (mktemp -t "yazi-cwd.XXXXX") + yazi ...$args --cwd-file $tmp + let cwd = (open $tmp) + if $cwd != "" and $cwd != $env.PWD { + cd $cwd + } + rm -fp $tmp + } + ''; + in { + bash.initExtra = mkIf cfg.enableBashIntegration bashIntegration; - programs.nushell.extraConfig = - mkIf cfg.enableNushellIntegration nushellIntegration; + zsh.initExtra = mkIf cfg.enableZshIntegration bashIntegration; + + fish.functions.${cfg.shellWrapperName} = + mkIf cfg.enableFishIntegration fishIntegration; + + nushell.extraConfig = + mkIf cfg.enableNushellIntegration nushellIntegration; + }; xdg.configFile = { "yazi/keymap.toml" = mkIf (cfg.keymap != { }) { @@ -216,27 +221,27 @@ in { } else { text = cfg.initLua; }); - } // (mapAttrs' (name: value: - nameValuePair "yazi/flavors/${name}.yazi" { source = value; }) - cfg.flavors) // (mapAttrs' (name: value: - nameValuePair "yazi/plugins/${name}.yazi" { source = value; }) + } // (lib.mapAttrs' (name: value: + lib.nameValuePair "yazi/flavors/${name}.yazi" { source = value; }) + cfg.flavors) // (lib.mapAttrs' (name: value: + lib.nameValuePair "yazi/plugins/${name}.yazi" { source = value; }) cfg.plugins); - warnings = filter (s: s != "") (concatLists [ - (mapAttrsToList (name: value: - optionalString (hasSuffix ".yazi" name) '' + warnings = lib.filter (s: s != "") (lib.concatLists [ + (mapAttrsToList (name: _value: + optionalString (lib.hasSuffix ".yazi" name) '' Flavors like `programs.yazi.flavors."${name}"` should no longer have the suffix ".yazi" in their attribute name. The flavor will be linked to `$XDG_CONFIG_HOME/yazi/flavors/${name}.yazi`. You probably want to rename it to `programs.yazi.flavors."${ - removeSuffix ".yazi" name + lib.removeSuffix ".yazi" name }"`. '') cfg.flavors) - (mapAttrsToList (name: value: - optionalString (hasSuffix ".yazi" name) '' + (mapAttrsToList (name: _value: + optionalString (lib.hasSuffix ".yazi" name) '' Plugins like `programs.yazi.plugins."${name}"` should no longer have the suffix ".yazi" in their attribute name. The plugin will be linked to `$XDG_CONFIG_HOME/yazi/plugins/${name}.yazi`. You probably want to rename it to `programs.yazi.plugins."${ - removeSuffix ".yazi" name + lib.removeSuffix ".yazi" name }"`. '') cfg.plugins) ]); @@ -245,20 +250,25 @@ in { mkAsserts = opt: requiredFiles: mapAttrsToList (name: value: let - isDir = pathIsDirectory "${value}"; + isDir = lib.pathIsDirectory "${value}"; msgNotDir = optionalString (!isDir) "The path or package should be a directory, not a single file."; isFileMissing = file: - !(pathExists "${value}/${file}") - || pathIsDirectory "${value}/${file}"; - missingFiles = filter isFileMissing requiredFiles; + !(lib.pathExists "${value}/${file}") + || lib.pathIsDirectory "${value}/${file}"; + missingFiles = lib.filter isFileMissing requiredFiles; msgFilesMissing = optionalString (missingFiles != [ ]) "The ${singularOpt} is missing these files: ${ toString missingFiles }"; - singularOpt = removeSuffix "s" opt; + singularOpt = lib.removeSuffix "s" opt; + isPluginValid = opt == "plugins" + && (lib.any (file: lib.pathExists "${value}/${file}") + requiredFiles); + isValid = + if opt == "plugins" then isPluginValid else missingFiles == [ ]; in { - assertion = isDir && missingFiles == [ ]; + assertion = isDir && isValid; message = '' Value at `programs.yazi.${opt}.${name}` is not a valid yazi ${singularOpt}. ${msgNotDir} @@ -273,6 +283,6 @@ in { "preview.png" "LICENSE" "LICENSE-tmtheme" - ]) ++ (mkAsserts "plugins" [ "init.lua" ]); + ]) ++ (mkAsserts "plugins" [ "init.lua" "main.lua" ]); }; } diff --git a/modules/programs/z-lua.nix b/modules/programs/z-lua.nix index 74dee31dc..4164aa394 100644 --- a/modules/programs/z-lua.nix +++ b/modules/programs/z-lua.nix @@ -29,29 +29,14 @@ in { ''; }; - enableBashIntegration = mkOption { - default = true; - type = types.bool; - description = '' - Whether to enable Bash integration. - ''; - }; + enableBashIntegration = + lib.hm.shell.mkBashIntegrationOption { inherit config; }; - enableZshIntegration = mkOption { - default = true; - type = types.bool; - description = '' - Whether to enable Zsh integration. - ''; - }; + enableFishIntegration = + lib.hm.shell.mkFishIntegrationOption { inherit config; }; - enableFishIntegration = mkOption { - default = true; - type = types.bool; - description = '' - Whether to enable Fish integration. - ''; - }; + enableZshIntegration = + lib.hm.shell.mkZshIntegrationOption { inherit config; }; enableAliases = mkOption { default = false; diff --git a/modules/programs/zathura.nix b/modules/programs/zathura.nix index ba34af590..3e41256d3 100644 --- a/modules/programs/zathura.nix +++ b/modules/programs/zathura.nix @@ -31,7 +31,7 @@ in { options = mkOption { default = { }; - type = with types; attrsOf (either str (either bool int)); + type = with types; attrsOf (oneOf [ str bool int float ]); description = '' Add {option}`:set` command options to zathura and make them permanent. See diff --git a/modules/programs/zed-editor.nix b/modules/programs/zed-editor.nix new file mode 100644 index 000000000..cfc55c073 --- /dev/null +++ b/modules/programs/zed-editor.nix @@ -0,0 +1,136 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.programs.zed-editor; + jsonFormat = pkgs.formats.json { }; + + mergedSettings = cfg.userSettings + // (lib.optionalAttrs (builtins.length cfg.extensions > 0) { + # this part by @cmacrae + auto_install_extensions = lib.genAttrs cfg.extensions (_: true); + }); +in { + meta.maintainers = [ hm.maintainers.libewa ]; + + options = { + # TODO: add vscode option parity (installing extensions, configuring + # keybinds with nix etc.) + programs.zed-editor = { + enable = mkEnableOption + "Zed, the high performance, multiplayer code editor from the creators of Atom and Tree-sitter"; + + package = mkPackageOption pkgs "zed-editor" { }; + + extraPackages = mkOption { + type = with types; listOf package; + default = [ ]; + example = literalExpression "[ pkgs.nixd ]"; + description = "Extra packages available to Zed."; + }; + + userSettings = mkOption { + type = jsonFormat.type; + default = { }; + example = literalExpression '' + { + features = { + copilot = false; + }; + telemetry = { + metrics = false; + }; + vim_mode = false; + ui_font_size = 16; + buffer_font_size = 16; + } + ''; + description = '' + Configuration written to Zed's {file}`settings.json`. + ''; + }; + + userKeymaps = mkOption { + type = jsonFormat.type; + default = { }; + example = literalExpression '' + [ + { + context = "Workspace"; + bindings = { + ctrl-shift-t = "workspace::NewTerminal"; + }; + }; + ] + ''; + description = '' + Configuration written to Zed's {file}`keymap.json`. + ''; + }; + + extensions = mkOption { + type = types.listOf types.str; + default = [ ]; + example = literalExpression '' + [ "swift" "nix" "xy-zed" ] + ''; + description = '' + A list of the extensions Zed should install on startup. + Use the name of a repository in the [extension list](https://github.com/zed-industries/extensions/tree/main/extensions). + ''; + }; + + installRemoteServer = mkOption { + type = types.bool; + default = false; + example = true; + description = '' + Whether to symlink the Zed's remote server binary to the expected + location. This allows remotely connecting to this system from a + distant Zed client. + + For more information, consult the + ["Remote Server" section](https://wiki.nixos.org/wiki/Zed#Remote_Server) + in the wiki. + ''; + }; + }; + }; + + config = mkIf cfg.enable { + home.packages = if cfg.extraPackages != [ ] then + [ + (pkgs.symlinkJoin { + name = + "${lib.getName cfg.package}-wrapped-${lib.getVersion cfg.package}"; + paths = [ cfg.package ]; + preferLocalBuild = true; + nativeBuildInputs = [ pkgs.makeWrapper ]; + postBuild = '' + wrapProgram $out/bin/zeditor \ + --suffix PATH : ${lib.makeBinPath cfg.extraPackages} + ''; + }) + ] + else + [ cfg.package ]; + + home.file = mkIf (cfg.installRemoteServer && (cfg.package ? remote_server)) + (let + inherit (cfg.package) version remote_server; + binaryName = "zed-remote-server-stable-${version}"; + in { + ".zed_server/${binaryName}".source = + lib.getExe' remote_server binaryName; + }); + + xdg.configFile."zed/settings.json" = (mkIf (mergedSettings != { }) { + source = jsonFormat.generate "zed-user-settings" mergedSettings; + }); + + xdg.configFile."zed/keymap.json" = (mkIf (cfg.userKeymaps != { }) { + source = jsonFormat.generate "zed-user-keymaps" cfg.userKeymaps; + }); + }; +} diff --git a/modules/programs/zellij.nix b/modules/programs/zellij.nix index 0906a028d..8d5f00051 100644 --- a/modules/programs/zellij.nix +++ b/modules/programs/zellij.nix @@ -34,24 +34,24 @@ in { ''; description = '' Configuration written to - {file}`$XDG_CONFIG_HOME/zellij/config.yaml`. + {file}`$XDG_CONFIG_HOME/zellij/config.kdl`. + + If `programs.zellij.package.version` is older than 0.32.0, then + the configuration is written to {file}`$XDG_CONFIG_HOME/zellij/config.yaml`. See for the full list of options. ''; }; - enableBashIntegration = mkEnableOption "Bash integration" // { - default = false; - }; + enableBashIntegration = + lib.hm.shell.mkBashIntegrationOption { inherit config; }; - enableZshIntegration = mkEnableOption "Zsh integration" // { - default = false; - }; + enableFishIntegration = + lib.hm.shell.mkFishIntegrationOption { inherit config; }; - enableFishIntegration = mkEnableOption "Fish integration" // { - default = false; - }; + enableZshIntegration = + lib.hm.shell.mkZshIntegrationOption { inherit config; }; }; config = mkIf cfg.enable { diff --git a/modules/programs/zk.nix b/modules/programs/zk.nix index d4abfe279..cffce3738 100644 --- a/modules/programs/zk.nix +++ b/modules/programs/zk.nix @@ -11,7 +11,7 @@ in { options.programs.zk = { enable = lib.mkEnableOption "zk"; - package = lib.mkPackageOption pkgs "zk" { }; + package = lib.mkPackageOption pkgs "zk" { nullable = true; }; settings = lib.mkOption { type = tomlFormat.type; @@ -43,7 +43,7 @@ in { }; config = lib.mkIf cfg.enable { - home.packages = [ cfg.package ]; + home.packages = lib.mkIf (cfg.package != null) [ cfg.package ]; xdg.configFile."zk/config.toml" = lib.mkIf (cfg.settings != { }) { source = tomlFormat.generate "config.toml" cfg.settings; diff --git a/modules/programs/zoxide.nix b/modules/programs/zoxide.nix index cab75cecf..8509a3dc6 100644 --- a/modules/programs/zoxide.nix +++ b/modules/programs/zoxide.nix @@ -1,30 +1,25 @@ { config, lib, pkgs, ... }: - -with lib; - let - cfg = config.programs.zoxide; - cfgOptions = concatStringsSep " " cfg.options; - + cfgOptions = lib.concatStringsSep " " cfg.options; in { meta.maintainers = [ ]; options.programs.zoxide = { - enable = mkEnableOption "zoxide"; + enable = lib.mkEnableOption "zoxide"; - package = mkOption { - type = types.package; + package = lib.mkOption { + type = lib.types.package; default = pkgs.zoxide; - defaultText = literalExpression "pkgs.zoxide"; + defaultText = lib.literalExpression "pkgs.zoxide"; description = '' Zoxide package to install. ''; }; - options = mkOption { - type = types.listOf types.str; + options = lib.mkOption { + type = lib.types.listOf lib.types.str; default = [ ]; example = [ "--no-cmd" ]; description = '' @@ -32,55 +27,37 @@ in { ''; }; - enableBashIntegration = mkOption { - default = true; - type = types.bool; - description = '' - Whether to enable Bash integration. - ''; - }; + enableBashIntegration = + lib.hm.shell.mkBashIntegrationOption { inherit config; }; - enableZshIntegration = mkOption { - default = true; - type = types.bool; - description = '' - Whether to enable Zsh integration. - ''; - }; + enableFishIntegration = + lib.hm.shell.mkFishIntegrationOption { inherit config; }; - enableFishIntegration = mkOption { - default = true; - type = types.bool; - description = '' - Whether to enable Fish integration. - ''; - }; + enableNushellIntegration = + lib.hm.shell.mkNushellIntegrationOption { inherit config; }; - enableNushellIntegration = mkOption { - default = true; - type = types.bool; - description = '' - Whether to enable Nushell integration. - ''; - }; + enableZshIntegration = + lib.hm.shell.mkZshIntegrationOption { inherit config; }; }; - config = mkIf cfg.enable { + config = lib.mkIf cfg.enable { home.packages = [ cfg.package ]; - programs.bash.initExtra = mkIf cfg.enableBashIntegration '' - eval "$(${cfg.package}/bin/zoxide init bash ${cfgOptions})" - ''; + programs.bash.initExtra = lib.mkIf cfg.enableBashIntegration + (lib.mkOrder 2000 '' + eval "$(${cfg.package}/bin/zoxide init bash ${cfgOptions})" + ''); - programs.zsh.initExtra = mkIf cfg.enableZshIntegration '' - eval "$(${cfg.package}/bin/zoxide init zsh ${cfgOptions})" - ''; + programs.zsh.initContent = lib.mkIf cfg.enableZshIntegration + (lib.mkOrder 2000 '' + eval "$(${cfg.package}/bin/zoxide init zsh ${cfgOptions})" + ''); - programs.fish.interactiveShellInit = mkIf cfg.enableFishIntegration '' + programs.fish.interactiveShellInit = lib.mkIf cfg.enableFishIntegration '' ${cfg.package}/bin/zoxide init fish ${cfgOptions} | source ''; - programs.nushell = mkIf cfg.enableNushellIntegration { + programs.nushell = lib.mkIf cfg.enableNushellIntegration { extraEnv = '' let zoxide_cache = "${config.xdg.cacheHome}/zoxide" if not ($zoxide_cache | path exists) { diff --git a/modules/programs/zsh.nix b/modules/programs/zsh.nix index b6e46392c..9d2631ace 100644 --- a/modules/programs/zsh.nix +++ b/modules/programs/zsh.nix @@ -1,292 +1,290 @@ { config, lib, pkgs, ... }: - -with lib; - let + inherit (lib) concatStringsSep literalExpression mkEnableOption mkIf mkOption mkOrder optionalString types; cfg = config.programs.zsh; relToDotDir = file: (optionalString (cfg.dotDir != null) (cfg.dotDir + "/")) + file; - pluginsDir = if cfg.dotDir != null then - relToDotDir "plugins" else ".zsh/plugins"; - - envVarsStr = config.lib.zsh.exportAll cfg.sessionVariables; - localVarsStr = config.lib.zsh.defineAll cfg.localVariables; - - aliasesStr = concatStringsSep "\n" ( - mapAttrsToList (k: v: "alias -- ${lib.escapeShellArg k}=${lib.escapeShellArg v}") cfg.shellAliases - ); - - dirHashesStr = concatStringsSep "\n" ( - mapAttrsToList (k: v: ''hash -d ${k}="${v}"'') cfg.dirHashes - ); - - zdotdir = "$HOME/" + lib.escapeShellArg cfg.dotDir; + stateVersion = config.home.stateVersion; bindkeyCommands = { emacs = "bindkey -e"; viins = "bindkey -v"; vicmd = "bindkey -a"; }; - - stateVersion = config.home.stateVersion; - - historyModule = types.submodule ({ config, ... }: { - options = { - append = mkOption { - type = types.bool; - default = false; - description = '' - If set, zsh sessions will append their history list to the history - file, rather than replace it. Thus, multiple parallel zsh sessions - will all have the new entries from their history lists added to the - history file, in the order that they exit. - - This file will still be periodically re-written to trim it when the - number of lines grows 20% beyond the value specified by - `programs.zsh.history.save`. - ''; - }; - - size = mkOption { - type = types.int; - default = 10000; - description = "Number of history lines to keep."; - }; - - save = mkOption { - type = types.int; - defaultText = 10000; - default = config.size; - description = "Number of history lines to save."; - }; - - path = mkOption { - type = types.str; - default = if versionAtLeast stateVersion "20.03" - then "$HOME/.zsh_history" - else relToDotDir ".zsh_history"; - defaultText = literalExpression '' - "$HOME/.zsh_history" if state version ≥ 20.03, - "$ZDOTDIR/.zsh_history" otherwise - ''; - example = literalExpression ''"''${config.xdg.dataHome}/zsh/zsh_history"''; - description = "History file location"; - }; - - ignorePatterns = mkOption { - type = types.listOf types.str; - default = []; - example = literalExpression ''[ "rm *" "pkill *" ]''; - description = '' - Do not enter command lines into the history list - if they match any one of the given shell patterns. - ''; - }; - - ignoreDups = mkOption { - type = types.bool; - default = true; - description = '' - Do not enter command lines into the history list - if they are duplicates of the previous event. - ''; - }; - - ignoreAllDups = mkOption { - type = types.bool; - default = false; - description = '' - If a new command line being added to the history list - duplicates an older one, the older command is removed - from the list (even if it is not the previous event). - ''; - }; - - ignoreSpace = mkOption { - type = types.bool; - default = true; - description = '' - Do not enter command lines into the history list - if the first character is a space. - ''; - }; - - expireDuplicatesFirst = mkOption { - type = types.bool; - default = false; - description = "Expire duplicates first."; - }; - - extended = mkOption { - type = types.bool; - default = false; - description = "Save timestamp into the history file."; - }; - - share = mkOption { - type = types.bool; - default = true; - description = "Share command history between zsh sessions."; - }; - }; - }); - - pluginModule = types.submodule ({ config, ... }: { - options = { - src = mkOption { - type = types.path; - description = '' - Path to the plugin folder. - - Will be added to {env}`fpath` and {env}`PATH`. - ''; - }; - - name = mkOption { - type = types.str; - description = '' - The name of the plugin. - - Don't forget to add {option}`file` - if the script name does not follow convention. - ''; - }; - - file = mkOption { - type = types.str; - description = "The plugin script to source."; - }; - }; - - config.file = mkDefault "${config.name}.plugin.zsh"; - }); - - ohMyZshModule = types.submodule { - options = { - enable = mkEnableOption "oh-my-zsh"; - - package = mkPackageOption pkgs "oh-my-zsh" { }; - - plugins = mkOption { - default = []; - example = [ "git" "sudo" ]; - type = types.listOf types.str; - description = '' - List of oh-my-zsh plugins - ''; - }; - - custom = mkOption { - default = ""; - type = types.str; - example = "$HOME/my_customizations"; - description = '' - Path to a custom oh-my-zsh package to override config of - oh-my-zsh. See - for more information. - ''; - }; - - theme = mkOption { - default = ""; - example = "robbyrussell"; - type = types.str; - description = '' - Name of the theme to be used by oh-my-zsh. - ''; - }; - - extraConfig = mkOption { - default = ""; - example = '' - zstyle :omz:plugins:ssh-agent identities id_rsa id_rsa2 id_github - ''; - type = types.lines; - description = '' - Extra settings for plugins. - ''; - }; - }; - }; - - historySubstringSearchModule = types.submodule { - options = { - enable = mkEnableOption "history substring search"; - searchUpKey = mkOption { - type = with types; either (listOf str) str ; - default = [ "^[[A" ]; - description = '' - The key codes to be used when searching up. - The default of `^[[A` may correspond to the UP key -- if not, try - `$terminfo[kcuu1]`. - ''; - }; - searchDownKey = mkOption { - type = with types; either (listOf str) str ; - default = [ "^[[B" ]; - description = '' - The key codes to be used when searching down. - The default of `^[[B` may correspond to the DOWN key -- if not, try - `$terminfo[kcud1]`. - ''; - }; - }; - }; - - syntaxHighlightingModule = types.submodule { - options = { - enable = mkEnableOption "zsh syntax highlighting"; - - package = mkPackageOption pkgs "zsh-syntax-highlighting" { }; - - highlighters = mkOption { - type = types.listOf types.str; - default = [ ]; - example = [ "brackets" ]; - description = '' - Highlighters to enable - See the list of highlighters: - ''; - }; - - patterns = mkOption { - type = types.attrsOf types.str; - default = {}; - example = { "rm -rf *" = "fg=white,bold,bg=red"; }; - description = '' - Custom syntax highlighting for user-defined patterns. - Reference: - ''; - }; - - styles = mkOption { - type = types.attrsOf types.str; - default = {}; - example = { comment = "fg=black,bold"; }; - description = '' - Custom styles for syntax highlighting. - See each highlighter style option: - ''; - }; - }; - }; - in - { imports = [ - (mkRenamedOptionModule [ "programs" "zsh" "enableAutosuggestions" ] [ "programs" "zsh" "autosuggestion" "enable" ]) - (mkRenamedOptionModule [ "programs" "zsh" "enableSyntaxHighlighting" ] [ "programs" "zsh" "syntaxHighlighting" "enable" ]) - (mkRenamedOptionModule [ "programs" "zsh" "zproof" ] [ "programs" "zsh" "zprof" ]) + (lib.mkRenamedOptionModule [ "programs" "zsh" "enableAutosuggestions" ] [ "programs" "zsh" "autosuggestion" "enable" ]) + (lib.mkRenamedOptionModule [ "programs" "zsh" "enableSyntaxHighlighting" ] [ "programs" "zsh" "syntaxHighlighting" "enable" ]) + (lib.mkRenamedOptionModule [ "programs" "zsh" "zproof" ] [ "programs" "zsh" "zprof" ]) ]; - options = { + options = + let + historyModule = types.submodule ({ config, ... }: { + options = { + append = mkOption { + type = types.bool; + default = false; + description = '' + If set, zsh sessions will append their history list to the history + file, rather than replace it. Thus, multiple parallel zsh sessions + will all have the new entries from their history lists added to the + history file, in the order that they exit. + + This file will still be periodically re-written to trim it when the + number of lines grows 20% beyond the value specified by + `programs.zsh.history.save`. + ''; + }; + + size = mkOption { + type = types.int; + default = 10000; + description = "Number of history lines to keep."; + }; + + save = mkOption { + type = types.int; + defaultText = 10000; + default = config.size; + description = "Number of history lines to save."; + }; + + path = mkOption { + type = types.str; + default = if lib.versionAtLeast stateVersion "20.03" + then "$HOME/.zsh_history" + else relToDotDir ".zsh_history"; + defaultText = literalExpression '' + "$HOME/.zsh_history" if state version ≥ 20.03, + "$ZDOTDIR/.zsh_history" otherwise + ''; + example = literalExpression ''"''${config.xdg.dataHome}/zsh/zsh_history"''; + description = "History file location"; + }; + + ignorePatterns = mkOption { + type = types.listOf types.str; + default = []; + example = literalExpression ''[ "rm *" "pkill *" ]''; + description = '' + Do not enter command lines into the history list + if they match any one of the given shell patterns. + ''; + }; + + ignoreDups = mkOption { + type = types.bool; + default = true; + description = '' + Do not enter command lines into the history list + if they are duplicates of the previous event. + ''; + }; + + ignoreAllDups = mkOption { + type = types.bool; + default = false; + description = '' + If a new command line being added to the history list + duplicates an older one, the older command is removed + from the list (even if it is not the previous event). + ''; + }; + + saveNoDups = mkOption { + type = types.bool; + default = false; + description = '' + Do not write duplicate entries into the history file. + ''; + }; + + findNoDups = mkOption { + type = types.bool; + default = false; + description = '' + Do not display a line previously found in the history + file. + ''; + }; + + ignoreSpace = mkOption { + type = types.bool; + default = true; + description = '' + Do not enter command lines into the history list + if the first character is a space. + ''; + }; + + expireDuplicatesFirst = mkOption { + type = types.bool; + default = false; + description = "Expire duplicates first."; + }; + + extended = mkOption { + type = types.bool; + default = false; + description = "Save timestamp into the history file."; + }; + + share = mkOption { + type = types.bool; + default = true; + description = "Share command history between zsh sessions."; + }; + }; + }); + + pluginModule = types.submodule ({ config, ... }: { + options = { + src = mkOption { + type = types.path; + description = '' + Path to the plugin folder. + + Will be added to {env}`fpath` and {env}`PATH`. + ''; + }; + + name = mkOption { + type = types.str; + description = '' + The name of the plugin. + + Don't forget to add {option}`file` + if the script name does not follow convention. + ''; + }; + + file = mkOption { + type = types.str; + description = "The plugin script to source."; + }; + }; + + config.file = lib.mkDefault "${config.name}.plugin.zsh"; + }); + + ohMyZshModule = types.submodule { + options = { + enable = mkEnableOption "oh-my-zsh"; + + package = lib.mkPackageOption pkgs "oh-my-zsh" { }; + + plugins = mkOption { + default = []; + example = [ "git" "sudo" ]; + type = types.listOf types.str; + description = '' + List of oh-my-zsh plugins + ''; + }; + + custom = mkOption { + default = ""; + type = types.str; + example = "$HOME/my_customizations"; + description = '' + Path to a custom oh-my-zsh package to override config of + oh-my-zsh. See + for more information. + ''; + }; + + theme = mkOption { + default = ""; + example = "robbyrussell"; + type = types.str; + description = '' + Name of the theme to be used by oh-my-zsh. + ''; + }; + + extraConfig = mkOption { + default = ""; + example = '' + zstyle :omz:plugins:ssh-agent identities id_rsa id_rsa2 id_github + ''; + type = types.lines; + description = '' + Extra settings for plugins. + ''; + }; + }; + }; + + historySubstringSearchModule = types.submodule { + options = { + enable = mkEnableOption "history substring search"; + searchUpKey = mkOption { + type = with types; either (listOf str) str ; + default = [ "^[[A" ]; + description = '' + The key codes to be used when searching up. + The default of `^[[A` may correspond to the UP key -- if not, try + `$terminfo[kcuu1]`. + ''; + }; + searchDownKey = mkOption { + type = with types; either (listOf str) str ; + default = [ "^[[B" ]; + description = '' + The key codes to be used when searching down. + The default of `^[[B` may correspond to the DOWN key -- if not, try + `$terminfo[kcud1]`. + ''; + }; + }; + }; + + syntaxHighlightingModule = types.submodule { + options = { + enable = mkEnableOption "zsh syntax highlighting"; + + package = lib.mkPackageOption pkgs "zsh-syntax-highlighting" { }; + + highlighters = mkOption { + type = types.listOf types.str; + default = [ ]; + example = [ "brackets" ]; + description = '' + Highlighters to enable + See the list of highlighters: + ''; + }; + + patterns = mkOption { + type = types.attrsOf types.str; + default = {}; + example = { "rm -rf *" = "fg=white,bold,bg=red"; }; + description = '' + Custom syntax highlighting for user-defined patterns. + Reference: + ''; + }; + + styles = mkOption { + type = types.attrsOf types.str; + default = {}; + example = { comment = "fg=black,bold"; }; + description = '' + Custom styles for syntax highlighting. + See each highlighter style option: + ''; + }; + }; + }; + in { programs.zsh = { enable = mkEnableOption "Z shell (Zsh)"; - package = mkPackageOption pkgs "zsh" { }; + package = lib.mkPackageOption pkgs "zsh" { }; autocd = mkOption { default = null; @@ -427,6 +425,9 @@ in - `match_prev_cmd`: Like `history`, but chooses the most recent match whose preceding history item matches the most recently executed command. Note that this strategy won't work as expected with ZSH options that don't preserve the history order such as `HIST_IGNORE_ALL_DUPS` or `HIST_EXPIRE_DUPS_FIRST`. + + Setting the option to an empty list `[]` will make ZSH_AUTOSUGGESTION_STRATEGY not be set automatically, + allowing the variable to be declared in {option}`programs.zsh.localVariables` or {option}`programs.zsh.sessionVariables` ''; }; }; @@ -438,7 +439,7 @@ in }; defaultKeymap = mkOption { - type = types.nullOr (types.enum (attrNames bindkeyCommands)); + type = types.nullOr (types.enum (lib.attrNames bindkeyCommands)); default = null; example = "emacs"; description = "The default base keymap to use."; @@ -451,6 +452,15 @@ in description = "Environment variables that will be set for zsh session."; }; + initContent = mkOption { + default = ""; + type = types.lines; + example = lib.mkOrder 1000 '' + echo "Hello, initContent!" + ''; + description = "Content to be added to {file}`.zshrc`. To specify the order, use `lib.mkOrder`."; + }; + initExtraBeforeCompInit = mkOption { default = ""; type = types.lines; @@ -540,7 +550,25 @@ in }; }; - config = mkIf cfg.enable (mkMerge [ + config = + let + pluginsDir = if cfg.dotDir != null then + relToDotDir "plugins" else ".zsh/plugins"; + + envVarsStr = config.lib.zsh.exportAll cfg.sessionVariables; + localVarsStr = config.lib.zsh.defineAll cfg.localVariables; + + aliasesStr = concatStringsSep "\n" ( + lib.mapAttrsToList (k: v: "alias -- ${lib.escapeShellArg k}=${lib.escapeShellArg v}") cfg.shellAliases + ); + + dirHashesStr = concatStringsSep "\n" ( + lib.mapAttrsToList (k: v: ''hash -d ${k}="${v}"'') cfg.dirHashes + ); + + zdotdir = "$HOME/" + lib.escapeShellArg cfg.dotDir; + in + mkIf cfg.enable (lib.mkMerge [ (mkIf (cfg.envExtra != "") { home.file."${relToDotDir ".zshenv"}".text = cfg.envExtra; }) @@ -593,156 +621,160 @@ in { home.packages = [ cfg.package ] - ++ optional cfg.enableCompletion pkgs.nix-zsh-completions - ++ optional cfg.oh-my-zsh.enable cfg.oh-my-zsh.package; + ++ lib.optional cfg.enableCompletion pkgs.nix-zsh-completions + ++ lib.optional cfg.oh-my-zsh.enable cfg.oh-my-zsh.package; - home.file."${relToDotDir ".zshrc"}".text = concatStringsSep "\n" ([ + programs.zsh.initContent = lib.mkMerge [ # zprof must be loaded before everything else, since it # benchmarks the shell initialization. - (optionalString cfg.zprof.enable '' + (lib.mkIf cfg.zprof.enable (mkOrder 400 '' zmodload zsh/zprof - '') + '')) - cfg.initExtraFirst - "typeset -U path cdpath fpath manpath" + (lib.mkIf (cfg.initExtraFirst != "") (mkOrder 550 cfg.initExtraFirst)) - (optionalString (cfg.cdpath != []) '' + (mkOrder 600 "typeset -U path cdpath fpath manpath") + + (lib.mkIf (cfg.cdpath != [ ]) (mkOrder 650 '' cdpath+=(${concatStringsSep " " cfg.cdpath}) + '')) + + (mkOrder 700 '' + for profile in ''${(z)NIX_PROFILES}; do + fpath+=($profile/share/zsh/site-functions $profile/share/zsh/$ZSH_VERSION/functions $profile/share/zsh/vendor-completions) + done + + HELPDIR="${cfg.package}/share/zsh/$ZSH_VERSION/help" '') - '' - for profile in ''${(z)NIX_PROFILES}; do - fpath+=($profile/share/zsh/site-functions $profile/share/zsh/$ZSH_VERSION/functions $profile/share/zsh/vendor-completions) - done - - HELPDIR="${cfg.package}/share/zsh/$ZSH_VERSION/help" - '' - - (optionalString (cfg.defaultKeymap != null) '' + (lib.mkIf (cfg.defaultKeymap != null) (mkOrder 750 '' # Use ${cfg.defaultKeymap} keymap as the default. - ${getAttr cfg.defaultKeymap bindkeyCommands} - '') - localVarsStr + ${lib.getAttr cfg.defaultKeymap bindkeyCommands} + '')) - cfg.initExtraBeforeCompInit + (lib.mkIf (localVarsStr != "") (mkOrder 800 localVarsStr)) - (concatStrings (map (plugin: '' + (lib.mkIf (cfg.initExtraBeforeCompInit != "") (mkOrder 850 cfg.initExtraBeforeCompInit)) + + (lib.mkIf (cfg.plugins != []) (mkOrder 900 (lib.concatStrings (map (plugin: '' path+="$HOME/${pluginsDir}/${plugin.name}" fpath+="$HOME/${pluginsDir}/${plugin.name}" - '') cfg.plugins)) + '') cfg.plugins)))) - '' - # Oh-My-Zsh/Prezto calls compinit during initialization, + # NOTE: Oh-My-Zsh/Prezto calls compinit during initialization, # calling it twice causes slight start up slowdown # as all $fpath entries will be traversed again. - ${optionalString (cfg.enableCompletion && !cfg.oh-my-zsh.enable && !cfg.prezto.enable) - cfg.completionInit - }'' + (lib.mkIf (cfg.enableCompletion && !cfg.oh-my-zsh.enable && !cfg.prezto.enable) + (mkOrder 950 cfg.completionInit)) - (optionalString cfg.autosuggestion.enable '' + (lib.mkIf cfg.autosuggestion.enable (mkOrder 1000 '' source ${pkgs.zsh-autosuggestions}/share/zsh-autosuggestions/zsh-autosuggestions.zsh - ZSH_AUTOSUGGEST_STRATEGY=(${concatStringsSep " " cfg.autosuggestion.strategy}) - '') - (optionalString (cfg.autosuggestion.enable && cfg.autosuggestion.highlight != null) '' - ZSH_AUTOSUGGEST_HIGHLIGHT_STYLE="${cfg.autosuggestion.highlight}" - '') + ${optionalString (cfg.autosuggestion.strategy != [ ]) '' + ZSH_AUTOSUGGEST_STRATEGY=(${ + concatStringsSep " " cfg.autosuggestion.strategy + }) + ''}${optionalString (cfg.autosuggestion.highlight != null) '' + ZSH_AUTOSUGGEST_HIGHLIGHT_STYLE="${cfg.autosuggestion.highlight}" + ''} + '')) - (optionalString cfg.oh-my-zsh.enable '' - # oh-my-zsh extra settings for plugins - ${cfg.oh-my-zsh.extraConfig} - # oh-my-zsh configuration generated by NixOS - ${optionalString (cfg.oh-my-zsh.plugins != []) - "plugins=(${concatStringsSep " " cfg.oh-my-zsh.plugins})" - } - ${optionalString (cfg.oh-my-zsh.custom != "") - "ZSH_CUSTOM=\"${cfg.oh-my-zsh.custom}\"" - } - ${optionalString (cfg.oh-my-zsh.theme != "") - "ZSH_THEME=\"${cfg.oh-my-zsh.theme}\"" - } - source $ZSH/oh-my-zsh.sh - '') + (lib.mkIf cfg.oh-my-zsh.enable (mkOrder 1100 '' + # oh-my-zsh extra settings for plugins + ${cfg.oh-my-zsh.extraConfig} + # oh-my-zsh configuration generated by NixOS + ${optionalString (cfg.oh-my-zsh.plugins != [ ]) + "plugins=(${concatStringsSep " " cfg.oh-my-zsh.plugins})"} + ${optionalString (cfg.oh-my-zsh.custom != "") + ''ZSH_CUSTOM="${cfg.oh-my-zsh.custom}"''} + ${optionalString (cfg.oh-my-zsh.theme != "") + ''ZSH_THEME="${cfg.oh-my-zsh.theme}"''} + source $ZSH/oh-my-zsh.sh + '')) - '' - ${optionalString cfg.prezto.enable - (builtins.readFile "${pkgs.zsh-prezto}/share/zsh-prezto/runcoms/zshrc")} + (mkOrder 1150 ((optionalString cfg.prezto.enable (builtins.readFile + "${cfg.prezto.package}/share/zsh-prezto/runcoms/zshrc")) + + (lib.concatStrings (map (plugin: '' + if [[ -f "$HOME/${pluginsDir}/${plugin.name}/${plugin.file}" ]]; then + source "$HOME/${pluginsDir}/${plugin.name}/${plugin.file}" + fi + '') cfg.plugins)) + '' + # History options should be set in .zshrc and after oh-my-zsh sourcing. + # See https://github.com/nix-community/home-manager/issues/177. + HISTSIZE="${toString cfg.history.size}" + SAVEHIST="${toString cfg.history.save}" + ${optionalString (cfg.history.ignorePatterns != [ ]) + "HISTORY_IGNORE=${ + lib.escapeShellArg + "(${lib.concatStringsSep "|" cfg.history.ignorePatterns})" + }"} + ${if lib.versionAtLeast stateVersion "20.03" then + ''HISTFILE="${cfg.history.path}"'' + else + ''HISTFILE="$HOME/${cfg.history.path}"''} + mkdir -p "$(dirname "$HISTFILE")" - ${concatStrings (map (plugin: '' - if [[ -f "$HOME/${pluginsDir}/${plugin.name}/${plugin.file}" ]]; then - source "$HOME/${pluginsDir}/${plugin.name}/${plugin.file}" - fi - '') cfg.plugins)} + setopt HIST_FCNTL_LOCK + ${if cfg.history.append then "setopt" else "unsetopt"} APPEND_HISTORY + ${if cfg.history.ignoreDups then "setopt" else "unsetopt"} HIST_IGNORE_DUPS + ${if cfg.history.ignoreAllDups then "setopt" else "unsetopt"} HIST_IGNORE_ALL_DUPS + ${if cfg.history.saveNoDups then "setopt" else "unsetopt"} HIST_SAVE_NO_DUPS + ${if cfg.history.findNoDups then "setopt" else "unsetopt"} HIST_FIND_NO_DUPS + ${if cfg.history.ignoreSpace then "setopt" else "unsetopt"} HIST_IGNORE_SPACE + ${if cfg.history.expireDuplicatesFirst then "setopt" else "unsetopt"} HIST_EXPIRE_DUPS_FIRST + ${if cfg.history.share then "setopt" else "unsetopt"} SHARE_HISTORY + ${if cfg.history.extended then "setopt" else "unsetopt"} EXTENDED_HISTORY + ${if cfg.autocd != null then "${if cfg.autocd then "setopt" else "unsetopt"} autocd" else ""} + '')) - # History options should be set in .zshrc and after oh-my-zsh sourcing. - # See https://github.com/nix-community/home-manager/issues/177. - HISTSIZE="${toString cfg.history.size}" - SAVEHIST="${toString cfg.history.save}" - ${optionalString (cfg.history.ignorePatterns != []) "HISTORY_IGNORE=${lib.escapeShellArg "(${lib.concatStringsSep "|" cfg.history.ignorePatterns})"}"} - ${if versionAtLeast config.home.stateVersion "20.03" - then ''HISTFILE="${cfg.history.path}"'' - else ''HISTFILE="$HOME/${cfg.history.path}"''} - mkdir -p "$(dirname "$HISTFILE")" + (lib.mkIf (cfg.initExtra != "") (mkOrder 1200 cfg.initExtra)) - setopt HIST_FCNTL_LOCK - ${if cfg.history.append then "setopt" else "unsetopt"} APPEND_HISTORY - ${if cfg.history.ignoreDups then "setopt" else "unsetopt"} HIST_IGNORE_DUPS - ${if cfg.history.ignoreAllDups then "setopt" else "unsetopt"} HIST_IGNORE_ALL_DUPS - ${if cfg.history.ignoreSpace then "setopt" else "unsetopt"} HIST_IGNORE_SPACE - ${if cfg.history.expireDuplicatesFirst then "setopt" else "unsetopt"} HIST_EXPIRE_DUPS_FIRST - ${if cfg.history.share then "setopt" else "unsetopt"} SHARE_HISTORY - ${if cfg.history.extended then "setopt" else "unsetopt"} EXTENDED_HISTORY - ${if cfg.autocd != null then "${if cfg.autocd then "setopt" else "unsetopt"} autocd" else ""} + (lib.mkIf (aliasesStr != "" || cfg.shellGlobalAliases != {}) (mkOrder 1250 + ((optionalString (aliasesStr != "") aliasesStr) + + (optionalString (cfg.shellGlobalAliases != {}) + (concatStringsSep "\n" (lib.mapAttrsToList + (k: v: "alias -g -- ${lib.escapeShellArg k}=${lib.escapeShellArg v}") + cfg.shellGlobalAliases)))))) - ${cfg.initExtra} + (lib.mkIf (dirHashesStr != "") (mkOrder 1300 '' + # Named Directory Hashes + ${dirHashesStr} + '')) - # Aliases - ${aliasesStr} - '' - ] - ++ (mapAttrsToList (k: v: "alias -g -- ${lib.escapeShellArg k}=${lib.escapeShellArg v}") cfg.shellGlobalAliases) - ++ [ ('' - # Named Directory Hashes - ${dirHashesStr} - '') - - (optionalString cfg.syntaxHighlighting.enable + (lib.mkIf cfg.syntaxHighlighting.enable (mkOrder 1350 # Load zsh-syntax-highlighting after all custom widgets have been created # https://github.com/zsh-users/zsh-syntax-highlighting#faq - '' - source ${cfg.syntaxHighlighting.package}/share/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh - ZSH_HIGHLIGHT_HIGHLIGHTERS+=(${lib.concatStringsSep " " (map lib.escapeShellArg cfg.syntaxHighlighting.highlighters)}) - ${lib.concatStringsSep "\n" ( + '' + source ${cfg.syntaxHighlighting.package}/share/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh + ZSH_HIGHLIGHT_HIGHLIGHTERS+=(${lib.concatStringsSep " " (map lib.escapeShellArg cfg.syntaxHighlighting.highlighters)}) + ${lib.concatStringsSep "\n" ( lib.mapAttrsToList - (name: value: "ZSH_HIGHLIGHT_STYLES+=(${lib.escapeShellArg name} ${lib.escapeShellArg value})") + (name: value: "ZSH_HIGHLIGHT_STYLES[${lib.escapeShellArg name}]=${lib.escapeShellArg value}") cfg.syntaxHighlighting.styles - )} - ${lib.concatStringsSep "\n" ( + )} + ${lib.concatStringsSep "\n" ( lib.mapAttrsToList (name: value: "ZSH_HIGHLIGHT_PATTERNS+=(${lib.escapeShellArg name} ${lib.escapeShellArg value})") cfg.syntaxHighlighting.patterns - )} - '') + )} + '')) - (optionalString (cfg.historySubstringSearch.enable or false) + (lib.mkIf (cfg.historySubstringSearch.enable or false) (mkOrder 1400 # Load zsh-history-substring-search after zsh-syntax-highlighting # https://github.com/zsh-users/zsh-history-substring-search#usage - '' - source ${pkgs.zsh-history-substring-search}/share/zsh-history-substring-search/zsh-history-substring-search.zsh - ${lib.concatMapStringsSep "\n" - (upKey: "bindkey \"${upKey}\" history-substring-search-up") - (lib.toList cfg.historySubstringSearch.searchUpKey) - } - ${lib.concatMapStringsSep "\n" - (downKey: "bindkey \"${downKey}\" history-substring-search-down") - (lib.toList cfg.historySubstringSearch.searchDownKey) - } - '') + '' + source ${pkgs.zsh-history-substring-search}/share/zsh-history-substring-search/zsh-history-substring-search.zsh + ${lib.concatMapStringsSep "\n" + (upKey: ''bindkey "${upKey}" history-substring-search-up'') + (lib.toList cfg.historySubstringSearch.searchUpKey)} + ${lib.concatMapStringsSep "\n" + (downKey: ''bindkey "${downKey}" history-substring-search-down'') + (lib.toList cfg.historySubstringSearch.searchDownKey)} + '')) - (optionalString cfg.zprof.enable - '' - zprof - '') - ]); + (lib.mkIf cfg.zprof.enable (mkOrder 1450 "zprof")) + ]; + + home.file."${relToDotDir ".zshrc"}".text = cfg.initContent; } (mkIf cfg.oh-my-zsh.enable { @@ -754,10 +786,10 @@ in (mkIf (cfg.plugins != []) { # Many plugins require compinit to be called # but allow the user to opt out. - programs.zsh.enableCompletion = mkDefault true; + programs.zsh.enableCompletion = lib.mkDefault true; home.file = - foldl' (a: b: a // b) {} + lib.foldl' (a: b: a // b) {} (map (plugin: { "${pluginsDir}/${plugin.name}".source = plugin.src; }) cfg.plugins); }) diff --git a/modules/programs/zsh/prezto.nix b/modules/programs/zsh/prezto.nix index 9a94f2385..5fdc8da23 100644 --- a/modules/programs/zsh/prezto.nix +++ b/modules/programs/zsh/prezto.nix @@ -14,6 +14,8 @@ let options = { enable = mkEnableOption "prezto"; + package = mkPackageOption pkgs "prezto" { default = "zsh-prezto"; }; + caseSensitive = mkOption { type = types.nullOr types.bool; # See . @@ -379,15 +381,15 @@ in { }; config = mkIf cfg.enable (mkMerge [{ home.file."${relToDotDir ".zprofile"}".text = - builtins.readFile "${pkgs.zsh-prezto}/share/zsh-prezto/runcoms/zprofile"; + builtins.readFile "${cfg.package}/share/zsh-prezto/runcoms/zprofile"; home.file."${relToDotDir ".zlogin"}".text = - builtins.readFile "${pkgs.zsh-prezto}/share/zsh-prezto/runcoms/zlogin"; + builtins.readFile "${cfg.package}/share/zsh-prezto/runcoms/zlogin"; home.file."${relToDotDir ".zlogout"}".text = - builtins.readFile "${pkgs.zsh-prezto}/share/zsh-prezto/runcoms/zlogout"; - home.packages = with pkgs; [ zsh-prezto ]; + builtins.readFile "${cfg.package}/share/zsh-prezto/runcoms/zlogout"; + home.packages = [ cfg.package ]; home.file."${relToDotDir ".zshenv"}".text = - builtins.readFile "${pkgs.zsh-prezto}/share/zsh-prezto/runcoms/zshenv"; + builtins.readFile "${cfg.package}/share/zsh-prezto/runcoms/zshenv"; home.file."${relToDotDir ".zpreztorc"}".text = '' # Generated by Nix ${optionalString (cfg.caseSensitive != null) '' diff --git a/modules/programs/zsh/zsh-abbr.nix b/modules/programs/zsh/zsh-abbr.nix index 8b6189c52..096e5da5a 100644 --- a/modules/programs/zsh/zsh-abbr.nix +++ b/modules/programs/zsh/zsh-abbr.nix @@ -9,6 +9,8 @@ in { enable = mkEnableOption "zsh-abbr - zsh manager for auto-expanding abbreviations"; + package = mkPackageOption pkgs "zsh-abbr" { }; + abbreviations = mkOption { type = types.attrsOf types.str; default = { }; @@ -27,8 +29,8 @@ in { config = mkIf cfg.enable { programs.zsh.plugins = [{ name = "zsh-abbr"; - src = pkgs.zsh-abbr; - file = "/share/zsh/zsh-abbr/abbr.plugin.zsh"; + src = cfg.package; + file = "share/zsh/zsh-abbr/zsh-abbr.plugin.zsh"; }]; xdg.configFile = { diff --git a/modules/services/amberol.nix b/modules/services/amberol.nix index a63012447..7aa169db4 100644 --- a/modules/services/amberol.nix +++ b/modules/services/amberol.nix @@ -54,7 +54,7 @@ in { Unit = { Description = "Amberol music player daemon"; Requires = [ "dbus.service" ]; - After = [ "graphical-session-pre.target" ]; + After = [ "graphical-session.target" ]; PartOf = [ "graphical-session.target" ]; }; diff --git a/modules/services/autorandr.nix b/modules/services/autorandr.nix index 64e6008e8..89ee612b2 100644 --- a/modules/services/autorandr.nix +++ b/modules/services/autorandr.nix @@ -36,7 +36,7 @@ in { systemd.user.services.autorandr = { Unit = { Description = "autorandr"; - After = [ "graphical-session-pre.target" ]; + After = [ "graphical-session.target" ]; PartOf = [ "graphical-session.target" ]; }; diff --git a/modules/services/avizo.nix b/modules/services/avizo.nix index 1bf1c1e68..4efefaa10 100644 --- a/modules/services/avizo.nix +++ b/modules/services/avizo.nix @@ -57,8 +57,8 @@ in { services.avizo = { Unit = { Description = "Volume/backlight OSD indicator"; - PartOf = [ "graphical-session.target" ]; - After = [ "graphical-session.target" ]; + PartOf = [ config.wayland.systemd.target ]; + After = [ config.wayland.systemd.target ]; ConditionEnvironment = "WAYLAND_DISPLAY"; Documentation = "man:avizo(1)"; }; @@ -69,7 +69,7 @@ in { Restart = "always"; }; - Install = { WantedBy = [ "graphical-session.target" ]; }; + Install = { WantedBy = [ config.wayland.systemd.target ]; }; }; }; }; diff --git a/modules/services/barrier.nix b/modules/services/barrier.nix index 513a7e749..59c4cbf75 100644 --- a/modules/services/barrier.nix +++ b/modules/services/barrier.nix @@ -63,7 +63,7 @@ in { systemd.user.services.barrierc = { Unit = { Description = "Barrier Client daemon"; - After = [ "graphical-session-pre.target" ]; + After = [ "graphical-session.target" ]; PartOf = [ "graphical-session.target" ]; }; Install.WantedBy = [ "graphical-session.target" ]; diff --git a/modules/services/batsignal.nix b/modules/services/batsignal.nix index 4f209f1e0..be5cf5347 100644 --- a/modules/services/batsignal.nix +++ b/modules/services/batsignal.nix @@ -32,7 +32,7 @@ in { systemd.user.services.batsignal = { Unit = { Description = "batsignal - battery monitor daemon"; - After = [ "graphical-session-pre.target" ]; + After = [ "graphical-session.target" ]; PartOf = [ "graphical-session.target" ]; }; diff --git a/modules/services/blanket.nix b/modules/services/blanket.nix index 5eeb2ab1e..bcc08ac85 100644 --- a/modules/services/blanket.nix +++ b/modules/services/blanket.nix @@ -24,7 +24,7 @@ in { Unit = { Description = "Blanket daemon"; Requires = [ "dbus.service" ]; - After = [ "graphical-session-pre.target" ]; + After = [ "graphical-session.target" ]; PartOf = [ "graphical-session.target" "pipewire.service" ]; }; diff --git a/modules/services/blueman-applet.nix b/modules/services/blueman-applet.nix index 5211534c4..47f81b48c 100644 --- a/modules/services/blueman-applet.nix +++ b/modules/services/blueman-applet.nix @@ -30,7 +30,7 @@ with lib; Unit = { Description = "Blueman applet"; Requires = [ "tray.target" ]; - After = [ "graphical-session-pre.target" "tray.target" ]; + After = [ "graphical-session.target" "tray.target" ]; PartOf = [ "graphical-session.target" ]; }; diff --git a/modules/services/cbatticon.nix b/modules/services/cbatticon.nix index 1616b2dcd..eebb5bdbc 100644 --- a/modules/services/cbatticon.nix +++ b/modules/services/cbatticon.nix @@ -118,7 +118,7 @@ in { Unit = { Description = "cbatticon system tray battery icon"; Requires = [ "tray.target" ]; - After = [ "graphical-session-pre.target" "tray.target" ]; + After = [ "graphical-session.target" "tray.target" ]; PartOf = [ "graphical-session.target" ]; }; diff --git a/modules/services/cliphist.nix b/modules/services/cliphist.nix index 1877a6de0..e7dc8e998 100644 --- a/modules/services/cliphist.nix +++ b/modules/services/cliphist.nix @@ -1,7 +1,15 @@ { config, lib, pkgs, ... }: let cfg = config.services.cliphist; in { - meta.maintainers = [ lib.hm.maintainers.janik ]; + meta.maintainers = [ lib.hm.maintainers.janik lib.maintainers.khaneliman ]; + + imports = [ + (lib.mkRenamedOptionModule [ "services" "cliphist" "systemdTarget" ] [ + "services" + "cliphist" + "systemdTargets" + ]) + ]; options.services.cliphist = { enable = @@ -25,16 +33,18 @@ in { ''; }; - systemdTarget = lib.mkOption { - type = lib.types.str; - default = "graphical-session.target"; + systemdTargets = lib.mkOption { + type = with lib.types; either (listOf str) str; + default = [ "graphical-session.target" ]; example = "sway-session.target"; description = '' - The systemd target that will automatically start the cliphist service. + The systemd targets that will automatically start the cliphist service. - When setting this value to `"sway-session.target"`, + When setting this value to `["sway-session.target"]`, make sure to also enable {option}`wayland.windowManager.sway.systemd.enable`, otherwise the service may never be started. + + Note: A single string value is deprecated, please use a list. ''; }; }; @@ -61,7 +71,7 @@ in { Restart = "on-failure"; }; - Install = { WantedBy = [ cfg.systemdTarget ]; }; + Install = { WantedBy = lib.toList cfg.systemdTargets; }; }; systemd.user.services.cliphist-images = lib.mkIf cfg.allowImages { @@ -77,7 +87,7 @@ in { Restart = "on-failure"; }; - Install = { WantedBy = [ cfg.systemdTarget ]; }; + Install = { WantedBy = lib.toList cfg.systemdTargets; }; }; }; } diff --git a/modules/services/clipman.nix b/modules/services/clipman.nix index 4616c2984..3a93773f0 100644 --- a/modules/services/clipman.nix +++ b/modules/services/clipman.nix @@ -11,7 +11,8 @@ in { systemdTarget = mkOption { type = types.str; - default = "graphical-session.target"; + default = config.wayland.systemd.target; + defaultText = literalExpression "config.wayland.systemd.target"; example = "sway-session.target"; description = '' The systemd target that will automatically start the clipman service. @@ -34,8 +35,9 @@ in { systemd.user.services.clipman = { Unit = { Description = "Clipboard management daemon"; - PartOf = [ "graphical-session.target" ]; - After = [ "graphical-session.target" ]; + PartOf = [ cfg.systemdTarget ]; + After = [ cfg.systemdTarget ]; + ConditionEnvironment = "WAYLAND_DISPLAY"; }; Service = { diff --git a/modules/services/clipse.nix b/modules/services/clipse.nix new file mode 100644 index 000000000..1d0ee95fd --- /dev/null +++ b/modules/services/clipse.nix @@ -0,0 +1,167 @@ +{ pkgs, config, lib, ... }: +let + cfg = config.services.clipse; + jsonFormat = pkgs.formats.json { }; +in { + meta.maintainers = [ lib.hm.maintainers.dsoverlord ]; + + options.services.clipse = { + enable = lib.mkEnableOption "Enable clipse clipboard manager"; + + package = lib.mkPackageOption pkgs "clipse" { nullable = true; }; + + systemdTarget = lib.mkOption { + type = lib.types.str; + default = "graphical-session.target"; + example = "sway-session.target"; + description = '' + The systemd target that will automatically start the clipse service. + + When setting this value to `"sway-session.target"`, + make sure to also enable {option}`wayland.windowManager.sway.systemd.enable`, + otherwise the service may never be started. + ''; + }; + + allowDuplicates = lib.mkOption { + type = lib.types.bool; + default = false; + description = "Allow duplicates"; + }; + + historySize = lib.mkOption { + type = lib.types.int; + default = 100; + description = "Number of history lines to keep."; + }; + + imageDisplay = { + type = lib.mkOption { + type = lib.types.enum [ "basic" "kitty" "sixel" ]; + default = "basic"; + description = "Preview image method"; + }; + + scaleX = lib.mkOption { + type = lib.types.int; + default = 9; + description = "Image scaling factor X"; + }; + + scaleY = lib.mkOption { + type = lib.types.int; + default = 9; + description = "Image scaling factor Y"; + }; + + heightCut = lib.mkOption { + type = lib.types.int; + default = 2; + description = "Height cut"; + }; + }; + + keyBindings = lib.mkOption { + type = jsonFormat.type; + + default = { }; + + example = lib.literalExpression '' + { + "choose": "enter", + "clearSelected": "S", + "down": "down", + "end": "end", + "filter": "/", + "home": "home", + "more": "?", + "nextPage": "right", + "prevPage": "left", + "preview": "t", + "quit": "q", + "remove": "x", + "selectDown": "ctrl+down", + "selectSingle": "s", + "selectUp": "ctrl+up", + "togglePin": "p", + "togglePinned": "tab", + "up": "up", + "yankFilter": "ctrl+s" + } + ''; + + description = "Custom key bindings"; + }; + + theme = lib.mkOption { + type = jsonFormat.type; + + default = { useCustomTheme = false; }; + + example = lib.literalExpression '' + { + useCustomTheme = true; + DimmedDesc = "#ffffff"; + DimmedTitle = "#ffffff"; + FilteredMatch = "#ffffff"; + NormalDesc = "#ffffff"; + NormalTitle = "#ffffff"; + SelectedDesc = "#ffffff"; + SelectedTitle = "#ffffff"; + SelectedBorder = "#ffffff"; + SelectedDescBorder = "#ffffff"; + TitleFore = "#ffffff"; + Titleback = "#434C5E"; + StatusMsg = "#ffffff"; + PinIndicatorColor = "#ff0000"; + }; + ''; + + description = '' + Configuration written to + {file}`$XDG_CONFIG_HOME/clipse/custom_theme.json`. + ''; + }; + }; + + config = lib.mkIf cfg.enable { + assertions = [ + (lib.hm.assertions.assertPlatform "services.clipse" pkgs + lib.platforms.linux) + ]; + + home.packages = lib.mkIf (cfg.package != null) [ cfg.package ]; + + xdg.configFile."clipse/config.json".source = + jsonFormat.generate "settings" { + allowDuplicates = cfg.allowDuplicates; + historyFile = "clipboard_history.json"; + maxHistory = cfg.historySize; + logFile = "clipse.log"; + themeFile = "custom_theme.json"; + tempDir = "tmp_files"; + keyBindings = cfg.keyBindings; + imageDisplay = cfg.imageDisplay; + }; + + xdg.configFile."clipse/custom_theme.json".source = + jsonFormat.generate "theme" cfg.theme; + + systemd.user.services.clipse = + lib.mkIf (pkgs.stdenv.isLinux && (cfg.package != null)) { + Unit = { + Description = "Clipse listener"; + PartOf = [ "graphical-session.target" ]; + After = [ "graphical-session.target" ]; + }; + + Service = { + Type = "oneshot"; + RemainAfterExit = true; + ExecStart = "${cfg.package}/bin/clipse -listen"; + }; + + Install = { WantedBy = [ cfg.systemdTarget ]; }; + }; + }; +} diff --git a/modules/services/conky.nix b/modules/services/conky.nix index bf7eeea8b..657c29bf5 100644 --- a/modules/services/conky.nix +++ b/modules/services/conky.nix @@ -41,7 +41,7 @@ in with lib; { Service = { Restart = "always"; RestartSec = "3"; - ExecStart = toString ([ "${pkgs.conky}/bin/conky" ] + ExecStart = toString ([ "${cfg.package}/bin/conky" ] ++ optional (cfg.extraConfig != "") "--config ${pkgs.writeText "conky.conf" cfg.extraConfig}"); }; diff --git a/modules/services/copyq.nix b/modules/services/copyq.nix index 32e83978b..6c4122048 100644 --- a/modules/services/copyq.nix +++ b/modules/services/copyq.nix @@ -25,6 +25,13 @@ in { otherwise the service may never be started. ''; }; + + forceXWayland = lib.mkOption { + type = lib.types.bool; + default = true; + example = false; + description = "Force the CopyQ to use the X backend on wayland"; + }; }; config = lib.mkIf cfg.enable { @@ -45,7 +52,7 @@ in { Service = { ExecStart = "${cfg.package}/bin/copyq"; Restart = "on-failure"; - Environment = [ "QT_QPA_PLATFORM=xcb" ]; + Environment = lib.optional cfg.forceXWayland "QT_QPA_PLATFORM=xcb"; }; Install = { WantedBy = [ cfg.systemdTarget ]; }; diff --git a/modules/services/darkman.nix b/modules/services/darkman.nix index b399dad86..93aafda98 100644 --- a/modules/services/darkman.nix +++ b/modules/services/darkman.nix @@ -48,7 +48,7 @@ in { darkman, a tool that automatically switches dark-mode on and off based on the time of the day''; - package = mkPackageOption pkgs "darkman" { }; + package = mkPackageOption pkgs "darkman" { nullable = true; }; settings = mkOption { type = types.submodule { freeformType = yamlFormat.type; }; @@ -76,7 +76,7 @@ in { (hm.assertions.assertPlatform "services.darkman" pkgs platforms.linux) ]; - home.packages = [ cfg.package ]; + home.packages = lib.mkIf (cfg.package != null) [ cfg.package ]; xdg.configFile = { "darkman/config.yaml" = mkIf (cfg.settings != { }) { @@ -91,7 +91,7 @@ in { (generateScripts "light-mode.d" cfg.lightModeScripts)) ]; - systemd.user.services.darkman = { + systemd.user.services.darkman = lib.mkIf (cfg.package != null) { Unit = { Description = "Darkman system service"; Documentation = "man:darkman(1)"; diff --git a/modules/services/devilspie2.nix b/modules/services/devilspie2.nix index fa77153e7..ab61e9778 100644 --- a/modules/services/devilspie2.nix +++ b/modules/services/devilspie2.nix @@ -36,7 +36,7 @@ in { Service.ExecStart = "${pkgs.devilspie2}/bin/devilspie2"; Unit = { Description = "devilspie2"; - After = [ "graphical-session-pre.target" ]; + After = [ "graphical-session.target" ]; PartOf = [ "graphical-session.target" ]; }; Install.WantedBy = [ "graphical-session.target" ]; diff --git a/modules/services/dunst.nix b/modules/services/dunst.nix index 5bd82a399..696783c15 100644 --- a/modules/services/dunst.nix +++ b/modules/services/dunst.nix @@ -25,7 +25,7 @@ let options = { package = mkOption { type = types.package; - example = literalExpression "pkgs.gnome.adwaita-icon-theme"; + example = literalExpression "pkgs.adwaita-icon-theme"; description = "Package providing the theme."; }; @@ -180,8 +180,8 @@ in { systemd.user.services.dunst = { Unit = { Description = "Dunst notification daemon"; - After = [ "graphical-session-pre.target" ]; - PartOf = [ "graphical-session.target" ]; + After = [ config.wayland.systemd.target ]; + PartOf = [ config.wayland.systemd.target ]; }; Service = { diff --git a/modules/services/easyeffects.nix b/modules/services/easyeffects.nix index fd5e4b404..b71ec8d83 100644 --- a/modules/services/easyeffects.nix +++ b/modules/services/easyeffects.nix @@ -51,7 +51,7 @@ in { Unit = { Description = "Easyeffects daemon"; Requires = [ "dbus.service" ]; - After = [ "graphical-session-pre.target" ]; + After = [ "graphical-session.target" ]; PartOf = [ "graphical-session.target" "pipewire.service" ]; }; diff --git a/modules/services/emacs.nix b/modules/services/emacs.nix index d319abf01..e280b3219 100644 --- a/modules/services/emacs.nix +++ b/modules/services/emacs.nix @@ -41,7 +41,6 @@ let # to work without wrapping it. socketDir = "%t/emacs"; socketPath = "${socketDir}/server"; - in { meta.maintainers = [ maintainers.tadfisher ]; @@ -112,12 +111,7 @@ in { }; config = mkIf cfg.enable (mkMerge [ - { - assertions = [ - (lib.hm.assertions.assertPlatform "services.emacs" pkgs - lib.platforms.linux) - ]; - + (mkIf pkgs.stdenv.isLinux { systemd.user.services.emacs = { Unit = { Description = "Emacs text editor"; @@ -190,9 +184,9 @@ in { }/bin/emacsclient "''${@:---create-frame}"''); }; }; - } + }) - (mkIf cfg.socketActivation.enable { + (mkIf (cfg.socketActivation.enable && pkgs.stdenv.isLinux) { systemd.user.sockets.emacs = { Unit = { Description = "Emacs text editor"; @@ -222,5 +216,20 @@ in { }; }; }) + + (mkIf pkgs.stdenv.isDarwin { + launchd.agents.emacs = { + enable = true; + config = { + ProgramArguments = [ "${cfg.package}/bin/emacs" "--fg-daemon" ] + ++ cfg.extraOptions; + RunAtLoad = true; + KeepAlive = { + Crashed = true; + SuccessfulExit = false; + }; + }; + }; + }) ]); } diff --git a/modules/services/espanso.nix b/modules/services/espanso.nix index f6e27e796..dbfa05875 100644 --- a/modules/services/espanso.nix +++ b/modules/services/espanso.nix @@ -121,9 +121,9 @@ in { systemd.user.services.espanso = { Unit = { Description = "Espanso: cross platform text expander in Rust"; }; Service = { - Type = "exec"; - ExecStart = "${cfg.package}/bin/espanso daemon"; + ExecStart = "${cfg.package}/bin/espanso launcher"; Restart = "on-failure"; + RestartSec = 3; }; Install = { WantedBy = [ "default.target" ]; }; }; diff --git a/modules/services/etesync-dav.nix b/modules/services/etesync-dav.nix index 5fd58d092..fe83e5391 100644 --- a/modules/services/etesync-dav.nix +++ b/modules/services/etesync-dav.nix @@ -25,7 +25,7 @@ in { serverUrl = mkOption { type = types.str; - default = "https://api.etesync.com/"; + default = "https://api.etebase.com/partner/etesync/"; description = "The URL to the etesync server."; }; diff --git a/modules/services/flameshot.nix b/modules/services/flameshot.nix index ebdfd0067..b35f518b3 100644 --- a/modules/services/flameshot.nix +++ b/modules/services/flameshot.nix @@ -56,7 +56,7 @@ in { Unit = { Description = "Flameshot screenshot tool"; Requires = [ "tray.target" ]; - After = [ "graphical-session-pre.target" "tray.target" ]; + After = [ "graphical-session.target" "tray.target" ]; PartOf = [ "graphical-session.target" ]; X-Restart-Triggers = mkIf (cfg.settings != { }) [ "${iniFile}" ]; }; diff --git a/modules/services/fnott.nix b/modules/services/fnott.nix index ecbd0fd15..e63cb571d 100644 --- a/modules/services/fnott.nix +++ b/modules/services/fnott.nix @@ -88,8 +88,9 @@ in { Unit = { Description = "Fnott notification daemon"; Documentation = "man:fnott(1)"; - After = [ "graphical-session-pre.target" ]; - PartOf = [ "graphical-session.target" ]; + After = [ config.wayland.systemd.target ]; + PartOf = [ config.wayland.systemd.target ]; + ConditionEnvironment = "WAYLAND_DISPLAY"; }; Service = { diff --git a/modules/services/fusuma.nix b/modules/services/fusuma.nix index 17d8b1431..aa81320b1 100644 --- a/modules/services/fusuma.nix +++ b/modules/services/fusuma.nix @@ -119,7 +119,7 @@ in { systemd.user.services.fusuma = { Unit = { Description = "Fusuma services"; - After = [ "graphical-session-pre.target" ]; + After = [ "graphical-session.target" ]; PartOf = [ "graphical-session.target" ]; }; diff --git a/modules/services/git-sync.nix b/modules/services/git-sync.nix index 2d90d6331..ba16085b3 100644 --- a/modules/services/git-sync.nix +++ b/modules/services/git-sync.nix @@ -16,9 +16,9 @@ let "PATH=${ lib.makeBinPath (with pkgs; [ openssh git ] ++ repo.extraPackages) }" - "GIT_SYNC_DIRECTORY=${repo.path}" + "GIT_SYNC_DIRECTORY=${strings.escapeShellArg repo.path}" "GIT_SYNC_COMMAND=${cfg.package}/bin/git-sync" - "GIT_SYNC_REPOSITORY=${repo.uri}" + "GIT_SYNC_REPOSITORY=${strings.escapeShellArg repo.uri}" "GIT_SYNC_INTERVAL=${toString repo.interval}" ]; ExecStart = "${cfg.package}/bin/git-sync-on-inotify"; @@ -112,6 +112,15 @@ in { description = '' The repositories that should be synchronized. ''; + example = literalExpression '' + { + xyz = { + path = "''${config.home.homeDirectory}/foo/home-manager"; + uri = "git@github.com:nix-community/home-manager.git"; + interval = 1000; + }; + } + ''; }; }; }; diff --git a/modules/services/glance.nix b/modules/services/glance.nix index fa4f1a8d7..7abe17e2c 100644 --- a/modules/services/glance.nix +++ b/modules/services/glance.nix @@ -59,11 +59,11 @@ in { lib.platforms.linux) ]; - home.packages = [ cfg.package ]; + home.packages = lib.mkIf (cfg.package != null) [ cfg.package ]; xdg.configFile."glance/glance.yml".source = settingsFile; - systemd.user.services.glance = { + systemd.user.services.glance = lib.mkIf (cfg.package != null) { Unit = { Description = "Glance feed dashboard server"; PartOf = [ "graphical-session.target" ]; diff --git a/modules/services/gpg-agent.nix b/modules/services/gpg-agent.nix index 7af58c8df..f32d85af3 100644 --- a/modules/services/gpg-agent.nix +++ b/modules/services/gpg-agent.nix @@ -18,6 +18,10 @@ let export GPG_TTY '' + optionalString cfg.enableSshSupport gpgSshSupportStr; + gpgZshInitStr = '' + export GPG_TTY=$TTY + '' + optionalString cfg.enableSshSupport gpgSshSupportStr; + gpgFishInitStr = '' set -gx GPG_TTY (tty) '' + optionalString cfg.enableSshSupport gpgSshSupportStr; @@ -214,6 +218,21 @@ in { ''; }; + noAllowExternalCache = mkOption { + type = types.bool; + default = false; + description = '' + Tell Pinentry not to enable features which use an external cache for + passphrases. + + Some desktop environments prefer to unlock all credentials with one + master password and may have installed a Pinentry which employs an + additional external cache to implement such a policy. By using this + option the Pinentry is advised not to make use of such a cache and + instead always ask the user for the requested passphrase. + ''; + }; + extraConfig = mkOption { type = types.lines; default = ""; @@ -231,34 +250,27 @@ in { example = literalExpression "pkgs.pinentry-gnome3"; default = null; description = '' - Which pinentry interface to use. If not - `null`, it sets - {option}`pinentry-program` in - {file}`gpg-agent.conf`. Beware that - `pinentry-gnome3` may not work on non-Gnome - systems. You can fix it by adding the following to your - system configuration: + Which pinentry interface to use. If not `null`, it sets + {option}`pinentry-program` in {file}`gpg-agent.conf`. Beware that + `pinentry-gnome3` may not work on non-GNOME systems. You can fix it by + adding the following to your configuration: ```nix - services.dbus.packages = [ pkgs.gcr ]; + home.packages = [ pkgs.gcr ]; ``` ''; }; - enableBashIntegration = mkEnableOption "Bash integration" // { - default = true; - }; + enableBashIntegration = + lib.hm.shell.mkBashIntegrationOption { inherit config; }; - enableZshIntegration = mkEnableOption "Zsh integration" // { - default = true; - }; + enableFishIntegration = + lib.hm.shell.mkFishIntegrationOption { inherit config; }; - enableFishIntegration = mkEnableOption "Fish integration" // { - default = true; - }; + enableNushellIntegration = + lib.hm.shell.mkNushellIntegrationOption { inherit config; }; - enableNushellIntegration = mkEnableOption "Nushell integration" // { - default = true; - }; + enableZshIntegration = + lib.hm.shell.mkZshIntegrationOption { inherit config; }; }; }; @@ -268,6 +280,7 @@ in { (optional (cfg.enableSshSupport) "enable-ssh-support" ++ optional cfg.grabKeyboardAndMouse "grab" ++ optional (!cfg.enableScDaemon) "disable-scdaemon" + ++ optional (cfg.noAllowExternalCache) "no-allow-external-cache" ++ optional (cfg.defaultCacheTtl != null) "default-cache-ttl ${toString cfg.defaultCacheTtl}" ++ optional (cfg.defaultCacheTtlSsh != null) @@ -281,13 +294,13 @@ in { ++ [ cfg.extraConfig ]); home.sessionVariablesExtra = optionalString cfg.enableSshSupport '' - if [[ -z "$SSH_AUTH_SOCK" ]]; then + if [ -z "$SSH_AUTH_SOCK" ]; then export SSH_AUTH_SOCK="$(${gpgPkg}/bin/gpgconf --list-dirs agent-ssh-socket)" fi ''; programs.bash.initExtra = mkIf cfg.enableBashIntegration gpgInitStr; - programs.zsh.initExtra = mkIf cfg.enableZshIntegration gpgInitStr; + programs.zsh.initExtra = mkIf cfg.enableZshIntegration gpgZshInitStr; programs.fish.interactiveShellInit = mkIf cfg.enableFishIntegration gpgFishInitStr; diff --git a/modules/services/grobi.nix b/modules/services/grobi.nix index 9031089c9..c8a3b1412 100644 --- a/modules/services/grobi.nix +++ b/modules/services/grobi.nix @@ -79,7 +79,7 @@ in { systemd.user.services.grobi = { Unit = { Description = "grobi display auto config daemon"; - After = [ "graphical-session-pre.target" ]; + After = [ "graphical-session.target" ]; PartOf = [ "graphical-session.target" ]; }; diff --git a/modules/services/gromit-mpx.nix b/modules/services/gromit-mpx.nix index f46eddb39..142c49814 100644 --- a/modules/services/gromit-mpx.nix +++ b/modules/services/gromit-mpx.nix @@ -215,7 +215,7 @@ in { systemd.user.services.gromit-mpx = { Unit = { Description = "Gromit-MPX"; - After = [ "graphical-session-pre.target" ]; + After = [ "graphical-session.target" ]; PartOf = [ "graphical-session.target" ]; X-Restart-Triggers = [ "${config.xdg.configFile."gromit-mpx.cfg".source}" diff --git a/modules/services/hypridle.nix b/modules/services/hypridle.nix index 0e28c5438..2778bff66 100644 --- a/modules/services/hypridle.nix +++ b/modules/services/hypridle.nix @@ -1,15 +1,12 @@ { config, lib, pkgs, ... }: -with lib; -let - - cfg = config.services.hypridle; +let cfg = config.services.hypridle; in { - meta.maintainers = [ maintainers.khaneliman maintainers.fufexan ]; + meta.maintainers = with lib.maintainers; [ khaneliman fufexan ]; options.services.hypridle = { - enable = mkEnableOption "Hypridle, Hyprland's idle daemon"; + enable = lib.mkEnableOption "Hypridle, Hyprland's idle daemon"; - package = mkPackageOption pkgs "hypridle" { }; + package = lib.mkPackageOption pkgs "hypridle" { nullable = true; }; settings = lib.mkOption { type = with lib.types; @@ -65,28 +62,28 @@ in { }; }; - config = mkIf cfg.enable { - xdg.configFile."hypr/hypridle.conf" = mkIf (cfg.settings != { }) { + config = lib.mkIf cfg.enable { + xdg.configFile."hypr/hypridle.conf" = lib.mkIf (cfg.settings != { }) { text = lib.hm.generators.toHyprconf { attrs = cfg.settings; inherit (cfg) importantPrefixes; }; }; - systemd.user.services.hypridle = { - Install = { WantedBy = [ "graphical-session.target" ]; }; + systemd.user.services.hypridle = lib.mkIf (cfg.package != null) { + Install = { WantedBy = [ config.wayland.systemd.target ]; }; Unit = { ConditionEnvironment = "WAYLAND_DISPLAY"; Description = "hypridle"; - After = [ "graphical-session-pre.target" ]; - PartOf = [ "graphical-session.target" ]; - X-Restart-Triggers = + After = [ config.wayland.systemd.target ]; + PartOf = [ config.wayland.systemd.target ]; + X-Restart-Triggers = lib.mkIf (cfg.settings != { }) [ "${config.xdg.configFile."hypr/hypridle.conf".source}" ]; }; Service = { - ExecStart = "${getExe cfg.package}"; + ExecStart = "${lib.getExe cfg.package}"; Restart = "always"; RestartSec = "10"; }; diff --git a/modules/services/hyprpaper.nix b/modules/services/hyprpaper.nix index ede09b258..ba64e2372 100644 --- a/modules/services/hyprpaper.nix +++ b/modules/services/hyprpaper.nix @@ -1,15 +1,12 @@ { config, lib, pkgs, ... }: -with lib; -let - - cfg = config.services.hyprpaper; +let cfg = config.services.hyprpaper; in { - meta.maintainers = [ maintainers.khaneliman maintainers.fufexan ]; + meta.maintainers = with lib.maintainers; [ khaneliman fufexan ]; options.services.hyprpaper = { - enable = mkEnableOption "Hyprpaper, Hyprland's wallpaper daemon"; + enable = lib.mkEnableOption "Hyprpaper, Hyprland's wallpaper daemon"; - package = mkPackageOption pkgs "hyprpaper" { }; + package = lib.mkPackageOption pkgs "hyprpaper" { nullable = true; }; settings = lib.mkOption { type = with lib.types; @@ -59,28 +56,28 @@ in { }; }; - config = mkIf cfg.enable { - xdg.configFile."hypr/hyprpaper.conf" = mkIf (cfg.settings != { }) { + config = lib.mkIf cfg.enable { + xdg.configFile."hypr/hyprpaper.conf" = lib.mkIf (cfg.settings != { }) { text = lib.hm.generators.toHyprconf { attrs = cfg.settings; inherit (cfg) importantPrefixes; }; }; - systemd.user.services.hyprpaper = { - Install = { WantedBy = [ "graphical-session.target" ]; }; + systemd.user.services.hyprpaper = lib.mkIf (cfg.package != null) { + Install = { WantedBy = [ config.wayland.systemd.target ]; }; Unit = { ConditionEnvironment = "WAYLAND_DISPLAY"; Description = "hyprpaper"; - After = [ "graphical-session-pre.target" ]; - PartOf = [ "graphical-session.target" ]; - X-Restart-Triggers = + After = [ config.wayland.systemd.target ]; + PartOf = [ config.wayland.systemd.target ]; + X-Restart-Triggers = lib.mkIf (cfg.settings != { }) [ "${config.xdg.configFile."hypr/hyprpaper.conf".source}" ]; }; Service = { - ExecStart = "${getExe cfg.package}"; + ExecStart = "${lib.getExe cfg.package}"; Restart = "always"; RestartSec = "10"; }; diff --git a/modules/services/imapnotify-accounts.nix b/modules/services/imapnotify-accounts.nix index e437f94e3..1a6fbf58a 100644 --- a/modules/services/imapnotify-accounts.nix +++ b/modules/services/imapnotify-accounts.nix @@ -1,10 +1,8 @@ { pkgs, lib, ... }: - -with lib; - -{ +let inherit (lib) mkOption types; +in { options.imapnotify = { - enable = mkEnableOption "imapnotify"; + enable = lib.mkEnableOption "imapnotify"; onNotify = mkOption { type = with types; either str (attrsOf str); @@ -30,10 +28,16 @@ with lib; description = "IMAP folders to watch."; }; + extraArgs = mkOption { + type = types.listOf types.str; + default = [ ]; + example = [ "-wait 1" ]; + description = "Extra arguments to pass to goimapnotify."; + }; + extraConfig = mkOption { type = let jsonFormat = pkgs.formats.json { }; in jsonFormat.type; default = { }; - example = { wait = 10; }; description = "Additional configuration to add for this account."; }; }; diff --git a/modules/services/imapnotify.nix b/modules/services/imapnotify.nix index 63e61e7c7..bf8fefd39 100644 --- a/modules/services/imapnotify.nix +++ b/modules/services/imapnotify.nix @@ -23,12 +23,15 @@ let Service = { # Use the nix store path for config to ensure service restarts when it changes ExecStart = - "${getExe cfg.package} -conf '${genAccountConfig account}'"; + "${getExe cfg.package} -conf '${genAccountConfig account}'" + " ${ + lib.optionalString (account.imapnotify.extraArgs != [ ]) + (toString account.imapnotify.extraArgs) + }"; Restart = "always"; RestartSec = 30; Type = "simple"; - } // optionalAttrs account.notmuch.enable { - Environment = + Environment = [ "PATH=${cfg.path}" ] + ++ optional account.notmuch.enable "NOTMUCH_CONFIG=${config.xdg.configHome}/notmuch/default/config"; }; @@ -97,6 +100,17 @@ in { example = literalExpression "pkgs.imapnotify"; description = "The imapnotify package to use"; }; + + path = mkOption { + type = types.listOf types.package; + apply = lib.makeBinPath; + default = [ ]; + description = '' + List of packages to provide in PATH for the imapnotify service. + + Note, this does not apply to the Darwin launchd service. + ''; + }; }; accounts.email.accounts = mkOption { @@ -122,6 +136,12 @@ in { (checkAccounts (a: a.userName == null) "username") ]; + services.imapnotify.path = lib.mkMerge [ + (lib.mkIf config.programs.notmuch.enable [ pkgs.notmuch ]) + (lib.mkIf config.programs.mbsync.enable + [ config.programs.mbsync.package ]) + ]; + systemd.user.services = listToAttrs (map genAccountUnit imapnotifyAccounts); launchd.agents = listToAttrs (map genAccountAgent imapnotifyAccounts); diff --git a/modules/services/kanshi.nix b/modules/services/kanshi.nix index 3b1bdf2cf..453944982 100644 --- a/modules/services/kanshi.nix +++ b/modules/services/kanshi.nix @@ -38,9 +38,7 @@ let else throw "Unknown tags ${attrNames x}"; - directivesStr = '' - ${concatStringsSep "\n" (map tagToStr cfg.settings)} - ''; + directivesStr = concatStringsSep "\n" (map tagToStr cfg.settings); oldDirectivesStr = '' ${concatStringsSep "\n" @@ -288,7 +286,8 @@ in { systemdTarget = mkOption { type = types.str; - default = "sway-session.target"; + default = config.wayland.systemd.target; + defaultText = literalExpression "config.wayland.systemd.target"; description = '' Systemd target to bind to. ''; @@ -330,16 +329,21 @@ in { }) { - xdg.configFile."kanshi/config".text = - if cfg.profiles == { } && cfg.extraConfig == "" then - directivesStr - else - oldDirectivesStr; + home.packages = [ cfg.package ]; + + xdg.configFile."kanshi/config" = let + generatedConfigStr = + if cfg.profiles == { } && cfg.extraConfig == "" then + directivesStr + else + oldDirectivesStr; + in mkIf (generatedConfigStr != "") { text = generatedConfigStr; }; systemd.user.services.kanshi = { Unit = { Description = "Dynamic output configuration"; Documentation = "man:kanshi(1)"; + ConditionEnvironment = "WAYLAND_DISPLAY"; PartOf = cfg.systemdTarget; Requires = cfg.systemdTarget; After = cfg.systemdTarget; diff --git a/modules/services/kdeconnect.nix b/modules/services/kdeconnect.nix index f0b1da5be..3e6822744 100644 --- a/modules/services/kdeconnect.nix +++ b/modules/services/kdeconnect.nix @@ -14,8 +14,8 @@ in { enable = mkEnableOption "KDE connect"; package = mkOption { type = types.package; - default = pkgs.plasma5Packages.kdeconnect-kde; - example = literalExpression "pkgs.kdePackages.kdeconnect-kde"; + default = pkgs.kdePackages.kdeconnect-kde; + example = literalExpression "pkgs.plasma5Packages.kdeconnect-kde"; description = "The KDE connect package to use"; }; @@ -40,7 +40,7 @@ in { Unit = { Description = "Adds communication between your desktop and your smartphone"; - After = [ "graphical-session-pre.target" ]; + After = [ "graphical-session.target" ]; PartOf = [ "graphical-session.target" ]; }; @@ -69,7 +69,7 @@ in { Unit = { Description = "kdeconnect-indicator"; After = [ - "graphical-session-pre.target" + "graphical-session.target" "polybar.service" "taffybar.service" "stalonetray.service" diff --git a/modules/services/keynav.nix b/modules/services/keynav.nix index d83252e53..7ba5ce2e0 100644 --- a/modules/services/keynav.nix +++ b/modules/services/keynav.nix @@ -18,7 +18,7 @@ in { systemd.user.services.keynav = { Unit = { Description = "keynav"; - After = [ "graphical-session-pre.target" ]; + After = [ "graphical-session.target" ]; PartOf = [ "graphical-session.target" ]; }; diff --git a/modules/services/linux-wallpaperengine.nix b/modules/services/linux-wallpaperengine.nix new file mode 100644 index 000000000..f2d971b8f --- /dev/null +++ b/modules/services/linux-wallpaperengine.nix @@ -0,0 +1,121 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + cfg = config.services.linux-wallpaperengine; + +in { + meta.maintainers = [ hm.maintainers.ckgxrg ]; + + options.services.linux-wallpaperengine = { + enable = mkEnableOption + "linux-wallpaperengine, an implementation of Wallpaper Engine functionality"; + + package = mkPackageOption pkgs "linux-wallpaperengine" { }; + + assetsPath = mkOption { + type = types.path; + description = "Path to the assets directory."; + }; + + clamping = mkOption { + type = types.nullOr (types.enum [ "clamp" "border" "repeat" ]); + default = null; + description = "Clamping mode for all wallpapers."; + }; + + wallpapers = mkOption { + type = types.listOf (types.submodule { + options = { + monitor = mkOption { + type = types.str; + description = "Which monitor to display the wallpaper."; + }; + + wallpaperId = mkOption { + type = types.str; + description = "Wallpaper ID to be used."; + }; + + extraOptions = mkOption { + type = types.listOf types.str; + default = [ ]; + description = + "Extra arguments to pass to the linux-wallpaperengine command for this wallpaper."; + }; + + scaling = mkOption { + type = + types.nullOr (types.enum [ "stretch" "fit" "fill" "default" ]); + default = null; + description = "Scaling mode for this wallpaper."; + }; + + fps = mkOption { + type = types.nullOr types.int; + default = null; + description = "Limits the FPS to a given number."; + }; + + audio = { + silent = mkOption { + type = types.bool; + default = false; + description = "Mutes all sound of the wallpaper."; + }; + + automute = mkOption { + type = types.bool; + default = true; + description = "Automute when another app is playing sound."; + }; + + processing = mkOption { + type = types.bool; + default = true; + description = "Enables audio processing for background."; + }; + }; + }; + }); + default = [ ]; + description = "Define wallpapers."; + }; + }; + + config = mkIf cfg.enable { + assertions = [ + (lib.hm.assertions.assertPlatform "services.linux-wallpaperengine" pkgs + lib.platforms.linux) + ]; + + home.packages = [ cfg.package ]; + + systemd.user.services."linux-wallpaperengine" = let + args = lists.forEach cfg.wallpapers (each: + concatStringsSep " " (cli.toGNUCommandLine { } { + screen-root = each.monitor; + inherit (each) scaling fps; + silent = each.audio.silent; + noautomute = !each.audio.automute; + no-audio-processing = !each.audio.processing; + } ++ each.extraOptions) + # This has to be the last argument in each group + + " --bg ${each.wallpaperId}"); + in { + Unit = { + Description = "Implementation of Wallpaper Engine on Linux"; + After = [ "graphical-session.target" ]; + PartOf = [ "graphical-session.target" ]; + }; + Service = { + ExecStart = getExe cfg.package + " --assets-dir ${cfg.assetsPath} " + + "--clamping ${cfg.clamping} " + (strings.concatStringsSep " " args); + Restart = "on-failure"; + }; + Install = { WantedBy = [ "graphical-session.target" ]; }; + }; + }; +} diff --git a/modules/services/listenbrainz-mpd.nix b/modules/services/listenbrainz-mpd.nix index 3cc242216..3ccb75411 100644 --- a/modules/services/listenbrainz-mpd.nix +++ b/modules/services/listenbrainz-mpd.nix @@ -15,7 +15,7 @@ in { options.services.listenbrainz-mpd = { enable = mkEnableOption "listenbrainz-mpd"; - package = mkPackageOption pkgs "listenbrainz-mpd" { }; + package = mkPackageOption pkgs "listenbrainz-mpd" { nullable = true; }; settings = mkOption { type = tomlFormat.type; @@ -29,7 +29,7 @@ in { }; config = mkIf cfg.enable { - systemd.user.services."listenbrainz-mpd" = { + systemd.user.services."listenbrainz-mpd" = lib.mkIf (cfg.package != null) { Unit = { Description = "ListenBrainz submission client for MPD"; Documentation = "https://codeberg.org/elomatreb/listenbrainz-mpd"; diff --git a/modules/services/lorri.nix b/modules/services/lorri.nix index 533a53441..93673dd8f 100644 --- a/modules/services/lorri.nix +++ b/modules/services/lorri.nix @@ -59,7 +59,6 @@ in { "%C/lorri" # Needs %C/nix/fetcher-cache-v1.sqlite "%C/nix" - "/nix/var/nix/gcroots/per-user/%u" ]; CacheDirectory = [ "lorri" ]; Restart = "on-failure"; diff --git a/modules/services/ludusavi.nix b/modules/services/ludusavi.nix new file mode 100644 index 000000000..7acadc1a0 --- /dev/null +++ b/modules/services/ludusavi.nix @@ -0,0 +1,93 @@ +{ config, lib, pkgs, ... }: + +let + inherit (lib) getExe maintainers mkEnableOption mkIf mkOption; + + inherit (lib.types) bool nullOr path; + + cfg = config.services.ludusavi; + settingsFormat = pkgs.formats.yaml { }; + + configFile = if cfg.configFile == null then + settingsFormat.generate "config.yaml" cfg.settings + else + cfg.configFile; +in { + + options.services.ludusavi = { + enable = mkEnableOption "Ludusavi game backup tool"; + configFile = mkOption { + type = nullOr path; + default = null; + description = '' + Path to a Ludusavi `config.yaml`. Mutually exclusive with the `settings` option. + See https://github.com/mtkennerly/ludusavi/blob/master/docs/help/configuration-file.md for available options. + ''; + }; + settings = mkOption { + type = settingsFormat.type; + default = { + manifest.url = + "https://raw.githubusercontent.com/mtkennerly/ludusavi-manifest/master/data/manifest.yaml"; + roots = [ ]; + backup.path = "$XDG_STATE_HOME/backups/ludusavi"; + restore.path = "$XDG_STATE_HOME/backups/ludusavi"; + }; + example = { + language = "en-US"; + theme = "light"; + roots = [{ + path = "~/.local/share/Steam"; + store = "steam"; + }]; + backup.path = "~/.local/state/backups/ludusavi"; + restore.path = "~/.local/state/backups/ludusavi"; + }; + description = '' + Ludusavi configuration as an attribute set. See + https://github.com/mtkennerly/ludusavi#configuration-file + for available options. + ''; + }; + backupNotification = mkOption { + type = bool; + default = false; + description = '' + Send a notification message after a successful backup. + ''; + }; + }; + + config = mkIf cfg.enable { + assertions = [{ + assertion = (cfg.settings != { }) != (cfg.configFile != null); + message = + "The `settings` and `configFile` options are mutually exclusive."; + }]; + + systemd.user = { + services.ludusavi = { + Unit.Description = "Run a game save backup with Ludusavi"; + Service = { + Type = "oneshot"; + ExecStart = "${getExe pkgs.ludusavi} backup --force"; + } // lib.optionalAttrs cfg.backupNotification { + ExecStartPost = "${ + getExe pkgs.libnotify + } 'Ludusavi' 'Backup completed' -i ludusavi -a 'Ludusavi'"; + }; + }; + timers.ludusavi = { + Unit.Description = "Run a game save backup with Ludusavi, daily"; + Timer.OnCalendar = "daily"; + Install.WantedBy = [ "timers.target" ]; + }; + }; + + xdg.configFile."ludusavi/config.yaml".source = configFile; + + home.packages = [ pkgs.ludusavi ]; + }; + + meta.maintainers = [ maintainers.PopeRigby ]; +} diff --git a/modules/services/macos-remap-keys/default.nix b/modules/services/macos-remap-keys/default.nix new file mode 100644 index 000000000..0c0d2575d --- /dev/null +++ b/modules/services/macos-remap-keys/default.nix @@ -0,0 +1,72 @@ +{ config, lib, pkgs, ... }: +let + cfg = config.services.macos-remap-keys; + keytables = import ./keytables.nix { inherit lib; }; + + keyToHIDCode = table: key: keytables.${table}.${key}; + + # Note: hidutil requires HIDKeyboardModifierMapping values to be in hexadecimal + # format rather than decimal JSON. Using hex strings instead of numbers will + # crash macOS. + makeMapping = table: from: to: + '' + { "HIDKeyboardModifierMappingSrc": ${ + keyToHIDCode table from + }, "HIDKeyboardModifierMappingDst": ${keyToHIDCode table to} }''; + + makeMappingsList = table: mappings: + lib.mapAttrsToList (from: to: makeMapping table from to) mappings; + + allMappings = (makeMappingsList "keyboard" (cfg.keyboard or { })) + ++ (makeMappingsList "keypad" (cfg.keypad or { })); + + allMappingsString = lib.concatStringsSep ", " allMappings; + propertyString = ''{ "UserKeyMapping": [ ${allMappingsString} ] }''; +in { + meta.maintainers = [ lib.maintainers.WeetHet ]; + + options.services.macos-remap-keys = { + enable = lib.mkEnableOption "macOS key remapping service"; + + keyboard = lib.mkOption { + type = lib.types.attrsOf lib.types.str; + default = { }; + example = { + Capslock = "Escape"; + SquareBracketOpen = "SquareBracketClose"; + }; + description = "Mapping of keyboard keys to remap"; + }; + + keypad = lib.mkOption { + type = lib.types.attrsOf lib.types.str; + default = { }; + example = { + Enter = "Equal"; + Plus = "Minus"; + }; + description = "Mapping of keypad keys to remap"; + }; + }; + + config = lib.mkIf cfg.enable { + assertions = [ + (lib.hm.assertions.assertPlatform "services.macos-remap-keys" pkgs + lib.platforms.darwin) + ]; + home.activation.macosRemapKeys = + lib.hm.dag.entryAfter [ "writeBoundary" ] '' + run --silence /usr/bin/hidutil property --set '${propertyString}' + ''; + + launchd.agents.remap-keys = { + enable = true; + config = { + ProgramArguments = + [ "/usr/bin/hidutil" "property" "--set" propertyString ]; + KeepAlive.SuccessfulExit = false; + RunAtLoad = true; + }; + }; + }; +} diff --git a/modules/services/macos-remap-keys/keytables.nix b/modules/services/macos-remap-keys/keytables.nix new file mode 100644 index 000000000..a44bb4ece --- /dev/null +++ b/modules/services/macos-remap-keys/keytables.nix @@ -0,0 +1,139 @@ +{ lib }: +let + letters = let + alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + lettersList = lib.stringToCharacters alphabet; + indices = builtins.genList (i: i + 4) 26; + in lib.listToAttrs (lib.zipListsWith (letter: index: { + name = letter; + value = "0x${lib.toHexString index}"; + }) lettersList indices); + + numbers = { + One = "0x1E"; + Two = "0x1F"; + Three = "0x20"; + Four = "0x21"; + Five = "0x22"; + Six = "0x23"; + Seven = "0x24"; + Eight = "0x25"; + Nine = "0x26"; + Zero = "0x27"; + }; + + specialKeys = { + Enter = "0x28"; + Escape = "0x29"; + Backspace = "0x2A"; + Tab = "0x2B"; + Spacebar = "0x2C"; + Minus = "0x2D"; + Equal = "0x2E"; + SquareBracketOpen = "0x2F"; + SquareBracketClose = "0x30"; + Backslash = "0x31"; + Hash = "0x32"; + Semicolon = "0x33"; + SingleQuote = "0x34"; + GraveAccent = "0x35"; + Comma = "0x36"; + Dot = "0x37"; + Slash = "0x38"; + Capslock = "0x39"; + }; + + fKeys1To12 = { + F1 = "0x3A"; + F2 = "0x3B"; + F3 = "0x3C"; + F4 = "0x3D"; + F5 = "0x3E"; + F6 = "0x3F"; + F7 = "0x40"; + F8 = "0x41"; + F9 = "0x42"; + F10 = "0x43"; + F11 = "0x44"; + F12 = "0x45"; + }; + + fKeys13To24 = { + F13 = "0x68"; + F14 = "0x69"; + F15 = "0x6A"; + F16 = "0x6B"; + F17 = "0x6C"; + F18 = "0x6D"; + F19 = "0x6E"; + F20 = "0x6F"; + F21 = "0x70"; + F22 = "0x71"; + F23 = "0x72"; + F24 = "0x73"; + }; + + navigationKeys = { + PrintScreen = "0x46"; + ScrollLock = "0x47"; + Pause = "0x48"; + Insert = "0x49"; + Home = "0x4A"; + PageUp = "0x4B"; + ForwardDelete = "0x4C"; + End = "0x4D"; + PageDown = "0x4E"; + RightArrow = "0x4F"; + LeftArrow = "0x50"; + DownArrow = "0x51"; + UpArrow = "0x52"; + NumLock = "0x53"; + }; + + modifierKeys = { + Control = "0xE0"; + Shift = "0xE1"; + Option = "0xE2"; + Command = "0xE3"; + RightControl = "0xE4"; + RightShift = "0xE5"; + RightOption = "0xE6"; + RightCommand = "0xE7"; + }; + + keypadKeys = { + Slash = "0x54"; + Asterisk = "0x55"; + Minus = "0x56"; + Plus = "0x57"; + Enter = "0x58"; + One = "0x59"; + Two = "0x5A"; + Three = "0x5B"; + Four = "0x5C"; + Five = "0x5D"; + Six = "0x5E"; + Seven = "0x5F"; + Eight = "0x60"; + Nine = "0x61"; + Zero = "0x62"; + Dot = "0x63"; + BashSlash = "0x64"; + Application = "0x65"; + Power = "0x66"; + Equal = "0x67"; + }; + + mapToInt = keyPage: attrs: + lib.mapAttrs (name: value: + let keycode = lib.fromHexString (lib.removePrefix "0x" value); + in "0x${lib.toHexString (keyPage + keycode)}") attrs; + + page7Keys = mapToInt (lib.fromHexString "700000000") (letters // numbers + // specialKeys // fKeys1To12 // fKeys13To24 // navigationKeys + // modifierKeys); + pageFFKeys = mapToInt (lib.fromHexString "FF00000000") { Fn = "0x3"; }; +in { + keyboard = page7Keys // pageFFKeys; + keypad = mapToInt keypadKeys; +} diff --git a/modules/services/mako.nix b/modules/services/mako.nix index 7ca011782..df6532274 100644 --- a/modules/services/mako.nix +++ b/modules/services/mako.nix @@ -33,6 +33,15 @@ in { ''; }; + maxHistory = mkOption { + default = 5; + type = types.nullOr types.int; + description = '' + Set maximum number of expired notifications to keep in the history + buffer. Set 0 to disable history. + ''; + }; + sort = mkOption { default = "-time"; type = @@ -75,12 +84,14 @@ in { "bottom-right" "bottom-center" "bottom-left" + "center-right" + "center-left" "center" ]); description = '' Show notifications at the specified position on the output. Supported values are top-right, top-center, top-left, bottom-right, - bottom-center, bottom-left, and center. + bottom-center, bottom-left, center-right, center-left and center. ''; }; @@ -313,6 +324,7 @@ in { ''; text = '' ${optionalInteger "max-visible" cfg.maxVisible} + ${optionalInteger "max-history" cfg.maxHistory} ${optionalString "sort" cfg.sort} ${optionalString "output" cfg.output} ${optionalString "layer" cfg.layer} diff --git a/modules/services/megasync.nix b/modules/services/megasync.nix index 03eab490a..19258e5dd 100644 --- a/modules/services/megasync.nix +++ b/modules/services/megasync.nix @@ -1,23 +1,24 @@ { config, lib, pkgs, ... }: - -with lib; - -let - - cfg = config.services.megasync; - +let cfg = config.services.megasync; in { - meta.maintainers = [ maintainers.GaetanLepage ]; + meta.maintainers = [ lib.maintainers.GaetanLepage ]; options = { services.megasync = { - enable = mkEnableOption "Megasync client"; + enable = lib.mkEnableOption "Megasync client"; - package = mkPackageOption pkgs "megasync" { }; + package = lib.mkPackageOption pkgs "megasync" { }; + + forceWayland = lib.mkOption { + type = lib.types.bool; + default = false; + example = true; + description = "Force Megasync to run on wayland"; + }; }; }; - config = mkIf cfg.enable { + config = lib.mkIf cfg.enable { assertions = [ (lib.hm.assertions.assertPlatform "services.megasync" pkgs lib.platforms.linux) @@ -34,7 +35,11 @@ in { Install = { WantedBy = [ "graphical-session.target" ]; }; - Service = { ExecStart = "${cfg.package}/bin/megasync"; }; + Service = { + Environment = + lib.optionals cfg.forceWayland [ "DO_NOT_UNSET_XDG_SESSION_TYPE=1" ]; + ExecStart = lib.getExe' cfg.package "megasync"; + }; }; }; } diff --git a/modules/services/mopidy.nix b/modules/services/mopidy.nix index b02708578..397ed287e 100644 --- a/modules/services/mopidy.nix +++ b/modules/services/mopidy.nix @@ -23,7 +23,8 @@ let name = "mopidy-with-extensions-${pkgs.mopidy.version}"; paths = closePropagation cfg.extensionPackages; pathsToLink = [ "/${pkgs.mopidyPackages.python.sitePackages}" ]; - buildInputs = [ pkgs.makeWrapper ]; + nativeBuildInputs = [ pkgs.makeWrapper ]; + ignoreCollisions = true; postBuild = '' makeWrapper ${pkgs.mopidy}/bin/mopidy $out/bin/mopidy \ --prefix PYTHONPATH : $out/${pkgs.mopidyPackages.python.sitePackages} @@ -126,10 +127,13 @@ in { Description = "mopidy music player daemon"; Documentation = [ "https://mopidy.com/" ]; After = [ "network.target" "sound.target" ]; + X-Restart-Triggers = mkIf (cfg.settings != { }) + [ "${config.xdg.configFile."mopidy/mopidy.conf".source}" ]; }; Service = { ExecStart = "${mopidyEnv}/bin/mopidy --config ${configFilePaths}"; + Restart = "on-failure"; }; Install.WantedBy = [ "default.target" ]; diff --git a/modules/services/mpd-discord-rpc.nix b/modules/services/mpd-discord-rpc.nix index 8996051a5..dfe408921 100644 --- a/modules/services/mpd-discord-rpc.nix +++ b/modules/services/mpd-discord-rpc.nix @@ -50,7 +50,7 @@ in { Unit = { Description = "Discord Rich Presence for MPD"; Documentation = "https://github.com/JakeStanger/mpd-discord-rpc"; - After = [ "graphical-session-pre.target" ]; + After = [ "graphical-session.target" ]; PartOf = [ "graphical-session.target" ]; }; Service = { diff --git a/modules/services/mpd.nix b/modules/services/mpd.nix index 8787ad667..a1df5640a 100644 --- a/modules/services/mpd.nix +++ b/modules/services/mpd.nix @@ -1,38 +1,11 @@ { config, lib, pkgs, ... }: - -with lib; - let - - name = "mpd"; + inherit (lib) mkIf mkOption types; cfg = config.services.mpd; - - mpdConf = pkgs.writeText "mpd.conf" '' - music_directory "${cfg.musicDirectory}" - playlist_directory "${cfg.playlistDirectory}" - ${lib.optionalString (cfg.dbFile != null) '' - db_file "${cfg.dbFile}" - ''} - state_file "${cfg.dataDir}/state" - sticker_file "${cfg.dataDir}/sticker.sql" - - ${optionalString (cfg.network.listenAddress != "any") - ''bind_to_address "${cfg.network.listenAddress}"''} - ${optionalString (cfg.network.port != 6600) - ''port "${toString cfg.network.port}"''} - - ${cfg.extraConfig} - ''; - in { - - ###### interface - options = { - services.mpd = { - enable = mkOption { type = types.bool; default = false; @@ -52,7 +25,7 @@ in { musicDirectory = mkOption { type = with types; either path str; - defaultText = literalExpression '' + defaultText = lib.literalExpression '' ''${home.homeDirectory}/music if state version < 22.11 ''${xdg.userDirs.music} if xdg.userDirs.enable == true undefined otherwise @@ -100,7 +73,7 @@ in { dataDir = mkOption { type = types.path; - default = "${config.xdg.dataHome}/${name}"; + default = "${config.xdg.dataHome}/mpd"; defaultText = "$XDG_DATA_HOME/mpd"; apply = toString; # Prevent copies to Nix store. description = '' @@ -113,8 +86,10 @@ in { startWhenNeeded = mkOption { type = types.bool; default = false; + visible = pkgs.stdenv.hostPlatform.isLinux; + readOnly = pkgs.stdenv.hostPlatform.isDarwin; description = '' - Enable systemd socket activation. + Enable systemd socket activation. This is only supported on Linux. ''; }; @@ -149,72 +124,97 @@ in { ''; }; }; - }; - ###### implementation + config = let + mpdConf = pkgs.writeText "mpd.conf" ('' + music_directory "${cfg.musicDirectory}" + playlist_directory "${cfg.playlistDirectory}" + '' + lib.optionalString (cfg.dbFile != null) '' + db_file "${cfg.dbFile}" + '' + lib.optionalString (pkgs.stdenv.hostPlatform.isDarwin) '' + log_file "${config.home.homeDirectory}/Library/Logs/mpd/log.txt" + '' + '' + state_file "${cfg.dataDir}/state" + sticker_file "${cfg.dataDir}/sticker.sql" - config = mkIf cfg.enable { - assertions = [ - (lib.hm.assertions.assertPlatform "services.mpd" pkgs lib.platforms.linux) - ]; + '' + lib.optionalString (cfg.network.listenAddress != "any") '' + bind_to_address "${cfg.network.listenAddress}" + '' + lib.optionalString (cfg.network.port != 6600) '' + port "${toString cfg.network.port}" + '' + lib.optionalString (cfg.extraConfig != "") '' + ${cfg.extraConfig} + ''); + in mkIf cfg.enable { + home.packages = [ cfg.package ]; - services.mpd = mkMerge [ - (mkIf (versionAtLeast config.home.stateVersion "22.11" + services.mpd = lib.mkMerge [ + (mkIf (lib.versionAtLeast config.home.stateVersion "22.11" && config.xdg.userDirs.enable) { - musicDirectory = mkOptionDefault config.xdg.userDirs.music; + musicDirectory = lib.mkOptionDefault config.xdg.userDirs.music; }) - (mkIf (versionOlder config.home.stateVersion "22.11") { - musicDirectory = mkOptionDefault "${config.home.homeDirectory}/music"; + (mkIf (lib.versionOlder config.home.stateVersion "22.11") { + musicDirectory = + lib.mkOptionDefault "${config.home.homeDirectory}/music"; }) ]; - systemd.user.services.mpd = { - Unit = mkMerge [ - { - Description = "Music Player Daemon"; - After = [ "network.target" "sound.target" ]; - } + systemd.user = lib.mkIf pkgs.stdenv.hostPlatform.isLinux { + services.mpd = { + Unit = lib.mkMerge [ + { + Description = "Music Player Daemon"; + After = [ "network.target" "sound.target" ]; + } - (mkIf cfg.network.startWhenNeeded { - Requires = [ "mpd.socket" ]; - After = [ "mpd.socket" ]; - }) - ]; + (mkIf cfg.network.startWhenNeeded { + Requires = [ "mpd.socket" ]; + After = [ "mpd.socket" ]; + }) + ]; - Install = mkIf (!cfg.network.startWhenNeeded) { - WantedBy = [ "default.target" ]; + Install = mkIf (!cfg.network.startWhenNeeded) { + WantedBy = [ "default.target" ]; + }; + + Service = { + Environment = [ "PATH=${config.home.profileDirectory}/bin" ]; + ExecStart = "${cfg.package}/bin/mpd --no-daemon ${mpdConf} ${ + lib.escapeShellArgs cfg.extraArgs + }"; + Type = "notify"; + ExecStartPre = '' + ${pkgs.bash}/bin/bash -c "${pkgs.coreutils}/bin/mkdir -p '${cfg.dataDir}' '${cfg.playlistDirectory}'"''; + }; }; - Service = { - Environment = [ "PATH=${config.home.profileDirectory}/bin" ]; - ExecStart = "${cfg.package}/bin/mpd --no-daemon ${mpdConf} ${ - escapeShellArgs cfg.extraArgs - }"; - Type = "notify"; - ExecStartPre = '' - ${pkgs.bash}/bin/bash -c "${pkgs.coreutils}/bin/mkdir -p '${cfg.dataDir}' '${cfg.playlistDirectory}'"''; + sockets.mpd = mkIf cfg.network.startWhenNeeded { + Socket = { + ListenStream = let + listen = if cfg.network.listenAddress == "any" then + toString cfg.network.port + else + "${cfg.network.listenAddress}:${toString cfg.network.port}"; + in [ listen "%t/mpd/socket" ]; + + Backlog = 5; + KeepAlive = true; + }; + + Install = { WantedBy = [ "sockets.target" ]; }; }; }; - systemd.user.sockets.mpd = mkIf cfg.network.startWhenNeeded { - Socket = { - ListenStream = let - listen = if cfg.network.listenAddress == "any" then - toString cfg.network.port - else - "${cfg.network.listenAddress}:${toString cfg.network.port}"; - in [ listen "%t/mpd/socket" ]; - - Backlog = 5; + launchd.agents.mpd = lib.mkIf pkgs.stdenv.hostPlatform.isDarwin { + enable = true; + config = { + ProgramArguments = + [ (lib.getExe cfg.package) "--no-daemon" "${mpdConf}" ] + ++ cfg.extraArgs; KeepAlive = true; + ProcessType = "Interactive"; }; - - Install = { WantedBy = [ "sockets.target" ]; }; }; - - home.packages = [ cfg.package ]; }; - } diff --git a/modules/services/muchsync.nix b/modules/services/muchsync.nix index d4fcd864f..1357cbcd4 100644 --- a/modules/services/muchsync.nix +++ b/modules/services/muchsync.nix @@ -126,7 +126,7 @@ let }; in { - meta.maintainers = with maintainers; [ pacien ]; + meta.maintainers = with maintainers; [ euxane ]; options.services.muchsync = { remotes = mkOption { diff --git a/modules/services/network-manager-applet.nix b/modules/services/network-manager-applet.nix index 524921b71..8738cae66 100644 --- a/modules/services/network-manager-applet.nix +++ b/modules/services/network-manager-applet.nix @@ -7,11 +7,11 @@ let cfg = config.services.network-manager-applet; in { - meta.maintainers = [ maintainers.rycee hm.maintainers.cvoges12 ]; + meta.maintainers = [ maintainers.rycee maintainers.midirhee12 ]; options = { services.network-manager-applet = { - enable = mkEnableOption "the Network Manager applet"; + enable = mkEnableOption "the Network Manager applet (nm-applet)"; }; }; @@ -28,7 +28,7 @@ in { Unit = { Description = "Network Manager applet"; Requires = [ "tray.target" ]; - After = [ "graphical-session-pre.target" "tray.target" ]; + After = [ "graphical-session.target" "tray.target" ]; PartOf = [ "graphical-session.target" ]; }; diff --git a/modules/services/nextcloud-client.nix b/modules/services/nextcloud-client.nix index 24b3c99dd..7a3ceacb1 100644 --- a/modules/services/nextcloud-client.nix +++ b/modules/services/nextcloud-client.nix @@ -36,7 +36,7 @@ in { systemd.user.services.nextcloud-client = { Unit = { Description = "Nextcloud Client"; - After = [ "graphical-session-pre.target" ]; + After = [ "graphical-session.target" ]; PartOf = [ "graphical-session.target" ]; }; diff --git a/modules/services/nix-gc.nix b/modules/services/nix-gc.nix index 50e8b6351..7789aeffb 100644 --- a/modules/services/nix-gc.nix +++ b/modules/services/nix-gc.nix @@ -81,6 +81,18 @@ in { ''; }; + randomizedDelaySec = lib.mkOption { + default = "0"; + type = lib.types.singleLineStr; + example = "45min"; + description = '' + Add a randomized delay before each garbage collection. + The delay will be chosen between zero and this value. + This value must be a time span in the format specified by + {manpage}`systemd.time(7)` + ''; + }; + options = mkOption { type = types.nullOr types.str; default = null; @@ -121,6 +133,7 @@ in { Unit = { Description = "Nix Garbage Collector"; }; Timer = { OnCalendar = "${cfg.frequency}"; + RandomizedDelaySec = cfg.randomizedDelaySec; Persistent = cfg.persistent; Unit = "nix-gc.service"; }; diff --git a/modules/services/notify-osd.nix b/modules/services/notify-osd.nix index 4faf83643..b118a275e 100644 --- a/modules/services/notify-osd.nix +++ b/modules/services/notify-osd.nix @@ -33,7 +33,7 @@ in { systemd.user.services.notify-osd = { Unit = { Description = "notify-osd"; - After = [ "graphical-session-pre.target" ]; + After = [ "graphical-session.target" ]; PartOf = [ "graphical-session.target" ]; }; diff --git a/modules/services/ollama.nix b/modules/services/ollama.nix new file mode 100644 index 000000000..0cb1b2eee --- /dev/null +++ b/modules/services/ollama.nix @@ -0,0 +1,112 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + cfg = config.services.ollama; + + ollamaPackage = if cfg.acceleration == null then + cfg.package + else + cfg.package.override { inherit (cfg) acceleration; }; + +in { + meta.maintainers = [ maintainers.terlar ]; + + options = { + services.ollama = { + enable = mkEnableOption "ollama server for local large language models"; + + package = mkPackageOption pkgs "ollama" { }; + + host = mkOption { + type = types.str; + default = "127.0.0.1"; + example = "[::]"; + description = '' + The host address which the ollama server HTTP interface listens to. + ''; + }; + + port = mkOption { + type = types.port; + default = 11434; + example = 11111; + description = '' + Which port the ollama server listens to. + ''; + }; + + acceleration = mkOption { + type = types.nullOr (types.enum [ false "rocm" "cuda" ]); + default = null; + example = "rocm"; + description = '' + What interface to use for hardware acceleration. + + - `null`: default behavior + - if `nixpkgs.config.rocmSupport` is enabled, uses `"rocm"` + - if `nixpkgs.config.cudaSupport` is enabled, uses `"cuda"` + - otherwise defaults to `false` + - `false`: disable GPU, only use CPU + - `"rocm"`: supported by most modern AMD GPUs + - may require overriding gpu type with `services.ollama.rocmOverrideGfx` + if rocm doesn't detect your AMD gpu + - `"cuda"`: supported by most modern NVIDIA GPUs + ''; + }; + + environmentVariables = mkOption { + type = types.attrsOf types.str; + default = { }; + example = { + OLLAMA_LLM_LIBRARY = "cpu"; + HIP_VISIBLE_DEVICES = "0,1"; + }; + description = '' + Set arbitrary environment variables for the ollama service. + + Be aware that these are only seen by the ollama server (systemd service), + not normal invocations like `ollama run`. + Since `ollama run` is mostly a shell around the ollama server, this is usually sufficient. + ''; + }; + }; + }; + + config = mkIf cfg.enable { + systemd.user.services.ollama = mkIf pkgs.stdenv.isLinux { + Unit = { + Description = "Server for local large language models"; + After = [ "network.target" ]; + }; + + Service = { + ExecStart = "${getExe ollamaPackage} serve"; + Environment = + (mapAttrsToList (n: v: "${n}=${v}") cfg.environmentVariables) + ++ [ "OLLAMA_HOST=${cfg.host}:${toString cfg.port}" ]; + }; + + Install = { WantedBy = [ "default.target" ]; }; + }; + + launchd.agents.ollama = mkIf pkgs.stdenv.isDarwin { + enable = true; + config = { + ProgramArguments = [ "${getExe ollamaPackage}" "serve" ]; + EnvironmentVariables = cfg.environmentVariables // { + OLLAMA_HOST = "${cfg.host}:${toString cfg.port}"; + }; + KeepAlive = { + Crashed = true; + SuccessfulExit = false; + }; + ProcessType = "Background"; + }; + }; + + home.packages = [ ollamaPackage ]; + }; +} diff --git a/modules/services/opensnitch-ui.nix b/modules/services/opensnitch-ui.nix index f45ee9cdb..a6df254f5 100644 --- a/modules/services/opensnitch-ui.nix +++ b/modules/services/opensnitch-ui.nix @@ -23,7 +23,7 @@ in { systemd.user.services.opensnitch-ui = { Unit = { Description = "Opensnitch ui"; - After = [ "graphical-session-pre.target" ]; + After = [ "graphical-session.target" ]; PartOf = [ "graphical-session.target" ]; }; diff --git a/modules/services/owncloud-client.nix b/modules/services/owncloud-client.nix index 3235dac9c..aad2d487c 100644 --- a/modules/services/owncloud-client.nix +++ b/modules/services/owncloud-client.nix @@ -24,7 +24,7 @@ in { systemd.user.services.owncloud-client = { Unit = { Description = "Owncloud Client"; - After = [ "graphical-session-pre.target" ]; + After = [ "graphical-session.target" ]; PartOf = [ "graphical-session.target" ]; }; diff --git a/modules/services/parcellite.nix b/modules/services/parcellite.nix index 39b81e869..dc6b84c41 100644 --- a/modules/services/parcellite.nix +++ b/modules/services/parcellite.nix @@ -42,7 +42,7 @@ in { Unit = { Description = "Lightweight GTK+ clipboard manager"; Requires = [ "tray.target" ]; - After = [ "graphical-session-pre.target" "tray.target" ]; + After = [ "graphical-session.target" "tray.target" ]; PartOf = [ "graphical-session.target" ]; }; diff --git a/modules/services/pasystray.nix b/modules/services/pasystray.nix index 4ea340d21..62e203584 100644 --- a/modules/services/pasystray.nix +++ b/modules/services/pasystray.nix @@ -30,7 +30,7 @@ in { Unit = { Description = "PulseAudio system tray"; Requires = [ "tray.target" ]; - After = [ "graphical-session-pre.target" "tray.target" ]; + After = [ "graphical-session.target" "tray.target" ]; PartOf = [ "graphical-session.target" ]; }; diff --git a/modules/services/pbgopy.nix b/modules/services/pbgopy.nix index 3a3499e52..48556a5ba 100644 --- a/modules/services/pbgopy.nix +++ b/modules/services/pbgopy.nix @@ -60,7 +60,7 @@ in { systemd.user.services.pbgopy = { Unit = { Description = "pbgopy server for sharing the clipboard between devices"; - After = [ "graphical-session-pre.target" ]; + After = [ "graphical-session.target" ]; PartOf = [ "graphical-session.target" ]; }; Service = { diff --git a/modules/services/picom.nix b/modules/services/picom.nix index 1d9b7bb55..59e373a62 100644 --- a/modules/services/picom.nix +++ b/modules/services/picom.nix @@ -310,7 +310,7 @@ in { systemd.user.services.picom = { Unit = { Description = "Picom X11 compositor"; - After = [ "graphical-session-pre.target" ]; + After = [ "graphical-session.target" ]; PartOf = [ "graphical-session.target" ]; }; diff --git a/modules/services/plex-mpv-shim.nix b/modules/services/plex-mpv-shim.nix index 940e57184..795827c40 100644 --- a/modules/services/plex-mpv-shim.nix +++ b/modules/services/plex-mpv-shim.nix @@ -58,7 +58,7 @@ in { systemd.user.services.plex-mpv-shim = { Unit = { Description = "Plex mpv shim"; - After = [ "graphical-session-pre.target" ]; + After = [ "graphical-session.target" ]; PartOf = [ "graphical-session.target" ]; }; diff --git a/modules/services/podman-linux/activation.nix b/modules/services/podman-linux/activation.nix new file mode 100644 index 000000000..205b6651e --- /dev/null +++ b/modules/services/podman-linux/activation.nix @@ -0,0 +1,102 @@ +{ config, podman-lib, ... }: + +{ + cleanup = '' + PATH=$PATH:${podman-lib.newuidmapPaths} + export VERBOSE=true + + DRYRUN_ENABLED() { + return $([ -n "''${DRY_RUN:-}" ] && echo 0 || echo 1) + } + + VERBOSE_ENABLED() { + return $([ -n "''${VERBOSE:-}" ] && echo 0 || echo 1) + } + + cleanup() { + local resourceType=$1 + local manifestFile="${config.xdg.configHome}/podman/$2" + local extraListCommands="''${3:-}" + [[ $resourceType = "container" ]] && extraListCommands+=" -a" + [[ $resourceType = "volume" ]] && extraListCommands+=" --filter label=nix.home-manager.preserve=false" + + [ ! -f "$manifestFile" ] && VERBOSE_ENABLED && echo "Manifest does not exist: $manifestFile" && return 0 + + VERBOSE_ENABLED && echo "Cleaning up ''${resourceType}s not in manifest..." || true + + loadManifest "$manifestFile" + + formatString="{{.Name}}" + [[ $resourceType = "container" ]] && formatString="{{.Names}}" + [[ $resourceType = "image" ]] && formatString="{{.Repository}}" + + local listOutput=$(${config.services.podman.package}/bin/podman $resourceType ls $extraListCommands --filter 'label=nix.home-manager.managed=true' --format "$formatString") + + IFS=$'\n' read -r -d "" -a podmanResources <<< "$listOutput" || true + + if [ ''${#podmanResources[@]} -eq 0 ]; then + VERBOSE_ENABLED && echo "No ''${resourceType}s available to process." || true + else + for resource in "''${podmanResources[@]}"; do + if ! isResourceInManifest "$resource"; then + removeResource "$resourceType" "$resource" + else + VERBOSE_ENABLED && echo "Keeping managed $resourceType: $resource" || true + fi + done + fi + } + + isResourceInManifest() { + local resource="$1" + for manifestEntry in "''${resourceManifest[@]}"; do + if [ "$resource" = "$manifestEntry" ]; then + return 0 # Resource found in manifest + fi + done + return 1 # Resource not found in manifest + } + + # Function to fill resourceManifest from the manifest file + loadManifest() { + local manifestFile="$1" + VERBOSE_ENABLED && echo "Loading manifest from $manifestFile..." || true + IFS=$'\n' read -r -d "" -a resourceManifest <<< "$(cat "$manifestFile")" || true + } + + removeResource() { + local resourceType="$1" + local resource="$2" + echo "Removing orphaned $resourceType: $resource" + commands=() + case "$resourceType" in + "container") + commands+=("${config.services.podman.package}/bin/podman $resourceType stop $resource") + commands+=("${config.services.podman.package}/bin/podman $resourceType rm -f $resource") + ;; + "image" | "network" | "volume") + commands+=("${config.services.podman.package}/bin/podman $resourceType rm $resource") + ;; + esac + for command in "''${commands[@]}"; do + command=$(echo $command | tr -d ';&|`') + DRYRUN_ENABLED && echo "Would run: $command" && continue || true + VERBOSE_ENABLED && echo "Running: $command" || true + if [[ "$(eval "$command")" != *"$resource" ]]; then + echo -e "\tCommand failed: ''${command}" + [ "$resourceType" == "image" ] && resourceType="ancestor" + usedByContainers=$(${config.services.podman.package}/bin/podman container ls -a --filter "$resourceType=$resource" --format "{{.Names}}") + echo -e "\t$resource in use by containers: $usedByContainers" + fi + done + } + + resourceManifest=() + [[ "$@" == *"--verbose"* ]] && VERBOSE="true" + [[ "$@" == *"--dry-run"* ]] && DRY_RUN="true" + + for type in "container" "image" "network" "volume"; do + cleanup "$type" "''${type}s.manifest" + done + ''; +} diff --git a/modules/services/podman-linux/builds.nix b/modules/services/podman-linux/builds.nix new file mode 100644 index 000000000..937a206b0 --- /dev/null +++ b/modules/services/podman-linux/builds.nix @@ -0,0 +1,168 @@ +{ config, lib, pkgs, ... }: +with lib; +let + cfg = config.services.podman; + + podman-lib = import ./podman-lib.nix { inherit pkgs lib config; }; + + createQuadletSource = name: buildDef: + let + buildConfig = podman-lib.deepMerge { + Build = { + AuthFile = buildDef.authFile; + Environment = buildDef.environment; + File = buildDef.file; + ImageTag = [ "homemanager/${name}" ] ++ buildDef.tags; + Label = buildDef.labels // { "nix.home-manager.managed" = true; }; + PodmanArgs = buildDef.extraPodmanArgs; + SetWorkingDirectory = buildDef.workingDirectory; + TLSVerify = buildDef.tlsVerify; + }; + Install = { + WantedBy = optionals buildDef.autoStart [ + "default.target" + "multi-user.target" + ]; + }; + Service = { + TimeoutStartSec = 300; + RemainAfterExit = "yes"; + }; + Unit = { Description = buildDef.description; }; + } buildDef.extraConfig; + in '' + # Automatically generated by home-manager for podman build configuration + # DO NOT EDIT THIS FILE DIRECTLY + # + # ${name}.build + ${podman-lib.toQuadletIni buildConfig} + ''; + + toQuadletInternal = name: buildDef: { + assertions = podman-lib.buildConfigAsserts name buildDef.extraConfig; + serviceName = + "podman-${name}"; # quadlet service name: 'podman--build.service + source = podman-lib.removeBlankLines (createQuadletSource name buildDef); + resourceType = "build"; + }; +in let + buildDefinitionType = types.submodule ({ name, ... }: { + options = { + + autoStart = mkOption { + type = types.bool; + default = true; + description = + "Whether to start the build on boot. Requires user lingering."; + }; + + authFile = mkOption { + type = with types; nullOr path; + default = null; + description = "Path of the authentication file."; + }; + + description = mkOption { + type = with types; nullOr str; + default = "Service for build ${name}"; + defaultText = "Service for build \${name}"; + example = "My Build"; + description = "The description of the build."; + }; + + environment = mkOption { + type = podman-lib.primitiveAttrs; + default = { }; + example = literalExpression '' + { + VAR1 = "0:100"; + VAR2 = true; + VAR3 = 5; + } + ''; + description = "Environment variables to set in the build."; + }; + + extraConfig = mkOption { + type = podman-lib.extraConfigType; + default = { }; + example = literalExpression '' + { + Build = { + Arch = "aarch64"; + }; + Service = { + TimeoutStartSec = 15; + }; + } + ''; + description = "INI sections and values to populate the Build Quadlet."; + }; + + extraPodmanArgs = mkOption { + type = types.listOf types.str; + default = [ ]; + example = [ "--retries 5" ]; + description = "Extra arguments to pass to the podman build command."; + }; + + file = mkOption { + type = types.str; + example = literalExpression '' + `"xdg.configFile."containerfiles/my-img/Containerfile"` + or + `"https://github.com/.../my-img/Containerfile"` + ''; + description = + "Path to a Containerfile which contains instructions to build the image."; + }; + + tags = mkOption { + type = with types; listOf str; + default = [ ]; + description = '' + Name associated with the build. + First tag will always be "homemanager/". + ''; + }; + + labels = mkOption { + type = with types; attrsOf str; + default = { }; + example = { + app = "myapp"; + some-label = "somelabel"; + }; + description = "The labels to apply to the build."; + }; + + tlsVerify = mkOption { + type = types.bool; + default = true; + description = + "Require HTTPS and verification of certificates when contacting registries."; + }; + + workingDirectory = mkOption { + type = with types; nullOr path; + default = null; + description = "WorkingDirectory of the systemd unit file."; + }; + }; + }); +in { + options.services.podman.builds = mkOption { + type = types.attrsOf buildDefinitionType; + default = { }; + description = "Defines Podman build quadlet configurations."; + }; + + config = let buildQuadlets = mapAttrsToList toQuadletInternal cfg.builds; + in mkIf cfg.enable { + services.podman.internal.quadletDefinitions = buildQuadlets; + assertions = flatten (map (build: build.assertions) buildQuadlets); + + xdg.configFile."podman/images.manifest".text = + podman-lib.generateManifestText buildQuadlets; + }; +} diff --git a/modules/services/podman-linux/containers.nix b/modules/services/podman-linux/containers.nix new file mode 100644 index 000000000..d5836119a --- /dev/null +++ b/modules/services/podman-linux/containers.nix @@ -0,0 +1,348 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.services.podman; + + podman-lib = import ./podman-lib.nix { inherit pkgs lib config; }; + + createQuadletSource = name: containerDef: + let + formatServiceNameForType = type: name: + { + image = "podman-${name}-image.service"; + build = "podman-${name}-build.service"; + network = "podman-${name}-network.service"; + volume = "podman-${name}-volume.service"; + }."${type}"; + + dependencyByHomeManagerQuadlet = type: name: + let + definitionsOfType = + filter (q: q.resourceType == type) cfg.internal.quadletDefinitions; + matchingName = + filter (q: q.serviceName == "podman-${name}") definitionsOfType; + in if ((length matchingName) == 1) then + [ (formatServiceNameForType type name) ] + else + [ ]; + + forEachValue = type: value: + let resolve = v: dependencyByHomeManagerQuadlet type v; + in if isList value then + concatLists (map resolve value) + else + resolve value; + + withResolverFor = type: value: + { + "image" = forEachValue "image" value; + "build" = forEachValue "build" value; + "network" = forEachValue "network" value; + "volume" = let + a = if isList value then value else [ value ]; + volumes = map (v: elemAt (splitString ":" v) 0) a; + in forEachValue "volume" volumes; + }.${type}; + + dependencyServices = (withResolverFor "image" containerDef.image) + ++ (withResolverFor "build" containerDef.image) + ++ (withResolverFor "network" containerDef.network) + ++ (withResolverFor "volume" containerDef.volumes); + + resolvedImage = if (builtins.hasAttr containerDef.image cfg.images) then + cfg.images."${containerDef.image}".image + else if (builtins.hasAttr containerDef.image cfg.builds) then + "localhost/homemanager/${containerDef.image}" + else + containerDef.image; + + quadlet = (podman-lib.deepMerge { + Container = { + AddCapability = containerDef.addCapabilities; + AddDevice = containerDef.devices; + AutoUpdate = containerDef.autoUpdate; + ContainerName = name; + DropCapability = containerDef.dropCapabilities; + Entrypoint = containerDef.entrypoint; + Environment = containerDef.environment; + EnvironmentFile = containerDef.environmentFile; + Exec = containerDef.exec; + Group = containerDef.group; + Image = resolvedImage; + IP = containerDef.ip4; + IP6 = containerDef.ip6; + Label = + (containerDef.labels // { "nix.home-manager.managed" = true; }); + Network = containerDef.network; + NetworkAlias = containerDef.networkAlias; + PodmanArgs = containerDef.extraPodmanArgs; + PublishPort = containerDef.ports; + UserNS = containerDef.userNS; + User = containerDef.user; + Volume = containerDef.volumes; + }; + Install = { + WantedBy = optionals containerDef.autoStart [ + "default.target" + "multi-user.target" + ]; + }; + Service = { + Environment = { + PATH = (builtins.concatStringsSep ":" [ + "/run/wrappers/bin" + "/run/current-system/sw/bin" + "${config.home.homeDirectory}/.nix-profile/bin" + ]); + }; + Restart = "always"; + TimeoutStopSec = 30; + }; + Unit = { + After = dependencyServices; + Requires = dependencyServices; + Description = (if (builtins.isString containerDef.description) then + containerDef.description + else + "Service for container ${name}"); + }; + } containerDef.extraConfig); + in '' + # Automatically generated by home-manager podman container configuration + # DO NOT EDIT THIS FILE DIRECTLY + # + # ${name}.container + ${podman-lib.toQuadletIni quadlet} + ''; + + toQuadletInternal = name: containerDef: { + assertions = podman-lib.buildConfigAsserts name containerDef.extraConfig; + resourceType = "container"; + serviceName = + "podman-${name}"; # quadlet service name: 'podman-.service' + source = + podman-lib.removeBlankLines (createQuadletSource name containerDef); + }; + + # Define the container user type as the user interface + containerDefinitionType = types.submodule { + options = { + + addCapabilities = mkOption { + type = with types; listOf str; + default = [ ]; + example = [ "CAP_DAC_OVERRIDE" "CAP_IPC_OWNER" ]; + description = "The capabilities to add to the container."; + }; + + autoStart = mkOption { + type = types.bool; + default = true; + description = '' + Whether to start the container on boot (requires user lingering). + ''; + }; + + autoUpdate = mkOption { + type = types.enum [ null "registry" "local" ]; + default = null; + example = "registry"; + description = "The autoupdate policy for the container."; + }; + + description = mkOption { + type = with types; nullOr str; + default = null; + example = "My Container"; + description = "The description of the container."; + }; + + devices = mkOption { + type = with types; listOf str; + default = [ ]; + example = [ "/dev/:/dev/" ]; + description = "The devices to mount into the container"; + }; + + dropCapabilities = mkOption { + type = with types; listOf str; + default = [ ]; + example = [ "CAP_DAC_OVERRIDE" "CAP_IPC_OWNER" ]; + description = "The capabilities to drop from the container."; + }; + + entrypoint = mkOption { + type = with types; nullOr str; + default = null; + example = "/foo.sh"; + description = "The container entrypoint."; + }; + + environment = mkOption { + type = podman-lib.primitiveAttrs; + default = { }; + example = literalExpression '' + { + VAR1 = "0:100"; + VAR2 = true; + VAR3 = 5; + } + ''; + description = "Environment variables to set in the container."; + }; + + environmentFile = mkOption { + type = with types; listOf str; + default = [ ]; + example = [ "/etc/environment" "/etc/other-env" ]; + description = '' + Paths to files containing container environment variables. + ''; + }; + + exec = mkOption { + type = with types; nullOr str; + default = null; + example = "sleep inf"; + description = "The command to run after the container start."; + }; + + extraPodmanArgs = mkOption { + type = types.listOf types.str; + default = [ ]; + example = [ + "--security-opt=no-new-privileges" + "--security-opt=seccomp=unconfined" + ]; + description = "Extra arguments to pass to the podman run command."; + }; + + extraConfig = mkOption { + type = podman-lib.extraConfigType; + default = { }; + example = literalExpression '' + { + Container = { + User = 1000; + }; + Service = { + TimeoutStartSec = 15; + }; + } + ''; + description = '' + INI sections and values to populate the Container Quadlet. + ''; + }; + + group = mkOption { + type = with types; nullOr (either int str); + default = null; + description = "The group ID inside the container."; + }; + + image = mkOption { + type = types.str; + example = "registry.access.redhat.com/ubi9-minimal:latest"; + description = "The container image."; + }; + + ip4 = mkOption { + type = with types; nullOr str; + default = null; + description = "Set an IPv4 address for the container."; + }; + + ip6 = mkOption { + type = with types; nullOr str; + default = null; + description = "Set an IPv6 address for the container."; + }; + + labels = mkOption { + type = with types; attrsOf str; + default = { }; + example = { + app = "myapp"; + some-label = "somelabel"; + }; + description = "The labels to apply to the container."; + }; + + network = mkOption { + type = with types; either str (listOf str); + default = [ ]; + apply = value: if isString value then [ value ] else value; + example = literalMD '' + `"host"` + or + `"bridge_network_1"` + or + `[ "bridge_network_1" "bridge_network_2" ]` + ''; + description = '' + The network mode or network/s to connect the container to. Equivalent + to `podman run --network=