Compare commits
83 commits
984708c34d
...
436b27742c
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
436b27742c | ||
|
|
a913ae61bf | ||
|
|
c9507a9aa5 | ||
|
|
168fbe8891 | ||
|
|
1dcebb44c6 | ||
|
|
8b6212ebd6 | ||
|
|
91be7cce76 | ||
|
|
167e0b6837 | ||
|
|
a0a01d8811 | ||
|
|
2dedeb55b2 | ||
|
|
f19a99503c | ||
|
|
0f156f177d | ||
|
|
8e0f4cdeee | ||
|
|
f1ebddedab | ||
|
|
b3ccd4bb26 | ||
|
|
77c47a4542 | ||
|
|
4ebb171bc5 | ||
|
|
30f54c7014 | ||
|
|
671ba1f70e | ||
|
|
f71fa310cf | ||
|
|
bfc89f1936 | ||
|
|
b0d7d25a46 | ||
|
|
b0b01ab65b | ||
|
|
5f1d42a97b | ||
|
|
c7d7ba954a | ||
|
|
ae8003d8b6 | ||
|
|
1e53254671 | ||
|
|
ee49ee29a1 | ||
|
|
ff5e5d882c | ||
|
|
05e6dc0f6e | ||
|
|
26dfad95d9 | ||
|
|
b3258dece8 | ||
|
|
e9b706bef7 | ||
|
|
cadfe449aa | ||
|
|
bc5652b227 | ||
|
|
29d617ecc8 | ||
|
|
4c4771cb01 | ||
|
|
3017414609 | ||
|
|
54ab8bc155 | ||
|
|
975606b2a5 | ||
|
|
5e90b62996 | ||
|
|
de4cfffc98 | ||
|
|
a6c93262f3 | ||
|
|
f24a755980 | ||
|
|
2fe1e0ea38 | ||
|
|
133585ddfa | ||
|
|
9bdb693810 | ||
|
|
258db1d39b | ||
|
|
2cc195b478 | ||
|
|
6a1f7101d2 | ||
|
|
ede6d1d95e | ||
|
|
2363f5a377 | ||
|
|
0825a0922a | ||
|
|
0acbd11806 | ||
|
|
b3f43db171 | ||
|
|
6c4fdbe1ad | ||
|
|
13a1beb7c9 | ||
|
|
6c8def1df8 | ||
|
|
b1f916ba05 | ||
|
|
a0da0f24fd | ||
|
|
afaa85cf32 | ||
|
|
42c607ecb4 | ||
|
|
f5d50fd8cb | ||
|
|
cbd8a72e5f | ||
|
|
6cee082157 | ||
|
|
471e6a065f | ||
|
|
f915881ba7 | ||
|
|
332027bc0a | ||
|
|
bbccee8713 | ||
|
|
04e5203db6 | ||
|
|
6f64dee491 | ||
|
|
cfb3b544f9 | ||
|
|
715e6d7f89 | ||
|
|
6c79e409a5 | ||
|
|
c8f9edda94 | ||
|
|
9b62076484 | ||
|
|
db9044b119 | ||
|
|
83cc9d32e3 | ||
|
|
7c47cafa90 | ||
|
|
689e4a3423 | ||
|
|
4fda26500b | ||
|
|
83e4f9b4d2 | ||
|
|
36349274d7 |
145 changed files with 2709 additions and 427 deletions
|
|
@ -50,7 +50,7 @@
|
|||
source = "nixpkgs";
|
||||
};
|
||||
ALameLlama = {
|
||||
email = "NicholasACiechanowski@gmail.com";
|
||||
email = "nicholas@ciech.anow.ski";
|
||||
github = "ALameLlama";
|
||||
githubId = 55490546;
|
||||
name = "Nicholas Ciechanowski";
|
||||
|
|
@ -1538,6 +1538,12 @@
|
|||
name = "Lukas Nagel";
|
||||
source = "home-manager";
|
||||
};
|
||||
magicquark = {
|
||||
github = "magicquark";
|
||||
githubId = 198001825;
|
||||
name = "magicquark";
|
||||
source = "nixpkgs";
|
||||
};
|
||||
mainrs = {
|
||||
email = "5113257+mainrs@users.noreply.github.com";
|
||||
github = "mainrs";
|
||||
|
|
@ -1545,6 +1551,18 @@
|
|||
name = "mainrs";
|
||||
source = "home-manager";
|
||||
};
|
||||
malikwirin = {
|
||||
email = "abdelmalik.najhi@stud.hs-kempten.de";
|
||||
github = "malikwirin";
|
||||
githubId = 117918464;
|
||||
keys = [
|
||||
{
|
||||
fingerprint = "B5ED 595C 8C7E 133C 6B68 63C8 CFEF 1E35 0351 F72D";
|
||||
}
|
||||
];
|
||||
name = "Malik";
|
||||
source = "nixpkgs";
|
||||
};
|
||||
malte-v = {
|
||||
email = "nixpkgs@mal.tc";
|
||||
github = "malte-v";
|
||||
|
|
@ -1634,6 +1652,13 @@
|
|||
name = "Shahar \"Dawn\" Or";
|
||||
source = "nixpkgs";
|
||||
};
|
||||
mikaeladev = {
|
||||
email = "mikaeladev@users.noreply.github.com";
|
||||
github = "mikaeladev";
|
||||
githubId = 100416544;
|
||||
name = "mikaeladev";
|
||||
source = "home-manager";
|
||||
};
|
||||
mikilio = {
|
||||
email = "official.mikilio+dev@gmail.com";
|
||||
github = "mikilio";
|
||||
|
|
@ -1814,13 +1839,6 @@
|
|||
name = "Judson Lester";
|
||||
source = "nixpkgs";
|
||||
};
|
||||
offlinehacker = {
|
||||
email = "jaka@x-truder.net";
|
||||
github = "offlinehacker";
|
||||
githubId = 585547;
|
||||
name = "Jaka Hudoklin";
|
||||
source = "nixpkgs";
|
||||
};
|
||||
olmokramer = {
|
||||
email = "olmokramer@users.noreply.github.com";
|
||||
github = "olmokramer";
|
||||
|
|
|
|||
|
|
@ -1,3 +1 @@
|
|||
attribute = "buildbot"
|
||||
flake_dir = "./tests"
|
||||
lock_file = "./flake.lock"
|
||||
|
|
|
|||
|
|
@ -69,6 +69,57 @@ let
|
|||
|
||||
hmPath = toString ./..;
|
||||
|
||||
# Keep submodule option docs visible when wrapped in `either` (and therefore
|
||||
# in `nullOr (either ...)`), which upstream currently omits.
|
||||
docsLib = lib.extend (
|
||||
_self: super:
|
||||
let
|
||||
mergeEitherSubOptions =
|
||||
prefix: leftType: rightType:
|
||||
let
|
||||
getSubOptionsOrEmpty =
|
||||
optionType:
|
||||
let
|
||||
subOptions = optionType.getSubOptions prefix;
|
||||
in
|
||||
if builtins.isAttrs subOptions then subOptions else { };
|
||||
|
||||
mkOptionDecl = options: {
|
||||
_file = "<docs/default.nix>";
|
||||
pos = null;
|
||||
inherit options;
|
||||
};
|
||||
|
||||
optionSets = lib.filter (options: options != { }) [
|
||||
(getSubOptionsOrEmpty leftType)
|
||||
(getSubOptionsOrEmpty rightType)
|
||||
];
|
||||
mergedOptions = lib.foldl' (
|
||||
acc: options:
|
||||
if acc == { } then
|
||||
options
|
||||
else
|
||||
(super.mergeOptionDecls prefix [
|
||||
(mkOptionDecl acc)
|
||||
(mkOptionDecl options)
|
||||
]).options
|
||||
) { } optionSets;
|
||||
in
|
||||
mergedOptions;
|
||||
|
||||
in
|
||||
{
|
||||
types = super.types // {
|
||||
either =
|
||||
leftType: rightType:
|
||||
(super.types.either leftType rightType)
|
||||
// {
|
||||
getSubOptions = prefix: mergeEitherSubOptions prefix leftType rightType;
|
||||
};
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
buildOptionsDocs =
|
||||
args@{
|
||||
modules,
|
||||
|
|
@ -103,7 +154,7 @@ let
|
|||
};
|
||||
|
||||
options =
|
||||
(lib.evalModules {
|
||||
(docsLib.evalModules {
|
||||
modules = modules ++ [ poisonModule ];
|
||||
class = "homeManager";
|
||||
}).options;
|
||||
|
|
@ -141,7 +192,8 @@ let
|
|||
hmOptionsDocs = buildOptionsDocs {
|
||||
modules =
|
||||
import ../modules/modules.nix {
|
||||
inherit lib pkgs;
|
||||
lib = docsLib;
|
||||
inherit pkgs;
|
||||
check = false;
|
||||
}
|
||||
++ [ scrubbedPkgsModule ];
|
||||
|
|
@ -246,4 +298,7 @@ in
|
|||
in
|
||||
builtins.toJSON result.config.meta.maintainers
|
||||
);
|
||||
|
||||
# Unstable, for tests.
|
||||
_internal = { inherit docsLib; };
|
||||
}
|
||||
|
|
|
|||
|
|
@ -217,13 +217,13 @@ and may cause failures. To run against the Nixpkgs from the `flake.lock` file,
|
|||
use instead e.g.
|
||||
|
||||
``` shell
|
||||
$ nix build --reference-lock-file flake.lock --option allow-import-from-derivation false ./tests#test-all
|
||||
$ nix build --option allow-import-from-derivation false .#test-all
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
``` shell
|
||||
$ nix build --reference-lock-file flake.lock --option allow-import-from-derivation false ./tests#test-alacritty-empty-settings
|
||||
$ nix build --option allow-import-from-derivation false .#test-alacritty-empty-settings
|
||||
```
|
||||
|
||||
Some tests may be marked with `enableLegacyIfd`, those may be run by run with e.g.
|
||||
|
|
|
|||
|
|
@ -1,10 +1,9 @@
|
|||
# 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`.
|
||||
When using [flake-parts](https://flake.parts) you may wish to import Home
|
||||
Manager's flake module, `flakeModules.home-manager`.
|
||||
|
||||
``` nix
|
||||
```nix
|
||||
{
|
||||
description = "flake-parts configuration";
|
||||
|
||||
|
|
@ -15,15 +14,41 @@ you may wish to import Home Manager's flake module,
|
|||
flake-parts.url = "github:hercules-ci/flake-parts";
|
||||
};
|
||||
|
||||
outputs = inputs@{ flake-parts, ... }:
|
||||
outputs = inputs@{
|
||||
flake-parts,
|
||||
home-manager,
|
||||
nixpkgs,
|
||||
...
|
||||
}:
|
||||
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
|
||||
# Reusable Home Manager module.
|
||||
homeModules.bash= { pkgs, ... }: {
|
||||
programs.bash = {
|
||||
enable = true;
|
||||
shellAliases = {
|
||||
ll = "ls -l";
|
||||
};
|
||||
};
|
||||
home.packages = [ pkgs.hello ];
|
||||
};
|
||||
|
||||
# Concrete Home Manager configuration.
|
||||
homeConfigurations.alice = home-manager.lib.homeManagerConfiguration {
|
||||
pkgs = import nixpkgs { system = "x86_64-linux"; };
|
||||
modules = [
|
||||
inputs.self.homeModules.bash
|
||||
{
|
||||
home.username = "alice";
|
||||
home.homeDirectory = "/home/alice";
|
||||
home.stateVersion = "25.11";
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
# See flake.parts for more features, such as `perSystem`
|
||||
};
|
||||
|
|
|
|||
|
|
@ -23,3 +23,22 @@ changes are only active if the `home.stateVersion` option is set to
|
|||
- The [](#opt-programs.zsh.dotDir) option now defaults to the XDG
|
||||
configuration directory (usually `~/.config/zsh`) when
|
||||
[](#opt-xdg.enable) is true.
|
||||
|
||||
- The [](#opt-programs.yazi.shellWrapperName) option now defaults to
|
||||
`y` instead of `yy`. For users with older `home.stateVersion` values,
|
||||
the legacy default `yy` is retained.
|
||||
|
||||
- The [](#opt-xdg.userDirs.setSessionVariables) option now defaults to `false`
|
||||
instead of `true`.
|
||||
|
||||
- The [](#opt-xdg.userDirs.extraConfig) option no longer accepts keys of the
|
||||
form `XDG_<name>_DIR`, they should be now be just the name. For example, if
|
||||
you had the key `XDG_DESKTOP_DIR` before, you should now use the key
|
||||
`DESKTOP`. Home Manager 26.05 introduced a warning when the `XDG_<name>_DIR`
|
||||
form is used.
|
||||
|
||||
- The [](#opt-programs.man.package) option now defaults to `null` on
|
||||
Darwin because the GNU `man` from nixpkgs ships `apropos`/`man -k`
|
||||
and `whatis`/`man -f` binaries that don't work on Darwin. Nix-installed
|
||||
manual pages still work with macOS's built-in `man` via
|
||||
[](#opt-home.extraOutputsToInstall).
|
||||
|
|
|
|||
6
flake.lock
generated
6
flake.lock
generated
|
|
@ -2,11 +2,11 @@
|
|||
"nodes": {
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1769018530,
|
||||
"narHash": "sha256-MJ27Cy2NtBEV5tsK+YraYr2g851f3Fl1LpNHDzDX15c=",
|
||||
"lastModified": 1770841267,
|
||||
"narHash": "sha256-9xejG0KoqsoKEGp2kVbXRlEYtFFcDTHjidiuX8hGO44=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "88d3861acdd3d2f0e361767018218e51810df8a1",
|
||||
"rev": "ec7c70d12ce2fc37cb92aff673dcdca89d187bae",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
|
|||
136
flake.nix
136
flake.nix
|
|
@ -48,6 +48,113 @@
|
|||
forAllPkgs =
|
||||
f:
|
||||
nixpkgs.lib.genAttrs nixpkgs.lib.systems.flakeExposed (system: f nixpkgs.legacyPackages.${system});
|
||||
|
||||
forCI = nixpkgs.lib.genAttrs [
|
||||
"aarch64-darwin"
|
||||
"x86_64-linux"
|
||||
];
|
||||
|
||||
testChunks =
|
||||
system:
|
||||
let
|
||||
pkgs = nixpkgs.legacyPackages.${system};
|
||||
inherit (pkgs) lib;
|
||||
|
||||
# Create chunked test packages for better CI parallelization
|
||||
tests = import ./tests {
|
||||
inherit pkgs;
|
||||
# Disable big tests since this is only used for CI
|
||||
enableBig = false;
|
||||
};
|
||||
allTests = lib.attrNames tests.build;
|
||||
# Remove 'all' from the test list as it's a meta-package
|
||||
filteredTests = lib.filter (name: name != "all") allTests;
|
||||
# NOTE: Just a starting value, we can tweak this to find a good value.
|
||||
targetTestsPerChunk = 50;
|
||||
numChunks = lib.max 1 (
|
||||
builtins.ceil ((builtins.length filteredTests) / (targetTestsPerChunk * 1.0))
|
||||
);
|
||||
chunkSize = builtins.ceil ((builtins.length filteredTests) / (numChunks * 1.0));
|
||||
|
||||
makeChunk =
|
||||
chunkNum: testList:
|
||||
let
|
||||
start = (chunkNum - 1) * chunkSize;
|
||||
end = lib.min (start + chunkSize) (builtins.length testList);
|
||||
chunkTests = lib.sublist start (end - start) testList;
|
||||
chunkAttrs = lib.genAttrs chunkTests (name: tests.build.${name});
|
||||
in
|
||||
pkgs.symlinkJoin {
|
||||
name = "test-chunk-${toString chunkNum}";
|
||||
paths = lib.attrValues chunkAttrs;
|
||||
passthru.tests = chunkTests;
|
||||
};
|
||||
in
|
||||
lib.listToAttrs (
|
||||
lib.genList (
|
||||
i: lib.nameValuePair "test-chunk-${toString (i + 1)}" (makeChunk (i + 1) filteredTests)
|
||||
) numChunks
|
||||
);
|
||||
|
||||
integrationTests =
|
||||
system:
|
||||
let
|
||||
pkgs = nixpkgs.legacyPackages.${system};
|
||||
inherit (pkgs) lib;
|
||||
in
|
||||
lib.optionalAttrs pkgs.stdenv.hostPlatform.isLinux (
|
||||
let
|
||||
tests = import ./tests/integration { inherit pkgs lib; };
|
||||
renameTestPkg = n: v: lib.nameValuePair "integration-${n}" v;
|
||||
in
|
||||
lib.mapAttrs' renameTestPkg (lib.removeAttrs tests [ "all" ])
|
||||
);
|
||||
|
||||
buildTests =
|
||||
system:
|
||||
let
|
||||
pkgs = nixpkgs.legacyPackages.${system};
|
||||
tests = import ./tests { inherit pkgs; };
|
||||
renameTestPkg = n: nixpkgs.lib.nameValuePair "test-${n}";
|
||||
in
|
||||
nixpkgs.lib.mapAttrs' renameTestPkg tests.build;
|
||||
|
||||
buildTestsNoBig =
|
||||
system:
|
||||
let
|
||||
pkgs = nixpkgs.legacyPackages.${system};
|
||||
tests = import ./tests {
|
||||
inherit pkgs;
|
||||
enableBig = false;
|
||||
};
|
||||
in
|
||||
{
|
||||
test-all-enableBig-false-enableLegacyIfd-false = tests.build.all;
|
||||
};
|
||||
|
||||
buildTestsNoBigIfd =
|
||||
system:
|
||||
let
|
||||
pkgs = nixpkgs.legacyPackages.${system};
|
||||
tests = import ./tests {
|
||||
inherit pkgs;
|
||||
enableBig = false;
|
||||
enableLegacyIfd = true;
|
||||
};
|
||||
in
|
||||
{
|
||||
test-all-enableBig-false-enableLegacyIfd-true = tests.build.all;
|
||||
};
|
||||
|
||||
integrationTestPackages =
|
||||
system:
|
||||
let
|
||||
pkgs = nixpkgs.legacyPackages.${system};
|
||||
inherit (pkgs) lib;
|
||||
tests = import ./tests/integration { inherit pkgs lib; };
|
||||
renameTestPkg = n: lib.nameValuePair "integration-test-${n}";
|
||||
in
|
||||
lib.mapAttrs' renameTestPkg tests;
|
||||
in
|
||||
{
|
||||
formatter = forAllPkgs (
|
||||
|
|
@ -63,6 +170,22 @@
|
|||
}
|
||||
);
|
||||
|
||||
# TODO: increase buildbot testing scope
|
||||
buildbot = forCI (
|
||||
system:
|
||||
let
|
||||
allIntegrationTests = integrationTests system;
|
||||
workingIntegrationTests = nixpkgs.lib.filterAttrs (
|
||||
name: _:
|
||||
nixpkgs.lib.elem name [
|
||||
"integration-nixos-basics"
|
||||
"integration-nixos-legacy-profile-management"
|
||||
]
|
||||
) allIntegrationTests;
|
||||
in
|
||||
(testChunks system) // workingIntegrationTests
|
||||
);
|
||||
|
||||
packages = forAllPkgs (
|
||||
pkgs:
|
||||
let
|
||||
|
|
@ -90,6 +213,19 @@
|
|||
docs-manpages = docs.manPages;
|
||||
}
|
||||
);
|
||||
|
||||
legacyPackages = forAllPkgs (
|
||||
pkgs:
|
||||
let
|
||||
system = pkgs.stdenv.hostPlatform.system;
|
||||
in
|
||||
(buildTests system)
|
||||
// (integrationTestPackages system)
|
||||
// (buildTestsNoBig system)
|
||||
// (buildTestsNoBigIfd system)
|
||||
// (testChunks system)
|
||||
// (integrationTests system)
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -998,9 +998,11 @@ function doShowNews() {
|
|||
return 1
|
||||
esac
|
||||
|
||||
local formattedNewsFile="$WORK_DIR/news.txt"
|
||||
nix-instantiate --quiet --eval --json --expr "(import ${newsNixFile}).news.$newsAttr" \
|
||||
| jq -r . \
|
||||
| ${PAGER:-less}
|
||||
> "$formattedNewsFile"
|
||||
${PAGER:-less} "$formattedNewsFile"
|
||||
|
||||
local allIds
|
||||
allIds="$(nix-instantiate --quiet --eval --expr "(import ${newsNixFile}).meta.ids")"
|
||||
|
|
|
|||
|
|
@ -224,7 +224,7 @@ in
|
|||
|
||||
(mkIf cfg.x11.enable {
|
||||
xsession.profileExtra = ''
|
||||
${pkgs.xorg.xsetroot}/bin/xsetroot -xcf ${cursorPath} ${toString cfg.size}
|
||||
${lib.getExe pkgs.xsetroot} -xcf ${cursorPath} ${toString cfg.size}
|
||||
'';
|
||||
|
||||
xresources.properties = {
|
||||
|
|
|
|||
|
|
@ -291,7 +291,7 @@ in
|
|||
home-files =
|
||||
pkgs.runCommandLocal "home-manager-files"
|
||||
{
|
||||
nativeBuildInputs = [ pkgs.xorg.lndir ];
|
||||
nativeBuildInputs = [ pkgs.lndir ];
|
||||
}
|
||||
(
|
||||
''
|
||||
|
|
|
|||
|
|
@ -618,7 +618,7 @@ in
|
|||
home.profileDirectory =
|
||||
if config.submoduleSupport.enable && config.submoduleSupport.externalPackageInstall then
|
||||
"/etc/profiles/per-user/${cfg.username}"
|
||||
else if config.nix.enable && (config.nix.settings.use-xdg-base-directories or false) then
|
||||
else if config.nix.useXdg then
|
||||
"${config.xdg.stateHome}/nix/profile"
|
||||
else
|
||||
cfg.homeDirectory + "/.nix-profile";
|
||||
|
|
|
|||
|
|
@ -259,6 +259,10 @@ in
|
|||
AfterInitialDemand = mkOption {
|
||||
type = types.nullOr types.bool;
|
||||
default = null;
|
||||
description = ''
|
||||
Whether to defer evaluating other `KeepAlive` conditions until
|
||||
the job has been started at least once by demand.
|
||||
'';
|
||||
};
|
||||
|
||||
};
|
||||
|
|
|
|||
|
|
@ -368,6 +368,12 @@
|
|||
github = "mifom";
|
||||
githubId = 23462908;
|
||||
};
|
||||
mikaeladev = {
|
||||
name = "mikaeladev";
|
||||
email = "mikaeladev@users.noreply.github.com";
|
||||
github = "mikaeladev";
|
||||
githubId = 100416544;
|
||||
};
|
||||
mikilio = {
|
||||
name = "mikilio";
|
||||
email = "official.mikilio+dev@gmail.com";
|
||||
|
|
@ -488,6 +494,12 @@
|
|||
github = "Rosuavio";
|
||||
githubId = 7164552;
|
||||
};
|
||||
rsahwe = {
|
||||
name = "rsahwe";
|
||||
email = "rsahwe@gmx.net";
|
||||
github = "rsahwe";
|
||||
githubId = 201613730;
|
||||
};
|
||||
rszamszur = {
|
||||
name = "Radosław Szamszur";
|
||||
email = "radoslawszamszur@gmail.com";
|
||||
|
|
|
|||
18
modules/misc/news/2025/12/2025-12-10_04-15-59.nix
Normal file
18
modules/misc/news/2025/12/2025-12-10_04-15-59.nix
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
{ config, ... }:
|
||||
{
|
||||
time = "2025-12-10T07:15:59+00:00";
|
||||
condition = config.programs.firefox.enable;
|
||||
message = ''
|
||||
The Firefox module now provides a
|
||||
'programs.firefox.profiles.<name>.handlers' option.
|
||||
|
||||
It allows declarative configuration of MIME type and URL scheme handlers
|
||||
through Firefox's handlers.json file, controlling how Firefox opens files
|
||||
and protocols (e.g., PDF viewers, mailto handlers).
|
||||
|
||||
Configure handlers with:
|
||||
|
||||
programs.firefox.profiles.<name>.handlers.mimeTypes
|
||||
programs.firefox.profiles.<name>.handlers.schemes
|
||||
'';
|
||||
}
|
||||
10
modules/misc/news/2026/01/2026-01-27_20-02-41.nix
Normal file
10
modules/misc/news/2026/01/2026-01-27_20-02-41.nix
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
time = "2026-01-27T20:02:41+00:00";
|
||||
condition = true;
|
||||
message = ''
|
||||
A new module is available: 'programs.prismlauncher'.
|
||||
|
||||
An open-source Minecraft launcher that can manage multiple instances,
|
||||
accounts, and mods. Focused on user freedom and free redistributability.
|
||||
'';
|
||||
}
|
||||
19
modules/misc/news/2026/02/2026-02-04_21-02-20.nix
Normal file
19
modules/misc/news/2026/02/2026-02-04_21-02-20.nix
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
{ config, ... }:
|
||||
{
|
||||
time = "2026-02-05T03:02:20+00:00";
|
||||
condition = config.xdg.userDirs.enable;
|
||||
message = ''
|
||||
The `xdg.userDirs` module now supports non-Linux platforms.
|
||||
|
||||
The `xdg.userDirs.package` option is now available. Set it to `null`
|
||||
to prevent Home Manager from installing `xdg-user-dirs`.
|
||||
|
||||
The `xdg.userDirs.extraConfig` option no longer recommends keys of the
|
||||
form `XDG_<name>_DIR`; use just `<name>` instead (e.g. `DESKTOP`).
|
||||
The old form is deprecated and will emit a warning.
|
||||
|
||||
The `xdg.userDirs.setSessionVariables` option was added to control
|
||||
whether XDG user directory environment variables like `XDG_DESKTOP_DIR` are
|
||||
set. It now defaults to `false` for `home.stateVersion` 26.05 and later.
|
||||
'';
|
||||
}
|
||||
10
modules/misc/news/2026/02/2026-02-08_10-59-14.nix
Normal file
10
modules/misc/news/2026/02/2026-02-08_10-59-14.nix
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
time = "2026-02-08T13:59:14+00:00";
|
||||
condition = true;
|
||||
message = ''
|
||||
A new module is available: `programs.lazyworktree`
|
||||
|
||||
LazyWorktree is a TUI for Git worktrees. It provides a keyboard-driven
|
||||
workflow for creating, inspecting, and navigating worktrees within a repository.
|
||||
'';
|
||||
}
|
||||
13
modules/misc/news/2026/02/2026-02-08_15-04-50.nix
Normal file
13
modules/misc/news/2026/02/2026-02-08_15-04-50.nix
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
{ config, ... }:
|
||||
{
|
||||
time = "2026-02-08T21:04:50+00:00";
|
||||
condition = config.programs.codex.enable;
|
||||
message = ''
|
||||
The `programs.codex` module now supports MCP integration via
|
||||
`programs.codex.enableMcpIntegration`.
|
||||
|
||||
When enabled, shared servers from `programs.mcp.servers` are merged
|
||||
into `programs.codex.settings.mcp_servers`, with settings-based values
|
||||
taking precedence.
|
||||
'';
|
||||
}
|
||||
8
modules/misc/news/2026/02/2026-02-11_23-16-46.nix
Normal file
8
modules/misc/news/2026/02/2026-02-11_23-16-46.nix
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
time = "2026-02-12T05:16:46+00:00";
|
||||
condition = true;
|
||||
message = ''
|
||||
The `services.flameshot` module now supports Darwin by generating a
|
||||
launchd agent in addition to the existing Linux systemd service.
|
||||
'';
|
||||
}
|
||||
16
modules/misc/news/2026/02/2026-02-12_13-22-50.nix
Normal file
16
modules/misc/news/2026/02/2026-02-12_13-22-50.nix
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
{ config, ... }:
|
||||
{
|
||||
time = "2026-02-12T19:22:50+00:00";
|
||||
condition = config.programs.pay-respects.enable;
|
||||
message = ''
|
||||
The option `programs.pay-respects.rules` was added.
|
||||
|
||||
It generates runtime rule files at
|
||||
{file}`$XDG_CONFIG_HOME/pay-respects/rules/<name>.toml`, where each
|
||||
attribute name under `rules` becomes a filename (for example, `rules.cargo`
|
||||
writes `cargo.toml`).
|
||||
|
||||
For the full runtime-rules format and command matching requirements, see
|
||||
<https://github.com/iffse/pay-respects/blob/main/rules.md>.
|
||||
'';
|
||||
}
|
||||
11
modules/misc/news/2026/02/2026-02-13_12-21-10.nix
Normal file
11
modules/misc/news/2026/02/2026-02-13_12-21-10.nix
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
time = "2026-02-13T11:21:10+00:00";
|
||||
condition = true;
|
||||
message = ''
|
||||
|
||||
A new module is available: 'programs.tirith'.
|
||||
|
||||
Tirith is a shell security monitor that helps protect against
|
||||
malicious commands by analyzing shell inputs before execution.
|
||||
'';
|
||||
}
|
||||
9
modules/misc/news/2026/02/2026-02-13_14-17-15.nix
Normal file
9
modules/misc/news/2026/02/2026-02-13_14-17-15.nix
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
{ config, ... }:
|
||||
{
|
||||
time = "2026-02-13T20:17:15+00:00";
|
||||
condition = config.programs.yazi.enable;
|
||||
message = "
|
||||
The option `programs.yazi.shellWrapperName` default has changed from `yy` to `y`
|
||||
to align with the recommendation from upstream.
|
||||
";
|
||||
}
|
||||
10
modules/misc/news/2026/02/2026-02-17_15-42-25.nix
Normal file
10
modules/misc/news/2026/02/2026-02-17_15-42-25.nix
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
time = "2026-02-17T14:42:25+00:00";
|
||||
condition = true;
|
||||
message = ''
|
||||
|
||||
A new module is available: 'programs.mistral-vibe'.
|
||||
|
||||
mistral-vibe is Mistral's open-source CLI coding assistant.
|
||||
'';
|
||||
}
|
||||
12
modules/misc/news/2026/02/2026-02-18_18-20-43.nix
Normal file
12
modules/misc/news/2026/02/2026-02-18_18-20-43.nix
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
time = "2026-02-18T17:20:43+00:00";
|
||||
condition = true;
|
||||
message = ''
|
||||
A new module is available: 'programs.rizin'.
|
||||
|
||||
Rizin is a free and open-source reverse engineering framework
|
||||
that delivers a comprehensive binary analysis experience.
|
||||
It focuses on usability, stability, and functional features,
|
||||
striving to create a welcoming environment for developers and users.
|
||||
'';
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
#!/usr/bin/env nix-shell
|
||||
#! nix-shell -I nixpkgs=https://github.com/NixOS/nixpkgs/archive/72ac591e737060deab2b86d6952babd1f896d7c5.tar.gz -i bash -p coreutils
|
||||
#! nix-shell -i bash -p coreutils
|
||||
|
||||
DATE="$(date --iso-8601=second --universal)"
|
||||
YEAR="$(date --date="$DATE" +"%Y")"
|
||||
|
|
@ -15,7 +15,7 @@ cd "$DIRNAME" || {
|
|||
exit 1
|
||||
}
|
||||
|
||||
cat - << EOF > "$YEAR/$MONTH/$FILENAME_BASE.nix"
|
||||
cat - <<EOF >"$YEAR/$MONTH/$FILENAME_BASE.nix"
|
||||
{
|
||||
time = "$DATE";
|
||||
condition = true;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
osConfig,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
|
|
@ -21,6 +22,7 @@ let
|
|||
isList
|
||||
isString
|
||||
literalExpression
|
||||
literalMD
|
||||
mapAttrsToList
|
||||
mkDefault
|
||||
mkEnableOption
|
||||
|
|
@ -41,7 +43,7 @@ let
|
|||
|
||||
nixPath = concatStringsSep ":" cfg.nixPath;
|
||||
|
||||
useXdg = config.nix.enable && (config.nix.settings.use-xdg-base-directories or false);
|
||||
inherit (config.nix) useXdg;
|
||||
defexprDir =
|
||||
if useXdg then
|
||||
"${config.xdg.stateHome}/nix/defexpr"
|
||||
|
|
@ -296,6 +298,30 @@ in
|
|||
'';
|
||||
};
|
||||
|
||||
assumeXdg = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Whether Home Manager should assume that Nix is configured to use XDG
|
||||
base directories. Note that this doesn't change the behavior of Nix. To
|
||||
do that, set nix.settings.use-xdg-base-directories instead. This option
|
||||
is intended for settings in which use-xdg-base-directories is set
|
||||
globally or nix.conf is unmanaged by Home Manager.
|
||||
'';
|
||||
};
|
||||
|
||||
useXdg = mkOption {
|
||||
type = types.bool;
|
||||
visible = false;
|
||||
readOnly = true;
|
||||
defaultText = literalMD ''
|
||||
In descending priority:
|
||||
* `true` if `nix.assumeXdg` is `true`
|
||||
* `nix.settings.use-xdg-base-directories` if it is set and `nix.enable` is `true`
|
||||
* `osConfig.nix.settings.use-xdg-base-directories` if it is set and `osConfig.nix.enable` is `true`
|
||||
'';
|
||||
};
|
||||
|
||||
extraOptions = mkOption {
|
||||
type = types.lines;
|
||||
default = "";
|
||||
|
|
@ -326,39 +352,69 @@ in
|
|||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable (mkMerge [
|
||||
(mkIf (cfg.nixPath != [ ] && !cfg.keepOldNixPath) {
|
||||
home.sessionVariables.NIX_PATH = "${nixPath}";
|
||||
})
|
||||
config = mkMerge [
|
||||
{
|
||||
nix.useXdg =
|
||||
let
|
||||
# Helper that checks if use-xdg-base-directories is in effect for the
|
||||
# given Nix configuration, falling back to a given default value if
|
||||
# it is undefined or the configuration is not enabled.
|
||||
checkNixXdg = def: cfg: if cfg.enable then cfg.settings.use-xdg-base-directories or def else def;
|
||||
|
||||
(mkIf (cfg.nixPath != [ ] && cfg.keepOldNixPath) {
|
||||
home.sessionVariables.NIX_PATH = "${nixPath}\${NIX_PATH:+:$NIX_PATH}";
|
||||
})
|
||||
# Whether the OS configuration indicates that XDG directories should
|
||||
# be used.
|
||||
osUseXdg = checkNixXdg false osConfig.nix or { enable = false; };
|
||||
|
||||
(lib.mkIf (cfg.channels != { }) {
|
||||
nix.nixPath = [ channelPath ];
|
||||
home.file."${channelPath}".source = channelsDrv;
|
||||
})
|
||||
# Whether the user configuration indicates that XDG directories
|
||||
# should be used, falling back to the OS configuration if not
|
||||
# specified.
|
||||
hmUseXdg = checkNixXdg osUseXdg cfg;
|
||||
in
|
||||
cfg.assumeXdg || hmUseXdg;
|
||||
|
||||
(mkIf (cfg.registry != { }) {
|
||||
xdg.configFile."nix/registry.json".source = jsonFormat.generate "registry.json" {
|
||||
version = cfg.registryVersion;
|
||||
flakes = mapAttrsToList (n: v: { inherit (v) from to exact; }) cfg.registry;
|
||||
};
|
||||
})
|
||||
|
||||
(mkIf (cfg.settings != { } || cfg.extraOptions != "") {
|
||||
assertions = [
|
||||
{
|
||||
assertion = cfg.package != null;
|
||||
assertion = !(cfg.assumeXdg && cfg.enable && cfg.settings ? use-xdg-base-directories);
|
||||
message = ''
|
||||
A corresponding Nix package must be specified via `nix.package` for generating
|
||||
nix.conf.
|
||||
`nix.assumeXdg` should not be set if `nix.settings.use-xdg-base-directories` is.
|
||||
'';
|
||||
}
|
||||
];
|
||||
}
|
||||
(mkIf cfg.enable (mkMerge [
|
||||
(mkIf (cfg.nixPath != [ ] && !cfg.keepOldNixPath) {
|
||||
home.sessionVariables.NIX_PATH = "${nixPath}";
|
||||
})
|
||||
|
||||
xdg.configFile."nix/nix.conf".source = nixConf;
|
||||
})
|
||||
]);
|
||||
(mkIf (cfg.nixPath != [ ] && cfg.keepOldNixPath) {
|
||||
home.sessionVariables.NIX_PATH = "${nixPath}\${NIX_PATH:+:$NIX_PATH}";
|
||||
})
|
||||
|
||||
(lib.mkIf (cfg.channels != { }) {
|
||||
nix.nixPath = [ channelPath ];
|
||||
home.file."${channelPath}".source = channelsDrv;
|
||||
})
|
||||
|
||||
(mkIf (cfg.registry != { }) {
|
||||
xdg.configFile."nix/registry.json".source = jsonFormat.generate "registry.json" {
|
||||
version = cfg.registryVersion;
|
||||
flakes = mapAttrsToList (n: v: { inherit (v) from to exact; }) cfg.registry;
|
||||
};
|
||||
})
|
||||
|
||||
(mkIf (cfg.settings != { } || cfg.extraOptions != "") {
|
||||
assertions = [
|
||||
{
|
||||
assertion = cfg.package != null;
|
||||
message = ''
|
||||
A corresponding Nix package must be specified via `nix.package` for generating
|
||||
nix.conf.
|
||||
'';
|
||||
}
|
||||
];
|
||||
|
||||
xdg.configFile."nix/nix.conf".source = nixConf;
|
||||
})
|
||||
]))
|
||||
];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ let
|
|||
|
||||
in
|
||||
{
|
||||
meta.maintainers = with lib.maintainers; [ thiagokokada ];
|
||||
meta.maintainers = [ ];
|
||||
|
||||
options.nixpkgs = {
|
||||
config = lib.mkOption {
|
||||
|
|
|
|||
|
|
@ -92,7 +92,6 @@ in
|
|||
{
|
||||
meta.maintainers = with lib.maintainers; [
|
||||
rycee
|
||||
thiagokokada
|
||||
];
|
||||
|
||||
imports = [
|
||||
|
|
@ -302,7 +301,7 @@ in
|
|||
Appearance = {
|
||||
style = "kvantum";
|
||||
icon_theme = "Papirus-Dark";
|
||||
standar_dialogs = "xdgdesktopportal";
|
||||
standard_dialogs = "xdgdesktopportal";
|
||||
};
|
||||
Fonts = {
|
||||
fixed = "\"DejaVuSansM Nerd Font Mono,12\"";
|
||||
|
|
|
|||
|
|
@ -36,6 +36,8 @@ in
|
|||
'';
|
||||
};
|
||||
|
||||
package = lib.mkPackageOption pkgs "xdg-user-dirs" { nullable = true; };
|
||||
|
||||
# Well-known directory list from
|
||||
# https://gitlab.freedesktop.org/xdg/xdg-user-dirs/blob/master/man/user-dirs.dirs.xml
|
||||
|
||||
|
|
@ -101,45 +103,88 @@ in
|
|||
defaultText = literalExpression "{ }";
|
||||
example = literalExpression ''
|
||||
{
|
||||
XDG_MISC_DIR = "''${config.home.homeDirectory}/Misc";
|
||||
MISC = "''${config.home.homeDirectory}/Misc";
|
||||
}
|
||||
'';
|
||||
description = "Other user directories.";
|
||||
apply =
|
||||
if lib.versionOlder config.home.stateVersion "26.05" then
|
||||
lib.mapAttrs' (
|
||||
k:
|
||||
let
|
||||
matches = lib.match "XDG_(.*)_DIR" k;
|
||||
in
|
||||
lib.nameValuePair (
|
||||
if matches == null then
|
||||
k
|
||||
else
|
||||
let
|
||||
name = lib.elemAt matches 0;
|
||||
in
|
||||
lib.warn "using keys like ‘${k}’ for xdg.userDirs.extraConfig is deprecated in favor of keys like ‘${name}’" name
|
||||
)
|
||||
)
|
||||
else
|
||||
lib.id;
|
||||
description = ''
|
||||
Other user directories.
|
||||
|
||||
The key ‘MISC’ corresponds to the user-dirs entry ‘XDG_MISC_DIR’.
|
||||
'';
|
||||
};
|
||||
|
||||
createDirectories = lib.mkEnableOption "automatic creation of the XDG user directories";
|
||||
|
||||
setSessionVariables = mkOption {
|
||||
type = with types; bool;
|
||||
default = lib.versionOlder config.home.stateVersion "26.05";
|
||||
defaultText = literalExpression ''
|
||||
lib.versionOlder config.home.stateVersion "26.05"
|
||||
'';
|
||||
description = ''
|
||||
Whether to set the XDG user dir environment variables, like
|
||||
`XDG_DESKTOP_DIR`.
|
||||
|
||||
::: {.note}
|
||||
The recommended way to get these values is via the `xdg-user-dir`
|
||||
command or by processing `$XDG_CONFIG_HOME/user-dirs.dirs` directly in
|
||||
your application.
|
||||
:::
|
||||
|
||||
This defaults to `true` for state version < 26.05 and `false` otherwise.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config =
|
||||
let
|
||||
directories =
|
||||
(lib.filterAttrs (n: v: !isNull v) {
|
||||
XDG_DESKTOP_DIR = cfg.desktop;
|
||||
XDG_DOCUMENTS_DIR = cfg.documents;
|
||||
XDG_DOWNLOAD_DIR = cfg.download;
|
||||
XDG_MUSIC_DIR = cfg.music;
|
||||
XDG_PICTURES_DIR = cfg.pictures;
|
||||
XDG_PUBLICSHARE_DIR = cfg.publicShare;
|
||||
XDG_TEMPLATES_DIR = cfg.templates;
|
||||
XDG_VIDEOS_DIR = cfg.videos;
|
||||
DESKTOP = cfg.desktop;
|
||||
DOCUMENTS = cfg.documents;
|
||||
DOWNLOAD = cfg.download;
|
||||
MUSIC = cfg.music;
|
||||
PICTURES = cfg.pictures;
|
||||
PUBLICSHARE = cfg.publicShare;
|
||||
TEMPLATES = cfg.templates;
|
||||
VIDEOS = cfg.videos;
|
||||
})
|
||||
// cfg.extraConfig;
|
||||
|
||||
bindings = lib.mapAttrs' (k: lib.nameValuePair "XDG_${k}_DIR") directories;
|
||||
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 = lib.mapAttrs (_: value: ''"${value}"'') directories;
|
||||
wrapped = lib.mapAttrs (_: value: ''"${value}"'') bindings;
|
||||
in
|
||||
lib.generators.toKeyValue { } wrapped;
|
||||
|
||||
xdg.configFile."user-dirs.conf".text = "enabled=False";
|
||||
|
||||
home.sessionVariables = directories;
|
||||
home.packages = lib.mkIf (cfg.package != null) [ cfg.package ];
|
||||
|
||||
home.sessionVariables = lib.mkIf cfg.setSessionVariables bindings;
|
||||
|
||||
home.activation.createXdgUserDirectories = lib.mkIf cfg.createDirectories (
|
||||
let
|
||||
|
|
|
|||
|
|
@ -371,7 +371,7 @@ in
|
|||
exit 1
|
||||
esac
|
||||
|
||||
echo "Xft.dpi: $DPI" | ''${pkgs.xorg.xrdb}/bin/xrdb -merge
|
||||
echo "Xft.dpi: $DPI" | ''${lib.getExe pkgs.xrdb} -merge
|
||||
'''
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,9 +27,32 @@ in
|
|||
enableNushellIntegration = lib.hm.shell.mkNushellIntegrationOption { inherit config; };
|
||||
|
||||
enableZshIntegration = lib.hm.shell.mkZshIntegrationOption { inherit config; };
|
||||
|
||||
ignoreCase = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Whether to enable case-insensitive matching for carapace completions.
|
||||
When enabled, the carapace binary is wrapped with {env}`CARAPACE_MATCH`
|
||||
set to `1`.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
programs.carapace.package = lib.mkIf cfg.ignoreCase (
|
||||
pkgs.symlinkJoin {
|
||||
name = "carapace-wrapped";
|
||||
paths = [ pkgs.carapace ];
|
||||
nativeBuildInputs = [ pkgs.makeWrapper ];
|
||||
postBuild = ''
|
||||
wrapProgram $out/bin/carapace \
|
||||
--set CARAPACE_MATCH 1
|
||||
'';
|
||||
meta.mainProgram = "carapace";
|
||||
}
|
||||
);
|
||||
|
||||
home.packages = [ cfg.package ];
|
||||
|
||||
programs = {
|
||||
|
|
|
|||
|
|
@ -298,14 +298,14 @@ in
|
|||
default = { };
|
||||
description = ''
|
||||
Custom skills for Claude Code.
|
||||
The attribute name becomes the skill filename or directory name, and the value is either:
|
||||
- Inline content as a string (creates .claude/skills/<name>.md)
|
||||
- A path to a file (creates .claude/skills/<name>.md)
|
||||
The attribute name becomes the skill directory name, and the value is either:
|
||||
- Inline content as a string (creates .claude/skills/<name>/SKILL.md)
|
||||
- A path to a file (creates .claude/skills/<name>/SKILL.md)
|
||||
- A path to a directory (creates .claude/skills/<name>/ with all files)
|
||||
'';
|
||||
example = lib.literalExpression ''
|
||||
{
|
||||
xlsx = ./skills/xlsx.md;
|
||||
xlsx = ./skills/xlsx/SKILL.md;
|
||||
data-analysis = ./skills/data-analysis;
|
||||
pdf-processing = '''
|
||||
---
|
||||
|
|
@ -334,8 +334,9 @@ in
|
|||
type = lib.types.nullOr lib.types.path;
|
||||
default = null;
|
||||
description = ''
|
||||
Path to a directory containing skill files for Claude Code.
|
||||
Skill files from this directory will be symlinked to .claude/skills/.
|
||||
Path to a directory containing skill directories for Claude Code.
|
||||
Each skill directory should contain a SKILL.md entrypoint file.
|
||||
Skill directories from this path will be symlinked to .claude/skills/.
|
||||
'';
|
||||
example = lib.literalExpression "./skills";
|
||||
};
|
||||
|
|
@ -516,7 +517,7 @@ in
|
|||
recursive = true;
|
||||
}
|
||||
else
|
||||
lib.nameValuePair ".claude/skills/${name}.md" (
|
||||
lib.nameValuePair ".claude/skills/${name}/SKILL.md" (
|
||||
if lib.isPath content then { source = content; } else { text = content; }
|
||||
)
|
||||
) cfg.skills;
|
||||
|
|
|
|||
|
|
@ -26,6 +26,20 @@ in
|
|||
|
||||
package = lib.mkPackageOption pkgs "codex" { nullable = true; };
|
||||
|
||||
enableMcpIntegration = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Whether to integrate the MCP server config from
|
||||
{option}`programs.mcp.servers` into
|
||||
{option}`programs.codex.settings.mcp_servers`.
|
||||
|
||||
Note: Settings defined in {option}`programs.mcp.servers` are merged
|
||||
with {option}`programs.codex.settings.mcp_servers`, with settings-based
|
||||
values taking precedence.
|
||||
'';
|
||||
};
|
||||
|
||||
settings = lib.mkOption {
|
||||
# NOTE: `yaml` type supports null, using `nullOr` for backwards compatibility period
|
||||
type = lib.types.nullOr tomlFormat.type;
|
||||
|
|
@ -48,6 +62,15 @@ in
|
|||
envKey = "OLLAMA_API_KEY";
|
||||
};
|
||||
};
|
||||
mcp_servers = {
|
||||
context7 = {
|
||||
command = "npx";
|
||||
args = [
|
||||
"-y"
|
||||
"@upstash/context7-mcp"
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
||||
'';
|
||||
};
|
||||
|
|
@ -111,10 +134,36 @@ in
|
|||
|
||||
config =
|
||||
let
|
||||
useXdgDirectories = (config.home.preferXdgDirectories && isTomlConfig);
|
||||
useXdgDirectories = config.home.preferXdgDirectories && isTomlConfig;
|
||||
xdgConfigHome = lib.removePrefix config.home.homeDirectory config.xdg.configHome;
|
||||
configDir = if useXdgDirectories then "${xdgConfigHome}/codex" else ".codex";
|
||||
configFileName = if isTomlConfig then "config.toml" else "config.yaml";
|
||||
|
||||
transformedMcpServers = lib.optionalAttrs (cfg.enableMcpIntegration && config.programs.mcp.enable) (
|
||||
lib.mapAttrs (
|
||||
_name: server:
|
||||
# NOTE: Convert shared programs.mcp fields to Codex config keys:
|
||||
# - removeAttrs drops keys that Codex does not use directly
|
||||
# - "disabled" becomes inverse "enabled"
|
||||
# - "headers" is renamed to "http_headers"
|
||||
# See: https://developers.openai.com/codex/mcp#other-configuration-options
|
||||
(lib.removeAttrs server [
|
||||
"disabled"
|
||||
"headers"
|
||||
])
|
||||
// (lib.optionalAttrs (server ? headers && !(server ? http_headers)) {
|
||||
http_headers = server.headers;
|
||||
})
|
||||
// {
|
||||
enabled = !(server.disabled or false);
|
||||
}
|
||||
) config.programs.mcp.servers
|
||||
);
|
||||
|
||||
settingMcpServers = lib.attrByPath [ "mcp_servers" ] { } cfg.settings;
|
||||
mergedMcpServers = transformedMcpServers // settingMcpServers;
|
||||
mergedSettings =
|
||||
cfg.settings // lib.optionalAttrs (mergedMcpServers != { }) { mcp_servers = mergedMcpServers; };
|
||||
in
|
||||
mkIf cfg.enable {
|
||||
assertions = [
|
||||
|
|
@ -126,9 +175,10 @@ in
|
|||
|
||||
home = {
|
||||
packages = mkIf (cfg.package != null) [ cfg.package ];
|
||||
|
||||
file = {
|
||||
"${configDir}/${configFileName}" = lib.mkIf (cfg.settings != { }) {
|
||||
source = settingsFormat.generate "codex-config" cfg.settings;
|
||||
"${configDir}/${configFileName}" = lib.mkIf (mergedSettings != { }) {
|
||||
source = settingsFormat.generate "codex-config" mergedSettings;
|
||||
};
|
||||
"${configDir}/AGENTS.md" = lib.mkIf (cfg.custom-instructions != "") {
|
||||
text = cfg.custom-instructions;
|
||||
|
|
@ -150,6 +200,7 @@ in
|
|||
if lib.isPath content then { source = content; } else { text = content; }
|
||||
)
|
||||
) (if builtins.isAttrs cfg.skills then cfg.skills else { }));
|
||||
|
||||
sessionVariables = mkIf useXdgDirectories {
|
||||
CODEX_HOME = "${config.xdg.configHome}/codex";
|
||||
};
|
||||
|
|
|
|||
|
|
@ -26,7 +26,6 @@ in
|
|||
name = "Firefox";
|
||||
wrappedPackageName = "firefox";
|
||||
unwrappedPackageName = "firefox-unwrapped";
|
||||
visible = true;
|
||||
|
||||
platforms.linux = {
|
||||
configPath = ".mozilla/firefox";
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@
|
|||
wrappedPackageName ? null,
|
||||
unwrappedPackageName ? null,
|
||||
platforms,
|
||||
visible ? false,
|
||||
enableBookmarks ? true,
|
||||
}:
|
||||
{
|
||||
|
|
@ -209,12 +208,10 @@ in
|
|||
example = true;
|
||||
description = ''
|
||||
Whether to enable ${appName}.${optionalString (description != null) " ${description}"}
|
||||
${optionalString (!visible) "See `${moduleName}` for more configuration options."}
|
||||
'';
|
||||
};
|
||||
|
||||
package = mkOption {
|
||||
inherit visible;
|
||||
type = with types; nullOr package;
|
||||
default = pkgs.${defaultPackageName};
|
||||
defaultText = literalExpression "pkgs.${packageName}";
|
||||
|
|
@ -317,7 +314,6 @@ in
|
|||
};
|
||||
|
||||
nativeMessagingHosts = mkOption {
|
||||
inherit visible;
|
||||
type = types.listOf types.package;
|
||||
default = [ ];
|
||||
description = ''
|
||||
|
|
@ -327,14 +323,12 @@ in
|
|||
};
|
||||
|
||||
finalPackage = mkOption {
|
||||
inherit visible;
|
||||
type = with types; nullOr package;
|
||||
readOnly = true;
|
||||
description = "Resulting ${appName} package.";
|
||||
};
|
||||
|
||||
policies = lib.optionalAttrs (wrappedPackageName != null) (mkOption {
|
||||
inherit visible;
|
||||
type = types.attrsOf jsonFormat.type;
|
||||
default = { };
|
||||
description = "[See list of policies](https://mozilla.github.io/policy-templates/).";
|
||||
|
|
@ -360,7 +354,6 @@ in
|
|||
};
|
||||
|
||||
profiles = mkOption {
|
||||
inherit visible;
|
||||
type = types.attrsOf (
|
||||
types.submodule (
|
||||
{ config, name, ... }:
|
||||
|
|
@ -555,6 +548,25 @@ in
|
|||
description = "Declarative search engine configuration.";
|
||||
};
|
||||
|
||||
handlers = mkOption {
|
||||
type = types.submodule (
|
||||
args:
|
||||
import ./profiles/handlers.nix {
|
||||
inherit (args) config;
|
||||
inherit lib pkgs appName;
|
||||
package = cfg.finalPackage;
|
||||
modulePath = modulePath ++ [
|
||||
"profiles"
|
||||
name
|
||||
"handlers"
|
||||
];
|
||||
profilePath = config.path;
|
||||
}
|
||||
);
|
||||
default = { };
|
||||
description = "Declarative handlers configuration for MIME types and URL schemes.";
|
||||
};
|
||||
|
||||
containersForce = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
|
|
@ -913,7 +925,6 @@ in
|
|||
};
|
||||
|
||||
enableGnomeExtensions = mkOption {
|
||||
inherit visible;
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
|
|
@ -1056,6 +1067,11 @@ in
|
|||
source = profile.search.file;
|
||||
};
|
||||
|
||||
"${cfg.profilesPath}/${profile.path}/handlers.json" = mkIf (profile.handlers.enable) {
|
||||
source = profile.handlers.configFile;
|
||||
force = profile.handlers.force;
|
||||
};
|
||||
|
||||
"${cfg.profilesPath}/${profile.path}/extensions" = mkIf (profile.extensions.packages != [ ]) {
|
||||
source =
|
||||
let
|
||||
|
|
|
|||
209
modules/programs/firefox/profiles/handlers.nix
Normal file
209
modules/programs/firefox/profiles/handlers.nix
Normal file
|
|
@ -0,0 +1,209 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
appName,
|
||||
...
|
||||
}:
|
||||
let
|
||||
jsonFormat = pkgs.formats.json { };
|
||||
|
||||
# Process configuration, remove null values and empty handlers arrays.
|
||||
genCfg =
|
||||
cfg:
|
||||
lib.mapAttrs (
|
||||
_: item:
|
||||
(removeAttrs item [ "handlers" ])
|
||||
// (lib.optionalAttrs (item.handlers != [ ]) {
|
||||
handlers = map (handler: lib.filterAttrsRecursive (_: v: v != null) handler) item.handlers;
|
||||
})
|
||||
) cfg;
|
||||
|
||||
# Common options shared between mimeTypes and schemes
|
||||
commonHandlerOptions = {
|
||||
action = lib.mkOption {
|
||||
type = lib.types.enum [
|
||||
0
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
];
|
||||
default = 1;
|
||||
description = ''
|
||||
The action to take for this MIME type / URL scheme. Possible values:
|
||||
- 0: Save file
|
||||
- 1: Always ask
|
||||
- 2: Use helper app
|
||||
- 3: Open in ${appName}
|
||||
- 4: Use system default
|
||||
'';
|
||||
};
|
||||
|
||||
ask = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
If true, the user is asked what they want to do with the file.
|
||||
If false, the action is taken without user intervention.
|
||||
'';
|
||||
};
|
||||
|
||||
handlers = lib.mkOption {
|
||||
type = lib.types.listOf (
|
||||
lib.types.submodule {
|
||||
options = {
|
||||
name = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
Display name of the handler.
|
||||
'';
|
||||
};
|
||||
|
||||
path = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
Path to the executable to be used.
|
||||
|
||||
Only one of 'path' or 'uriTemplate' should be set.
|
||||
'';
|
||||
};
|
||||
|
||||
uriTemplate = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
URI for the application handler.
|
||||
|
||||
Only one of 'path' or 'uriTemplate' should be set.
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
);
|
||||
default = [ ];
|
||||
description = ''
|
||||
An array of handlers with the first one being the default.
|
||||
If you don't want to have a default handler, use an empty object for the first handler.
|
||||
Only valid when action is set to 2 (Use helper app).
|
||||
'';
|
||||
};
|
||||
};
|
||||
in
|
||||
{
|
||||
imports = [ (pkgs.path + "/nixos/modules/misc/meta.nix") ];
|
||||
|
||||
meta.maintainers = with lib.maintainers; [ kugland ];
|
||||
|
||||
options = {
|
||||
enable = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = config.schemes != { } || config.mimeTypes != { };
|
||||
internal = true;
|
||||
};
|
||||
|
||||
force = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Whether to force replace the existing handlers configuration.
|
||||
'';
|
||||
};
|
||||
|
||||
mimeTypes = lib.mkOption {
|
||||
type = lib.types.attrsOf (
|
||||
lib.types.submodule {
|
||||
options = commonHandlerOptions // {
|
||||
extensions = lib.mkOption {
|
||||
type = lib.types.listOf (lib.types.strMatching "^[^\\.].+$");
|
||||
default = [ ];
|
||||
example = [
|
||||
"jpg"
|
||||
"jpeg"
|
||||
];
|
||||
description = ''
|
||||
List of file extensions associated with this MIME type.
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
);
|
||||
default = { };
|
||||
example = lib.literalExpression ''
|
||||
{
|
||||
"application/pdf" = {
|
||||
action = 2;
|
||||
ask = false;
|
||||
handlers = [
|
||||
{
|
||||
name = "Okular";
|
||||
path = "''${pkgs.okular}/bin/okular";
|
||||
}
|
||||
];
|
||||
extensions = [ "pdf" ];
|
||||
};
|
||||
}
|
||||
'';
|
||||
description = ''
|
||||
Attribute set mapping MIME types to their handler configurations.
|
||||
|
||||
For a configuration example, see [this file on Firefox’s source code](https://github.com/mozilla-firefox/firefox/blob/c3797cdebac1316dd7168e995e3468c5a597e8d1/uriloader/exthandler/tests/unit/handlers.json).
|
||||
'';
|
||||
};
|
||||
|
||||
schemes = lib.mkOption {
|
||||
type = lib.types.attrsOf (
|
||||
lib.types.submodule {
|
||||
options = commonHandlerOptions;
|
||||
}
|
||||
);
|
||||
default = { };
|
||||
example = lib.literalExpression ''
|
||||
{
|
||||
mailto = {
|
||||
action = 2;
|
||||
ask = false;
|
||||
handlers = [
|
||||
{
|
||||
name = "Gmail";
|
||||
uriTemplate = "https://mail.google.com/mail/?extsrc=mailto&url=%s";
|
||||
}
|
||||
];
|
||||
};
|
||||
}
|
||||
'';
|
||||
description = ''
|
||||
Attribute set mapping URL schemes to their handler configurations.
|
||||
|
||||
For a configuration example, see [this file on Firefox’s source code](https://github.com/mozilla-firefox/firefox/blob/c3797cdebac1316dd7168e995e3468c5a597e8d1/uriloader/exthandler/tests/unit/handlers.json).
|
||||
'';
|
||||
};
|
||||
|
||||
finalSettings = lib.mkOption {
|
||||
type = jsonFormat.type;
|
||||
internal = true;
|
||||
readOnly = true;
|
||||
default = {
|
||||
defaultHandlersVersion = { };
|
||||
isDownloadsImprovementsAlreadyMigrated = false;
|
||||
mimeTypes = genCfg config.mimeTypes;
|
||||
schemes = genCfg config.schemes;
|
||||
};
|
||||
description = ''
|
||||
Resulting handlers.json settings.
|
||||
'';
|
||||
};
|
||||
|
||||
configFile = lib.mkOption {
|
||||
type = lib.types.path;
|
||||
internal = true;
|
||||
readOnly = true;
|
||||
default = jsonFormat.generate "handlers.json" config.finalSettings;
|
||||
description = ''
|
||||
JSON representation of the handlers configuration.
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -397,6 +397,20 @@ let
|
|||
echo "end"
|
||||
echo "setup_hm_session_vars") > $out/${sessionVarsFile}
|
||||
'';
|
||||
sourceHandlersStr =
|
||||
let
|
||||
handlerAttrs = [
|
||||
"onJobExit"
|
||||
"onProcessExit"
|
||||
"onVariable"
|
||||
"onSignal"
|
||||
"onEvent"
|
||||
];
|
||||
isHandler = name: def: isAttrs def && builtins.any (attr: builtins.hasAttr attr def) handlerAttrs;
|
||||
handlerFunctions = lib.filterAttrs isHandler cfg.functions;
|
||||
sourceFunction = name: def: "source ${config.xdg.configHome}/fish/functions/${name}.fish";
|
||||
in
|
||||
builtins.concatStringsSep "\n" (lib.mapAttrsToList sourceFunction handlerFunctions);
|
||||
|
||||
in
|
||||
{
|
||||
|
|
@ -726,6 +740,9 @@ in
|
|||
|
||||
source ${cfg.sessionVariablesPackage}/${sessionVarsFile}
|
||||
|
||||
# Source handler functions
|
||||
${sourceHandlersStr}
|
||||
|
||||
${cfg.shellInit}
|
||||
|
||||
status is-login; and begin
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@ in
|
|||
name = "Floorp";
|
||||
wrappedPackageName = "floorp-bin";
|
||||
unwrappedPackageName = "floorp-bin-unwrapped";
|
||||
visible = true;
|
||||
|
||||
platforms.linux = {
|
||||
configPath = ".floorp";
|
||||
|
|
|
|||
|
|
@ -332,21 +332,43 @@ in
|
|||
home.packages = lib.optionals (cfg.package != null) [ cfg.package ];
|
||||
|
||||
assertions = [
|
||||
{
|
||||
assertion =
|
||||
let
|
||||
enabled = [
|
||||
(config.programs.delta.enable && config.programs.delta.enableGitIntegration)
|
||||
(config.programs.diff-highlight.enable && config.programs.diff-highlight.enableGitIntegration)
|
||||
(config.programs.diff-so-fancy.enable && config.programs.diff-so-fancy.enableGitIntegration)
|
||||
(config.programs.difftastic.enable && config.programs.difftastic.git.enable)
|
||||
(config.programs.patdiff.enable && config.programs.patdiff.enableGitIntegration)
|
||||
(config.programs.riff.enable && config.programs.riff.enableGitIntegration)
|
||||
];
|
||||
in
|
||||
lib.count lib.id enabled <= 1;
|
||||
message = "Only one of 'programs.git.delta.enable' or 'programs.git.difftastic.enable' or 'programs.git.diff-so-fancy.enable' or 'programs.git.diff-highlight' or 'programs.git.patdiff' can be set to true at the same time.";
|
||||
}
|
||||
(
|
||||
let
|
||||
configOf =
|
||||
{
|
||||
name,
|
||||
gitIntegrationOption ? [ "enableGitIntegration" ],
|
||||
}:
|
||||
{
|
||||
name = "programs.${name}.${lib.concatStringsSep "." gitIntegrationOption}";
|
||||
value =
|
||||
config.programs.${name}.enable && lib.getAttrFromPath gitIntegrationOption config.programs.${name};
|
||||
};
|
||||
enabled = builtins.filter (x: x.value) (
|
||||
map configOf [
|
||||
{ name = "delta"; }
|
||||
{ name = "diff-highlight"; }
|
||||
{ name = "diff-so-fancy"; }
|
||||
{
|
||||
name = "difftastic";
|
||||
gitIntegrationOption = [
|
||||
"git"
|
||||
"enable"
|
||||
];
|
||||
}
|
||||
{ name = "patdiff"; }
|
||||
{ name = "riff"; }
|
||||
]
|
||||
);
|
||||
in
|
||||
{
|
||||
assertion = lib.length enabled <= 1;
|
||||
message = ''
|
||||
Only one of the following options can be enabled at a time.
|
||||
- ${lib.concatStringsSep "\n - " (map (x: "`${x.name}'") enabled)}
|
||||
'';
|
||||
}
|
||||
)
|
||||
];
|
||||
|
||||
xdg.configFile = {
|
||||
|
|
@ -380,7 +402,7 @@ in
|
|||
lib.nameValuePair "sendemail.${name}" (
|
||||
if account.msmtp.enable then
|
||||
{
|
||||
sendmailCmd = "${pkgs.msmtp}/bin/msmtp";
|
||||
sendmailCmd = lib.getExe config.programs.msmtp.package;
|
||||
envelopeSender = "auto";
|
||||
from = "${realName} <${address}>";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ in
|
|||
};
|
||||
description = ''
|
||||
Configuration settings for halloy. All available options can be
|
||||
found here: <https://halloy.chat/configuration/index.html>. Note that
|
||||
found here: <https://halloy.chat/configuration.html>. Note that
|
||||
halloy requires at least one `server` to be configured, see example.
|
||||
'';
|
||||
};
|
||||
|
|
|
|||
|
|
@ -239,7 +239,7 @@ let
|
|||
|
||||
in
|
||||
{
|
||||
meta.maintainers = with lib.maintainers; [ thiagokokada ];
|
||||
meta.maintainers = [ ];
|
||||
|
||||
options.programs.hexchat = {
|
||||
enable = lib.mkEnableOption "HexChat, a graphical IRC client";
|
||||
|
|
|
|||
|
|
@ -14,7 +14,6 @@ let
|
|||
in
|
||||
{
|
||||
meta.maintainers = with lib.maintainers; [
|
||||
thiagokokada
|
||||
workflow
|
||||
];
|
||||
|
||||
|
|
|
|||
|
|
@ -168,10 +168,52 @@ in
|
|||
in `kitty-themes`, without the `.conf` suffix. See
|
||||
<https://github.com/kovidgoyal/kitty-themes/tree/master/themes> for a
|
||||
list of themes.
|
||||
|
||||
Note that if any automatic themes are configured via
|
||||
`programs.kitty.autoThemeFiles`, Kitty will prefer them based on the
|
||||
OS color scheme and they will override other color and background image
|
||||
settings.
|
||||
'';
|
||||
example = "SpaceGray_Eighties";
|
||||
};
|
||||
|
||||
autoThemeFiles = mkOption {
|
||||
type = types.nullOr (
|
||||
types.submodule {
|
||||
options = {
|
||||
light = mkOption {
|
||||
type = types.str;
|
||||
description = "Theme name for light color scheme.";
|
||||
};
|
||||
dark = mkOption {
|
||||
type = types.str;
|
||||
description = "Theme name for dark color scheme.";
|
||||
};
|
||||
noPreference = mkOption {
|
||||
type = types.str;
|
||||
description = "Theme name for no-preference color scheme.";
|
||||
};
|
||||
};
|
||||
}
|
||||
);
|
||||
default = null;
|
||||
description = ''
|
||||
Configure Kitty automatic color themes. This creates
|
||||
{file}`$XDG_CONFIG_HOME/kitty/light-theme.auto.conf`,
|
||||
{file}`$XDG_CONFIG_HOME/kitty/dark-theme.auto.conf`, and
|
||||
{file}`$XDG_CONFIG_HOME/kitty/no-preference-theme.auto.conf`.
|
||||
Kitty applies these based on the OS color scheme, and they override
|
||||
other color and background image settings.
|
||||
'';
|
||||
example = literalExpression ''
|
||||
{
|
||||
light = "GitHub";
|
||||
dark = "TokyoNight";
|
||||
noPreference = "OneDark";
|
||||
}
|
||||
'';
|
||||
};
|
||||
|
||||
font = mkOption {
|
||||
type = types.nullOr lib.hm.types.fontType;
|
||||
default = null;
|
||||
|
|
@ -358,15 +400,35 @@ in
|
|||
'';
|
||||
};
|
||||
|
||||
home.activation.checkKittyTheme = mkIf (cfg.themeFile != null) (
|
||||
xdg.configFile."kitty/light-theme.auto.conf" = mkIf (cfg.autoThemeFiles != null) {
|
||||
text = "include ${pkgs.kitty-themes}/share/kitty-themes/themes/${cfg.autoThemeFiles.light}.conf\n";
|
||||
};
|
||||
|
||||
xdg.configFile."kitty/dark-theme.auto.conf" = mkIf (cfg.autoThemeFiles != null) {
|
||||
text = "include ${pkgs.kitty-themes}/share/kitty-themes/themes/${cfg.autoThemeFiles.dark}.conf\n";
|
||||
};
|
||||
|
||||
xdg.configFile."kitty/no-preference-theme.auto.conf" = mkIf (cfg.autoThemeFiles != null) {
|
||||
text = "include ${pkgs.kitty-themes}/share/kitty-themes/themes/${cfg.autoThemeFiles.noPreference}.conf\n";
|
||||
};
|
||||
|
||||
home.activation.checkKittyTheme = mkIf (cfg.themeFile != null || cfg.autoThemeFiles != null) (
|
||||
let
|
||||
themePath = "${pkgs.kitty-themes}/share/kitty-themes/themes/${cfg.themeFile}.conf";
|
||||
themePath = name: "${pkgs.kitty-themes}/share/kitty-themes/themes/${name}.conf";
|
||||
checkThemeFile = name: ''
|
||||
if [[ ! -f "${themePath name}" ]]; then
|
||||
errorEcho "kitty-themes does not contain the theme file ${themePath name}!"
|
||||
exit 1
|
||||
fi
|
||||
'';
|
||||
in
|
||||
lib.hm.dag.entryBefore [ "writeBoundary" ] ''
|
||||
if [[ ! -f "${themePath}" ]]; then
|
||||
errorEcho "kitty-themes does not contain the theme file ${themePath}!"
|
||||
exit 1
|
||||
fi
|
||||
${lib.optionalString (cfg.themeFile != null) (checkThemeFile cfg.themeFile)}
|
||||
${lib.optionalString (cfg.autoThemeFiles != null) ''
|
||||
${checkThemeFile cfg.autoThemeFiles.light}
|
||||
${checkThemeFile cfg.autoThemeFiles.dark}
|
||||
${checkThemeFile cfg.autoThemeFiles.noPreference}
|
||||
''}
|
||||
''
|
||||
);
|
||||
|
||||
|
|
|
|||
48
modules/programs/lazyworktree.nix
Normal file
48
modules/programs/lazyworktree.nix
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
{
|
||||
lib,
|
||||
pkgs,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (lib)
|
||||
mkIf
|
||||
mkEnableOption
|
||||
mkPackageOption
|
||||
mkOption
|
||||
;
|
||||
cfg = config.programs.lazyworktree;
|
||||
yamlFormat = pkgs.formats.yaml { };
|
||||
in
|
||||
{
|
||||
meta.maintainers = with lib.hm.maintainers; [ aguirre-matteo ];
|
||||
options.programs.lazyworktree = {
|
||||
enable = mkEnableOption "lazyworktree";
|
||||
package = mkPackageOption pkgs "lazyworktree" { nullable = true; };
|
||||
settings = mkOption {
|
||||
inherit (yamlFormat) type;
|
||||
default = { };
|
||||
example = {
|
||||
worktree_dir = "~/.local/share/worktrees";
|
||||
sort_mode = "switched";
|
||||
auto_fetch_prs = false;
|
||||
auto_refresh = true;
|
||||
refresh_interval = 10;
|
||||
icon_set = "nerd-font-v3";
|
||||
search_auto_select = false;
|
||||
fuzzy_finder_input = false;
|
||||
};
|
||||
description = ''
|
||||
Configuration settings for lazyworktree. All the available options can be found here:
|
||||
<https://github.com/chmouel/lazyworktree?tab=readme-ov-file#global-configuration-yaml>
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
home.packages = mkIf (cfg.package != null) [ cfg.package ];
|
||||
xdg.configFile."lazyworktree/config.yaml" = mkIf (cfg.settings != { }) {
|
||||
source = yamlFormat.generate "lazyworktree.yaml" cfg.settings;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -34,7 +34,6 @@ in
|
|||
description = "LibreWolf is a privacy enhanced Firefox fork.";
|
||||
wrappedPackageName = "librewolf";
|
||||
unwrappedPackageName = "librewolf-unwrapped";
|
||||
visible = true;
|
||||
|
||||
platforms.linux = {
|
||||
configPath = ".librewolf";
|
||||
|
|
|
|||
|
|
@ -21,7 +21,18 @@ in
|
|||
'';
|
||||
};
|
||||
|
||||
package = lib.mkPackageOption pkgs "man" { };
|
||||
package = mkOption {
|
||||
type = with types; nullOr package;
|
||||
default =
|
||||
if pkgs.stdenv.isDarwin && lib.versionAtLeast config.home.stateVersion "26.05" then
|
||||
null
|
||||
else
|
||||
pkgs.man;
|
||||
defaultText = lib.literalExpression ''
|
||||
if pkgs.stdenv.isDarwin && lib.versionAtLeast config.home.stateVersion "26.05" then null else pkgs.man
|
||||
'';
|
||||
description = "The {command}`man` package to use.";
|
||||
};
|
||||
|
||||
extraConfig = mkOption {
|
||||
type = types.lines;
|
||||
|
|
@ -51,11 +62,15 @@ in
|
|||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
home.packages = [ cfg.package ];
|
||||
warnings = lib.optional (
|
||||
cfg.generateCaches && cfg.package == null
|
||||
) "programs.man.generateCaches has no effect when programs.man.package is null";
|
||||
|
||||
home.packages = lib.optional (cfg.package != null) cfg.package;
|
||||
home.extraOutputsToInstall = [ "man" ];
|
||||
|
||||
# This is mostly copy/pasted/adapted from NixOS' documentation.nix.
|
||||
home.file = lib.mkIf cfg.generateCaches {
|
||||
home.file = lib.mkIf (cfg.generateCaches && cfg.package != null) {
|
||||
".manpath".text =
|
||||
let
|
||||
# Generate a directory containing installed packages' manpages.
|
||||
|
|
|
|||
64
modules/programs/mistral-vibe.nix
Normal file
64
modules/programs/mistral-vibe.nix
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
|
||||
cfg = config.programs.mistral-vibe;
|
||||
|
||||
settingsFormat = pkgs.formats.toml { };
|
||||
|
||||
in
|
||||
{
|
||||
meta.maintainers = [ lib.maintainers.GaetanLepage ];
|
||||
|
||||
options.programs.mistral-vibe = {
|
||||
enable = lib.mkEnableOption "Mistral Vibe, Mistral's open-source CLI coding assistant";
|
||||
|
||||
package = lib.mkPackageOption pkgs "mistral-vibe" { nullable = true; };
|
||||
|
||||
settings = lib.mkOption {
|
||||
type = settingsFormat.type;
|
||||
example = lib.literalExpression ''
|
||||
{
|
||||
active_model = "devstral-latest";
|
||||
vim_keybindings = false;
|
||||
tool_paths = [];
|
||||
|
||||
providers = [
|
||||
{
|
||||
name = "mistral";
|
||||
backend = "mistral";
|
||||
api_base = "https://api.mistral.ai/v1";
|
||||
api_key_env_var = "MISTRAL_API_KEY";
|
||||
api_style = "openai";
|
||||
}
|
||||
];
|
||||
|
||||
models = [
|
||||
{
|
||||
name = "devstral-latest";
|
||||
provider = "mistral";
|
||||
alias = "devstral-latest";
|
||||
temperature = 0.1;
|
||||
input_price = 0.4;
|
||||
output_price = 2.0;
|
||||
}
|
||||
];
|
||||
}
|
||||
'';
|
||||
description = ''
|
||||
Mistral Vibe configuration.
|
||||
For available settings see <https://github.com/mistralai/mistral-vibe>.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
home.packages = lib.mkIf (cfg.package != null) [ cfg.package ];
|
||||
|
||||
home.file.".vibe/config.toml".source = settingsFormat.generate "config.toml" cfg.settings;
|
||||
};
|
||||
}
|
||||
|
|
@ -67,7 +67,6 @@ let
|
|||
in
|
||||
{
|
||||
meta.maintainers = with lib.maintainers; [
|
||||
thiagokokada
|
||||
chuangzhu
|
||||
];
|
||||
|
||||
|
|
@ -139,11 +138,14 @@ in
|
|||
default = [ ];
|
||||
example = literalExpression ''
|
||||
[
|
||||
"~/path/to/config.inc";
|
||||
"~/path/to/conditional.inc";
|
||||
"~/path/to/config.inc"
|
||||
"~~/conditional.inc"
|
||||
]
|
||||
'';
|
||||
description = "List of configuration files to include at the end of mpv.conf.";
|
||||
description = ''
|
||||
List of configuration files to include at the end of mpv.conf.
|
||||
Mpv accepts several useful [prefixes](https://mpv.io/manual/stable/#paths).
|
||||
'';
|
||||
};
|
||||
|
||||
profiles = mkOption {
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ let
|
|||
};
|
||||
in
|
||||
{
|
||||
meta.maintainers = with lib.maintainers; [ thiagokokada ];
|
||||
meta.maintainers = [ ];
|
||||
|
||||
options = {
|
||||
programs.nnn = {
|
||||
|
|
@ -100,6 +100,14 @@ in
|
|||
'';
|
||||
default = { };
|
||||
};
|
||||
|
||||
enableBashIntegration = lib.hm.shell.mkBashIntegrationOption { inherit config; };
|
||||
|
||||
enableFishIntegration = lib.hm.shell.mkFishIntegrationOption { inherit config; };
|
||||
|
||||
enableZshIntegration = lib.hm.shell.mkZshIntegrationOption { inherit config; };
|
||||
|
||||
quitcd = lib.mkEnableOption "cd on quit";
|
||||
};
|
||||
};
|
||||
|
||||
|
|
@ -116,10 +124,25 @@ in
|
|||
--prefix NNN_PLUG : "${renderSettings cfg.plugins.mappings}"
|
||||
'';
|
||||
});
|
||||
|
||||
quitcd = {
|
||||
bash_sh_zsh = "source ${nnnPackage}/share/quitcd/quitcd.bash_sh_zsh";
|
||||
fish = "source ${nnnPackage}/share/quitcd/quitcd.fish";
|
||||
};
|
||||
in
|
||||
lib.mkIf cfg.enable {
|
||||
programs.nnn.finalPackage = nnnPackage;
|
||||
home.packages = [ nnnPackage ];
|
||||
xdg.configFile."nnn/plugins" = lib.mkIf (cfg.plugins.src != null) { source = cfg.plugins.src; };
|
||||
|
||||
programs.bash.initExtra = lib.mkIf (cfg.enableBashIntegration && cfg.quitcd) (
|
||||
lib.mkAfter quitcd.bash_sh_zsh
|
||||
);
|
||||
programs.fish.interactiveShellInit = lib.mkIf (cfg.enableFishIntegration && cfg.quitcd) (
|
||||
lib.mkAfter quitcd.fish
|
||||
);
|
||||
programs.zsh.initContent = lib.mkIf (cfg.enableZshIntegration && cfg.quitcd) (
|
||||
lib.mkAfter quitcd.bash_sh_zsh
|
||||
);
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -72,6 +72,8 @@ in
|
|||
programs.notmuch = {
|
||||
enable = lib.mkEnableOption "Notmuch mail indexer";
|
||||
|
||||
package = lib.mkPackageOption pkgs "notmuch" { };
|
||||
|
||||
new = mkOption {
|
||||
type = types.submodule {
|
||||
options = {
|
||||
|
|
@ -197,7 +199,7 @@ in
|
|||
}
|
||||
];
|
||||
|
||||
home.packages = [ pkgs.notmuch ];
|
||||
home.packages = [ cfg.package ];
|
||||
|
||||
home.sessionVariables = {
|
||||
NOTMUCH_CONFIG = "${config.xdg.configHome}/notmuch/default/config";
|
||||
|
|
@ -208,7 +210,7 @@ in
|
|||
let
|
||||
hook = name: cmds: {
|
||||
"notmuch/default/hooks/${name}".source = pkgs.writeShellScript name ''
|
||||
export PATH="${pkgs.notmuch}/bin''${PATH:+:}$PATH"
|
||||
export PATH="${cfg.package}/bin''${PATH:+:}$PATH"
|
||||
export NOTMUCH_CONFIG="${config.xdg.configHome}/notmuch/default/config"
|
||||
export NMBGIT="${config.xdg.dataHome}/notmuch/nmbug"
|
||||
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@
|
|||
}:
|
||||
let
|
||||
cfg = config.programs.pay-respects;
|
||||
payRespectsCmd = lib.getExe cfg.package;
|
||||
cfgOptions = lib.concatStringsSep " " cfg.options;
|
||||
|
||||
tomlFormat = pkgs.formats.toml { };
|
||||
in
|
||||
{
|
||||
meta.maintainers = [ lib.maintainers.ALameLlama ];
|
||||
|
|
@ -29,6 +29,49 @@ in
|
|||
'';
|
||||
};
|
||||
|
||||
rules = lib.mkOption {
|
||||
type = lib.types.attrsOf tomlFormat.type;
|
||||
default = { };
|
||||
example = lib.literalExpression ''
|
||||
{
|
||||
cargo = {
|
||||
command = "cargo";
|
||||
match_err = [
|
||||
{
|
||||
pattern = [ "run `cargo init` to initialize a new rust project" ];
|
||||
suggest = [ "cargo init" ];
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
_PR_GENERAL = {
|
||||
match_err = [
|
||||
{
|
||||
pattern = [ "permission denied" ];
|
||||
suggest = [
|
||||
"#[executable(sudo), !cmd_contains(sudo)]\nsudo {{command}}"
|
||||
];
|
||||
}
|
||||
];
|
||||
};
|
||||
}
|
||||
'';
|
||||
description = ''
|
||||
Runtime rule files written to
|
||||
{file}`$XDG_CONFIG_HOME/pay-respects/rules/<name>.toml`.
|
||||
|
||||
Attribute names map to filenames. For example, setting `rules.cargo = { ... };`
|
||||
creates {file}`$XDG_CONFIG_HOME/pay-respects/rules/cargo.toml`.
|
||||
The filename must match the command name, except for `_PR_GENERAL`.
|
||||
|
||||
See <https://github.com/iffse/pay-respects/blob/main/rules.md>
|
||||
for runtime rule syntax and behavior.
|
||||
|
||||
Note that these rules are only applied when the runtime-rules module is
|
||||
available to `pay-respects`.
|
||||
'';
|
||||
};
|
||||
|
||||
enableBashIntegration = lib.hm.shell.mkBashIntegrationOption { inherit config; };
|
||||
|
||||
enableFishIntegration = lib.hm.shell.mkFishIntegrationOption { inherit config; };
|
||||
|
|
@ -41,26 +84,38 @@ in
|
|||
config = lib.mkIf cfg.enable {
|
||||
home.packages = [ cfg.package ];
|
||||
|
||||
programs = {
|
||||
bash.initExtra = lib.mkIf cfg.enableBashIntegration ''
|
||||
eval "$(${payRespectsCmd} bash ${cfgOptions})"
|
||||
'';
|
||||
xdg.configFile = lib.mapAttrs' (
|
||||
name: rule:
|
||||
lib.nameValuePair "pay-respects/rules/${name}.toml" {
|
||||
source = tomlFormat.generate "pay-respects-rule-${name}.toml" rule;
|
||||
}
|
||||
) cfg.rules;
|
||||
|
||||
zsh.initContent = lib.mkIf cfg.enableZshIntegration ''
|
||||
eval "$(${payRespectsCmd} zsh ${cfgOptions})"
|
||||
'';
|
||||
programs =
|
||||
let
|
||||
payRespectsCmd = lib.getExe cfg.package;
|
||||
cfgOptions = lib.concatStringsSep " " cfg.options;
|
||||
in
|
||||
{
|
||||
bash.initExtra = lib.mkIf cfg.enableBashIntegration ''
|
||||
eval "$(${payRespectsCmd} bash ${cfgOptions})"
|
||||
'';
|
||||
|
||||
fish.interactiveShellInit = lib.mkIf cfg.enableFishIntegration ''
|
||||
${payRespectsCmd} fish ${cfgOptions} | source
|
||||
'';
|
||||
zsh.initContent = lib.mkIf cfg.enableZshIntegration ''
|
||||
eval "$(${payRespectsCmd} zsh ${cfgOptions})"
|
||||
'';
|
||||
|
||||
nushell.extraConfig = lib.mkIf cfg.enableNushellIntegration ''
|
||||
source ${
|
||||
pkgs.runCommand "pay-respects-nushell-config.nu" { } ''
|
||||
${payRespectsCmd} nushell ${cfgOptions} >> "$out"
|
||||
''
|
||||
}
|
||||
'';
|
||||
};
|
||||
fish.interactiveShellInit = lib.mkIf cfg.enableFishIntegration ''
|
||||
${payRespectsCmd} fish ${cfgOptions} | source
|
||||
'';
|
||||
|
||||
nushell.extraConfig = lib.mkIf cfg.enableNushellIntegration ''
|
||||
source ${
|
||||
pkgs.runCommand "pay-respects-nushell-config.nu" { } ''
|
||||
${payRespectsCmd} nushell ${cfgOptions} >> "$out"
|
||||
''
|
||||
}
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
|||
112
modules/programs/prismlauncher.nix
Normal file
112
modules/programs/prismlauncher.nix
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
inherit (pkgs.stdenv.hostPlatform) isDarwin;
|
||||
|
||||
inherit (lib)
|
||||
escapeShellArg
|
||||
listToAttrs
|
||||
literalExpression
|
||||
mkIf
|
||||
mkOption
|
||||
types
|
||||
;
|
||||
|
||||
cfg = config.programs.prismlauncher;
|
||||
|
||||
iniFormat = pkgs.formats.ini { };
|
||||
in
|
||||
|
||||
{
|
||||
meta.maintainers = with lib.hm.maintainers; [
|
||||
mikaeladev
|
||||
];
|
||||
|
||||
options.programs.prismlauncher = {
|
||||
enable = lib.mkEnableOption "Prism Launcher";
|
||||
|
||||
package = lib.mkPackageOption pkgs "prismlauncher" { nullable = true; };
|
||||
|
||||
extraPackages = mkOption {
|
||||
type = types.listOf types.package;
|
||||
default = [ ];
|
||||
description = ''
|
||||
Additional theme packages to install to the user environment.
|
||||
|
||||
Themes can be sourced from <https://github.com/PrismLauncher/Themes> and should
|
||||
install to `$out/share/PrismLauncher/{themes,iconthemes,catpacks}`.
|
||||
'';
|
||||
};
|
||||
|
||||
icons = mkOption {
|
||||
type = types.listOf types.path;
|
||||
default = [ ];
|
||||
example = literalExpression "[ ./java.png ]";
|
||||
description = ''
|
||||
List of paths to instance icons.
|
||||
|
||||
These will be linked in {file}`$XDG_DATA_HOME/PrismLauncher/icons` on Linux and
|
||||
{file}`~/Library/Application Support/PrismLauncher/icons` on macOS.
|
||||
'';
|
||||
};
|
||||
|
||||
settings = mkOption {
|
||||
type = types.attrsOf iniFormat.lib.types.atom;
|
||||
default = { };
|
||||
example = {
|
||||
ShowConsole = true;
|
||||
ConsoleMaxLines = 100000;
|
||||
};
|
||||
description = ''
|
||||
Configuration written to {file}`prismlauncher.cfg`.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config =
|
||||
let
|
||||
dataDir =
|
||||
if (isDarwin && !config.xdg.enable) then
|
||||
"Library/Application Support/PrismLauncher"
|
||||
else
|
||||
"${config.xdg.dataHome}/PrismLauncher";
|
||||
|
||||
impureConfigMerger = filePath: staticSettingsFile: emptySettingsFile: ''
|
||||
mkdir -p $(dirname '${escapeShellArg filePath}')
|
||||
|
||||
if [ ! -e '${escapeShellArg filePath}' ]; then
|
||||
cat '${escapeShellArg emptySettingsFile}' > '${escapeShellArg filePath}'
|
||||
fi
|
||||
|
||||
${lib.getExe pkgs.crudini} --merge --ini-options=nospace \
|
||||
'${escapeShellArg filePath}' < '${escapeShellArg staticSettingsFile}'
|
||||
'';
|
||||
in
|
||||
mkIf cfg.enable {
|
||||
home = {
|
||||
packages = lib.mkMerge ([ (mkIf (cfg.package != null) [ cfg.package ]) ] ++ cfg.extraPackages);
|
||||
|
||||
activation = lib.mkIf (cfg.settings != { }) {
|
||||
prismlauncherConfigActivation = lib.hm.dag.entryAfter [ "linkGeneration" ] (
|
||||
impureConfigMerger "${dataDir}/prismlauncher.cfg" (iniFormat.generate "prismlauncher-static.cfg" {
|
||||
General = cfg.settings;
|
||||
}) (iniFormat.generate "prismlauncher-empty.cfg" { General = { }; })
|
||||
);
|
||||
};
|
||||
|
||||
file = mkIf (cfg.icons != [ ]) (
|
||||
listToAttrs (
|
||||
map (source: {
|
||||
name = "${dataDir}/icons/${baseNameOf source}";
|
||||
value = { inherit source; };
|
||||
}) cfg.icons
|
||||
)
|
||||
);
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -136,7 +136,13 @@ in
|
|||
node = {
|
||||
alias = mkOption {
|
||||
type = str;
|
||||
description = "Human readable alias for your node.";
|
||||
description = ''
|
||||
Human readable alias for your node.
|
||||
|
||||
When running 'rad auth' for the first time, you need to use the exact same alias,
|
||||
otherwise 'rad auth' will fail because it cannot write the configuration
|
||||
file in your home directory (which is generated by nix).
|
||||
'';
|
||||
default = config.home.username;
|
||||
defaultText = lib.literalExpression "config.home.username";
|
||||
};
|
||||
|
|
|
|||
52
modules/programs/rizin.nix
Normal file
52
modules/programs/rizin.nix
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.programs.rizin;
|
||||
in
|
||||
{
|
||||
meta.maintainers = [
|
||||
lib.hm.maintainers.rsahwe
|
||||
];
|
||||
|
||||
options = {
|
||||
programs.rizin = {
|
||||
enable = lib.mkEnableOption "Rizin";
|
||||
|
||||
package = lib.mkPackageOption pkgs "rizin" { nullable = true; };
|
||||
|
||||
extraConfig = lib.mkOption {
|
||||
type = lib.types.lines;
|
||||
default = "";
|
||||
example = ''
|
||||
e asm.bytes=true
|
||||
e asm.bytes.space=true
|
||||
'';
|
||||
description = ''
|
||||
Run configuration written to {file}`rizinrc`.
|
||||
See <https://book.rizin.re/src/configuration/initial_scripts.html>
|
||||
for more information.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config =
|
||||
let
|
||||
configFile =
|
||||
if config.xdg.enable && config.home.preferXdgDirectories then
|
||||
"${config.xdg.configHome}/rizin/rizinrc"
|
||||
else
|
||||
".rizinrc";
|
||||
in
|
||||
lib.mkIf cfg.enable {
|
||||
home.packages = lib.mkIf (cfg.package != null) [ cfg.package ];
|
||||
|
||||
home.file.${configFile} = lib.mkIf (cfg.extraConfig != "") {
|
||||
text = cfg.extraConfig;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -275,8 +275,14 @@ in
|
|||
listOf (
|
||||
either str (submodule {
|
||||
options = {
|
||||
name = mkOption { type = str; };
|
||||
path = mkOption { type = str; };
|
||||
name = mkOption {
|
||||
type = str;
|
||||
description = "Name used to reference the custom mode in the mode list.";
|
||||
};
|
||||
path = mkOption {
|
||||
type = str;
|
||||
description = "Executable path for the custom rofi script mode.";
|
||||
};
|
||||
};
|
||||
})
|
||||
);
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@ let
|
|||
mkKeyValue = key: value: "${key} ${value}";
|
||||
listsAsDuplicateKeys = true;
|
||||
};
|
||||
|
||||
in
|
||||
{
|
||||
meta.maintainers = [ lib.maintainers.podocarp ];
|
||||
|
|
@ -58,24 +57,58 @@ in
|
|||
{file}`$XDG_CONFIG_HOME/sioyek/prefs_user.config`.
|
||||
See <https://github.com/ahrm/sioyek/blob/main/pdf_viewer/prefs.config>.
|
||||
'';
|
||||
type = types.attrsOf types.str;
|
||||
default = { };
|
||||
example = literalExpression ''
|
||||
{
|
||||
"background_color" = "1.0 1.0 1.0";
|
||||
"text_highlight_color" = "1.0 0.0 0.0";
|
||||
startup_commands = [
|
||||
"toggle_visual_scroll"
|
||||
"toggle_dark_mode"
|
||||
];
|
||||
}
|
||||
'';
|
||||
};
|
||||
type = types.submodule {
|
||||
freeformType = types.attrsOf types.str;
|
||||
|
||||
options.startup_commands = mkOption {
|
||||
description = ''
|
||||
Commands to be run upon startup. Will be written to {file}`$XDG_CONFIG_HOME/sioyek/prefs_user.config`.
|
||||
See <https://github.com/ahrm/sioyek/blob/a4ce95fd968804fbf6ff3befcbe0d9b972bd754c/pdf_viewer/prefs.config#L116>.
|
||||
'';
|
||||
type = types.either types.str (types.listOf types.str);
|
||||
apply =
|
||||
x:
|
||||
lib.warnIf (lib.isString x)
|
||||
"`programs.sioyek.config.startup_commands` should now be a list of strings instead of a string."
|
||||
x;
|
||||
default = [ ];
|
||||
example = [
|
||||
"toggle_visual_scroll"
|
||||
"toggle_dark_mode"
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable (
|
||||
let
|
||||
prefsCfg =
|
||||
cfg.config
|
||||
//
|
||||
lib.optionalAttrs (cfg.config.startup_commands != [ ] && !lib.isString cfg.config.startup_commands)
|
||||
{
|
||||
startup_commands = lib.concatStringsSep ";" cfg.config.startup_commands;
|
||||
};
|
||||
in
|
||||
lib.mkMerge [
|
||||
{ home.packages = [ cfg.package ]; }
|
||||
(mkIf (cfg.config != { }) {
|
||||
xdg.configFile."sioyek/prefs_user.config".text = renderConfig cfg.config;
|
||||
{
|
||||
home.packages = [ cfg.package ];
|
||||
}
|
||||
(mkIf (prefsCfg != { }) {
|
||||
xdg.configFile."sioyek/prefs_user.config".text = renderConfig prefsCfg;
|
||||
})
|
||||
(mkIf (cfg.bindings != { }) {
|
||||
xdg.configFile."sioyek/keys_user.config".text = renderConfig cfg.bindings;
|
||||
|
|
|
|||
84
modules/programs/tirith.nix
Normal file
84
modules/programs/tirith.nix
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.programs.tirith;
|
||||
yamlFormat = pkgs.formats.yaml { };
|
||||
in
|
||||
{
|
||||
meta.maintainers = with lib.maintainers; [ malik ];
|
||||
|
||||
options.programs.tirith = {
|
||||
enable = lib.mkEnableOption "Tirith, a shell security monitor";
|
||||
|
||||
package = lib.mkPackageOption pkgs "tirith" { };
|
||||
|
||||
allowlist = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
default = [ ];
|
||||
apply = builtins.filter (s: s != "");
|
||||
example = [
|
||||
"localhost"
|
||||
];
|
||||
description = ''
|
||||
List of allowed domains that bypass Tirith analysis.
|
||||
Written to `$XDG_CONFIG_HOME/tirith/allowlist`.
|
||||
'';
|
||||
};
|
||||
|
||||
policy = lib.mkOption {
|
||||
type = yamlFormat.type;
|
||||
default = { };
|
||||
example = lib.literalExpression ''
|
||||
{
|
||||
version = 1;
|
||||
fail_mode = "open";
|
||||
allow_bypass = true;
|
||||
severity_overrides = {
|
||||
docker_untrusted_registry = "CRITICAL";
|
||||
};
|
||||
}
|
||||
'';
|
||||
description = ''
|
||||
Tirith policy configuration.
|
||||
Written to `$XDG_CONFIG_HOME/tirith/policy.yaml`.
|
||||
|
||||
See <https://github.com/sheeki03/tirith/blob/main/docs/cookbook.md>
|
||||
for policy examples.
|
||||
'';
|
||||
};
|
||||
|
||||
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 ];
|
||||
|
||||
xdg.configFile = {
|
||||
"tirith/allowlist" = lib.mkIf (cfg.allowlist != [ ]) {
|
||||
text = (lib.concatStringsSep "\n" cfg.allowlist) + "\n";
|
||||
};
|
||||
|
||||
"tirith/policy.yaml" = lib.mkIf (cfg.policy != { }) {
|
||||
source = yamlFormat.generate "tirith-policy.yaml" cfg.policy;
|
||||
};
|
||||
};
|
||||
|
||||
programs.bash.initExtra = lib.mkIf cfg.enableBashIntegration ''
|
||||
eval "$(${lib.getExe cfg.package} init --shell bash)"
|
||||
'';
|
||||
|
||||
programs.fish.interactiveShellInit = lib.mkIf cfg.enableFishIntegration ''
|
||||
${lib.getExe cfg.package} init --shell fish | source
|
||||
'';
|
||||
|
||||
programs.zsh.initExtra = lib.mkIf cfg.enableZshIntegration ''
|
||||
eval "$(${lib.getExe cfg.package} init --shell zsh)"
|
||||
'';
|
||||
};
|
||||
}
|
||||
|
|
@ -92,7 +92,7 @@ let
|
|||
# rebind main key: ${prefix}
|
||||
unbind ${defaultPrefix}
|
||||
set -g prefix ${prefix}
|
||||
bind -n -N "Send the prefix key through to the application" \
|
||||
bind -N "Send the prefix key through to the application" \
|
||||
${prefix} send-prefix
|
||||
''
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,8 +17,11 @@ let
|
|||
mkBashIntegrationOption
|
||||
mkZshIntegrationOption
|
||||
mkFishIntegrationOption
|
||||
mkNushellIntegrationOption
|
||||
;
|
||||
|
||||
inherit (lib.hm.nushell) mkNushellInline;
|
||||
|
||||
cfg = config.programs.vivid;
|
||||
yamlFormat = pkgs.formats.yaml { };
|
||||
in
|
||||
|
|
@ -35,6 +38,7 @@ in
|
|||
enableBashIntegration = mkBashIntegrationOption { inherit config; };
|
||||
enableZshIntegration = mkZshIntegrationOption { inherit config; };
|
||||
enableFishIntegration = mkFishIntegrationOption { inherit config; };
|
||||
enableNushellIntegration = mkNushellIntegrationOption { inherit config; };
|
||||
|
||||
colorMode = mkOption {
|
||||
type =
|
||||
|
|
@ -160,5 +164,9 @@ in
|
|||
programs.fish.interactiveShellInit = mkIf cfg.enableFishIntegration ''
|
||||
set -gx LS_COLORS "$(${vividCommand})"
|
||||
'';
|
||||
|
||||
programs.nushell.environmentVariables = mkIf cfg.enableNushellIntegration {
|
||||
LS_COLORS = mkNushellInline vividCommand;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,8 +48,23 @@ in
|
|||
|
||||
shellWrapperName = lib.mkOption {
|
||||
type = types.str;
|
||||
default = "yy";
|
||||
example = "y";
|
||||
default =
|
||||
if lib.versionAtLeast config.home.stateVersion "26.05" then
|
||||
"y"
|
||||
else
|
||||
lib.warn ''
|
||||
The default value of `programs.yazi.shellWrapperName` has changed from `yy` to `y`.
|
||||
You are currently using the legacy default (`yy`) because `home.stateVersion` is less than "26.05".
|
||||
To silence this warning and keep legacy behavior, set:
|
||||
programs.yazi.shellWrapperName = "yy";
|
||||
To adopt the new default behavior, set:
|
||||
programs.yazi.shellWrapperName = "y";
|
||||
'' "yy";
|
||||
defaultText = literalExpression ''
|
||||
"y" for state version ≥ 26.05
|
||||
"yy" for state version < 26.05
|
||||
'';
|
||||
example = "yy";
|
||||
description = ''
|
||||
Name of the shell wrapper to be called.
|
||||
'';
|
||||
|
|
|
|||
|
|
@ -304,7 +304,7 @@ in
|
|||
(mkIf (!cfg.mutableUserSettings && mergedSettings != { }) {
|
||||
"zed/settings.json".source = jsonFormat.generate "zed-user-settings" mergedSettings;
|
||||
})
|
||||
(mkIf (!cfg.mutableUserKeymaps && cfg.userKeymaps != { }) {
|
||||
(mkIf (!cfg.mutableUserKeymaps && cfg.userKeymaps != [ ]) {
|
||||
"zed/keymap.json".source = jsonFormat.generate "zed-user-keymaps" cfg.userKeymaps;
|
||||
})
|
||||
(mkIf (!cfg.mutableUserTasks && cfg.userTasks != [ ]) {
|
||||
|
|
|
|||
|
|
@ -478,7 +478,10 @@ in
|
|||
}
|
||||
|
||||
{
|
||||
home.packages = [ cfg.package ] ++ lib.optional cfg.enableCompletion pkgs.nix-zsh-completions;
|
||||
home.packages = [
|
||||
cfg.package
|
||||
]
|
||||
++ lib.optional cfg.enableCompletion (lib.lowPrio pkgs.nix-zsh-completions);
|
||||
|
||||
# NOTE: Always include "main" highlighter with normal priority.
|
||||
# Option default priority will cause `main` to get dropped by customization.
|
||||
|
|
|
|||
|
|
@ -202,7 +202,9 @@ in
|
|||
"--activate=${if profile.isActive then "true" else "false"}"
|
||||
"--save-config=false"
|
||||
];
|
||||
KeepAlive = true;
|
||||
KeepAlive = {
|
||||
SuccessfulExit = true;
|
||||
};
|
||||
RunAtLoad = true;
|
||||
EnvironmentVariables.PATH = lib.makeBinPath [
|
||||
cfg.package
|
||||
|
|
|
|||
|
|
@ -39,10 +39,6 @@ in
|
|||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
assertions = [
|
||||
(lib.hm.assertions.assertPlatform "services.flameshot" pkgs lib.platforms.linux)
|
||||
];
|
||||
|
||||
home.packages = [ cfg.package ];
|
||||
|
||||
xdg.configFile = lib.mkIf (cfg.settings != { }) {
|
||||
|
|
@ -67,7 +63,7 @@ in
|
|||
|
||||
Service = {
|
||||
Environment = [ "PATH=${config.home.profileDirectory}/bin" ];
|
||||
ExecStart = "${cfg.package}/bin/flameshot";
|
||||
ExecStart = lib.getExe cfg.package;
|
||||
Restart = "on-abort";
|
||||
|
||||
# Sandboxing.
|
||||
|
|
@ -80,5 +76,18 @@ in
|
|||
SystemCallFilter = "@system-service";
|
||||
};
|
||||
};
|
||||
|
||||
launchd.agents.flameshot = {
|
||||
enable = true;
|
||||
config = {
|
||||
ProgramArguments = [ (lib.getExe cfg.package) ];
|
||||
KeepAlive = {
|
||||
Crashed = true;
|
||||
SuccessfulExit = false;
|
||||
};
|
||||
ProcessType = "Interactive";
|
||||
RunAtLoad = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -100,11 +100,11 @@ in
|
|||
default = with pkgs; [
|
||||
xdotool
|
||||
coreutils
|
||||
xorg.xprop
|
||||
xprop
|
||||
];
|
||||
defaultText = literalExpression "pkgs.xdotool pkgs.coreutils pkgs.xorg.xprop";
|
||||
defaultText = literalExpression "pkgs.xdotool pkgs.coreutils pkgs.xprop";
|
||||
example = literalExpression ''
|
||||
with pkgs; [ xdotool coreutils xorg.xprop ];
|
||||
with pkgs; [ xdotool coreutils xprop ];
|
||||
'';
|
||||
description = ''
|
||||
Extra packages needs to bring to the scope of fusuma service.
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ in
|
|||
primary = true;
|
||||
atomic = true;
|
||||
execute_after = [
|
||||
"''${pkgs.xorg.xrandr}/bin/xrandr --dpi 96"
|
||||
"''${lib.getExe pkgs.xrandr} --dpi 96"
|
||||
"''${pkgs.xmonad-with-packages}/bin/xmonad --restart";
|
||||
];
|
||||
}
|
||||
|
|
@ -56,7 +56,7 @@ in
|
|||
primary = true;
|
||||
atomic = true;
|
||||
execute_after = [
|
||||
"''${pkgs.xorg.xrandr}/bin/xrandr --dpi 120"
|
||||
"''${lib.getExe pkgs.xrandr} --dpi 120"
|
||||
"''${pkgs.xmonad-with-packages}/bin/xmonad --restart";
|
||||
];
|
||||
}
|
||||
|
|
@ -92,7 +92,7 @@ in
|
|||
ExecStart = "${lib.getExe cfg.package} watch -v";
|
||||
Restart = "always";
|
||||
RestartSec = "2s";
|
||||
Environment = [ "PATH=${pkgs.xorg.xrandr}/bin:${pkgs.bash}/bin" ];
|
||||
Environment = [ "PATH=${pkgs.xrandr}/bin:${pkgs.bash}/bin" ];
|
||||
};
|
||||
|
||||
Install = {
|
||||
|
|
|
|||
|
|
@ -161,7 +161,7 @@ in
|
|||
};
|
||||
}
|
||||
(mkIf (!cfg.xautolock.enable) {
|
||||
systemd.user.services.xss-lock.Service.ExecStartPre = "${pkgs.xorg.xset}/bin/xset s ${
|
||||
systemd.user.services.xss-lock.Service.ExecStartPre = "${lib.getExe pkgs.xset} s ${
|
||||
toString (cfg.inactiveInterval * 60)
|
||||
} ${toString cfg.xss-lock.screensaverCycle}";
|
||||
})
|
||||
|
|
|
|||
|
|
@ -825,40 +825,37 @@ in
|
|||
};
|
||||
};
|
||||
|
||||
launchd.agents =
|
||||
let
|
||||
# agent `syncthing` uses `${syncthing_dir}/${watch_file}` to notify agent `syncthing-init`
|
||||
watch_file = ".launchd_update_config";
|
||||
in
|
||||
{
|
||||
syncthing = {
|
||||
enable = true;
|
||||
config = {
|
||||
ProgramArguments = [
|
||||
"${pkgs.writers.writeBash "syncthing-wrapper" ''
|
||||
${copyKeys} # simulate systemd's `syncthing-init.Service.ExecStartPre`
|
||||
touch "${syncthing_dir}/${watch_file}" # notify syncthing-init agent
|
||||
exec ${lib.escapeShellArgs syncthingArgs}
|
||||
''}"
|
||||
];
|
||||
KeepAlive = {
|
||||
Crashed = true;
|
||||
SuccessfulExit = false;
|
||||
};
|
||||
ProcessType = "Background";
|
||||
};
|
||||
};
|
||||
|
||||
syncthing-init = {
|
||||
enable = cleanedConfig != { };
|
||||
config = {
|
||||
ProgramArguments = [ "${updateConfig}" ];
|
||||
WatchPaths = [
|
||||
"${config.home.homeDirectory}/Library/Application Support/Syncthing/${watch_file}"
|
||||
];
|
||||
launchd.agents = {
|
||||
syncthing = {
|
||||
enable = true;
|
||||
config = {
|
||||
ProgramArguments = [
|
||||
"${pkgs.writers.writeBash "syncthing-wrapper" ''
|
||||
${copyKeys} # simulate systemd's `syncthing-init.Service.ExecStartPre`
|
||||
exec ${lib.escapeShellArgs syncthingArgs}
|
||||
''}"
|
||||
];
|
||||
KeepAlive = {
|
||||
Crashed = true;
|
||||
SuccessfulExit = false;
|
||||
};
|
||||
ProcessType = "Background";
|
||||
StandardOutPath = "${config.home.homeDirectory}/Library/Logs/Syncthing/syncthing-stdout.log";
|
||||
StandardErrorPath = "${config.home.homeDirectory}/Library/Logs/Syncthing/syncthing-stderr.log";
|
||||
};
|
||||
};
|
||||
|
||||
syncthing-init = {
|
||||
enable = cleanedConfig != { };
|
||||
config = {
|
||||
ProgramArguments = [ "${updateConfig}" ];
|
||||
ProcessType = "Background";
|
||||
RunAtLoad = true;
|
||||
StandardOutPath = "${config.home.homeDirectory}/Library/Logs/Syncthing/syncthing-init-stdout.log";
|
||||
StandardErrorPath = "${config.home.homeDirectory}/Library/Logs/Syncthing/syncthing-init-stderr.log";
|
||||
};
|
||||
};
|
||||
};
|
||||
})
|
||||
|
||||
(lib.mkIf cfg.tray.enable {
|
||||
|
|
|
|||
|
|
@ -57,17 +57,19 @@ in
|
|||
systemd.user.services.tomat = {
|
||||
Unit = {
|
||||
Description = "Tomat Pomodoro server";
|
||||
After = [ "graphical.target" ];
|
||||
After = [ "graphical-session.target" ];
|
||||
PartOf = [ "graphical-session.target" ];
|
||||
};
|
||||
|
||||
Service = {
|
||||
ExecStart = "${lib.getExe cfg.package} daemon run";
|
||||
Restart = "always";
|
||||
RestartSec = 5;
|
||||
Environment = [ "PATH=${config.home.profileDirectory}/bin" ];
|
||||
};
|
||||
|
||||
Install = {
|
||||
WantedBy = [ "default.target" ];
|
||||
WantedBy = [ "graphical-session.target" ];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -113,7 +113,7 @@ let
|
|||
|
||||
in
|
||||
{
|
||||
meta.maintainers = [ lib.maintainers.offline ];
|
||||
meta.maintainers = [ ];
|
||||
|
||||
options = {
|
||||
services.xsuspender = {
|
||||
|
|
|
|||
|
|
@ -112,7 +112,7 @@ in
|
|||
in
|
||||
{
|
||||
NIX_PATH =
|
||||
if config.nix.enable && (config.nix.settings.use-xdg-base-directories or false) then
|
||||
if config.nix.useXdg then
|
||||
"${config.xdg.stateHome}/nix/defexpr/channels\${NIX_PATH:+:}$NIX_PATH"
|
||||
else
|
||||
"$HOME/.nix-defexpr/channels\${NIX_PATH:+:}$NIX_PATH";
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ let
|
|||
in
|
||||
"${n}: ${formatValue v}";
|
||||
|
||||
xrdbMerge = "${pkgs.xorg.xrdb}/bin/xrdb -merge ${cfg.path}";
|
||||
xrdbMerge = "${lib.getExe pkgs.xrdb} -merge ${cfg.path}";
|
||||
|
||||
in
|
||||
{
|
||||
|
|
|
|||
|
|
@ -150,7 +150,7 @@ in
|
|||
++ [ "-option ''" ]
|
||||
++ map (v: "-option '${v}'") options;
|
||||
in
|
||||
"${pkgs.xorg.setxkbmap}/bin/setxkbmap ${toString args}";
|
||||
"${lib.getExe pkgs.setxkbmap} ${toString args}";
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@ let
|
|||
"eza"
|
||||
"fastfetch"
|
||||
"feh"
|
||||
"flameshot"
|
||||
"fzf"
|
||||
"gallery-dl"
|
||||
"getconf"
|
||||
|
|
@ -103,6 +104,7 @@ let
|
|||
"mergiraf"
|
||||
"micro"
|
||||
"mise"
|
||||
"mistral-vibe"
|
||||
"mpv"
|
||||
"msmtp"
|
||||
"mu"
|
||||
|
|
|
|||
|
|
@ -64,9 +64,8 @@ let
|
|||
# Needed by pretty much all tests that have anything to do with fish.
|
||||
babelfish
|
||||
fish
|
||||
lndir
|
||||
;
|
||||
|
||||
xorg = super.xorg.overrideScope (self: super: { inherit (pkgs.xorg) lndir; });
|
||||
};
|
||||
|
||||
outer =
|
||||
|
|
|
|||
169
tests/flake.nix
169
tests/flake.nix
|
|
@ -1,169 +0,0 @@
|
|||
# This is an internal Nix Flake intended for use when running tests.
|
||||
#
|
||||
# You can build all tests or specific tests by running
|
||||
#
|
||||
# nix build --reference-lock-file flake.lock ./tests#test-all
|
||||
# nix build --reference-lock-file flake.lock ./tests#test-alacritty-empty-settings
|
||||
#
|
||||
# in the Home Manager project root directory.
|
||||
#
|
||||
# Similarly for integration tests
|
||||
#
|
||||
# nix build --reference-lock-file flake.lock ./tests#integration-test-all
|
||||
# nix build --reference-lock-file flake.lock ./tests#integration-test-standalone-standard-basics
|
||||
|
||||
{
|
||||
description = "Tests of Home Manager for Nix";
|
||||
|
||||
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||
|
||||
outputs =
|
||||
{ nixpkgs, ... }:
|
||||
let
|
||||
forAllSystems = nixpkgs.lib.genAttrs nixpkgs.lib.systems.flakeExposed;
|
||||
forCI = nixpkgs.lib.genAttrs [
|
||||
"aarch64-darwin"
|
||||
"x86_64-linux"
|
||||
];
|
||||
|
||||
testChunks =
|
||||
system:
|
||||
let
|
||||
pkgs = nixpkgs.legacyPackages.${system};
|
||||
inherit (pkgs) lib;
|
||||
|
||||
# Create chunked test packages for better CI parallelization
|
||||
tests = import ./. {
|
||||
inherit pkgs;
|
||||
# Disable big tests since this is only used for CI
|
||||
enableBig = false;
|
||||
};
|
||||
allTests = lib.attrNames tests.build;
|
||||
# Remove 'all' from the test list as it's a meta-package
|
||||
filteredTests = lib.filter (name: name != "all") allTests;
|
||||
# NOTE: Just a starting value, we can tweak this to find a good value.
|
||||
targetTestsPerChunk = 50;
|
||||
numChunks = lib.max 1 (
|
||||
builtins.ceil ((builtins.length filteredTests) / (targetTestsPerChunk * 1.0))
|
||||
);
|
||||
chunkSize = builtins.ceil ((builtins.length filteredTests) / (numChunks * 1.0));
|
||||
|
||||
makeChunk =
|
||||
chunkNum: testList:
|
||||
let
|
||||
start = (chunkNum - 1) * chunkSize;
|
||||
end = lib.min (start + chunkSize) (builtins.length testList);
|
||||
chunkTests = lib.sublist start (end - start) testList;
|
||||
chunkAttrs = lib.genAttrs chunkTests (name: tests.build.${name});
|
||||
in
|
||||
pkgs.symlinkJoin {
|
||||
name = "test-chunk-${toString chunkNum}";
|
||||
paths = lib.attrValues chunkAttrs;
|
||||
passthru.tests = chunkTests;
|
||||
};
|
||||
in
|
||||
lib.listToAttrs (
|
||||
lib.genList (
|
||||
i: lib.nameValuePair "test-chunk-${toString (i + 1)}" (makeChunk (i + 1) filteredTests)
|
||||
) numChunks
|
||||
);
|
||||
|
||||
integrationTests =
|
||||
system:
|
||||
let
|
||||
pkgs = nixpkgs.legacyPackages.${system};
|
||||
inherit (pkgs) lib;
|
||||
in
|
||||
lib.optionalAttrs pkgs.stdenv.hostPlatform.isLinux (
|
||||
let
|
||||
tests = import ./integration { inherit pkgs lib; };
|
||||
renameTestPkg = n: v: lib.nameValuePair "integration-${n}" v;
|
||||
in
|
||||
lib.mapAttrs' renameTestPkg (lib.removeAttrs tests [ "all" ])
|
||||
);
|
||||
|
||||
# Test group definitions
|
||||
buildTests =
|
||||
system:
|
||||
let
|
||||
pkgs = nixpkgs.legacyPackages.${system};
|
||||
tests = import ./. { inherit pkgs; };
|
||||
renameTestPkg = n: nixpkgs.lib.nameValuePair "test-${n}";
|
||||
in
|
||||
nixpkgs.lib.mapAttrs' renameTestPkg tests.build;
|
||||
|
||||
buildTestsNoBig =
|
||||
system:
|
||||
let
|
||||
pkgs = nixpkgs.legacyPackages.${system};
|
||||
tests = import ./. {
|
||||
inherit pkgs;
|
||||
enableBig = false;
|
||||
};
|
||||
in
|
||||
{
|
||||
test-all-enableBig-false-enableLegacyIfd-false = tests.build.all;
|
||||
};
|
||||
|
||||
buildTestsNoBigIfd =
|
||||
system:
|
||||
let
|
||||
pkgs = nixpkgs.legacyPackages.${system};
|
||||
tests = import ./. {
|
||||
inherit pkgs;
|
||||
enableBig = false;
|
||||
enableLegacyIfd = true;
|
||||
};
|
||||
in
|
||||
{
|
||||
test-all-enableBig-false-enableLegacyIfd-true = tests.build.all;
|
||||
};
|
||||
|
||||
integrationTestPackages =
|
||||
system:
|
||||
let
|
||||
pkgs = nixpkgs.legacyPackages.${system};
|
||||
inherit (pkgs) lib;
|
||||
tests = import ./integration { inherit pkgs lib; };
|
||||
renameTestPkg = n: lib.nameValuePair "integration-test-${n}";
|
||||
in
|
||||
lib.mapAttrs' renameTestPkg tests;
|
||||
|
||||
in
|
||||
{
|
||||
# TODO: increase buildbot testing scope
|
||||
buildbot = forCI (
|
||||
system:
|
||||
let
|
||||
allIntegrationTests = integrationTests system;
|
||||
workingIntegrationTests = nixpkgs.lib.filterAttrs (
|
||||
name: _:
|
||||
nixpkgs.lib.elem name [
|
||||
"integration-nixos-basics"
|
||||
"integration-nixos-legacy-profile-management"
|
||||
]
|
||||
) allIntegrationTests;
|
||||
in
|
||||
(testChunks system) // workingIntegrationTests
|
||||
);
|
||||
|
||||
devShells = forAllSystems (
|
||||
system:
|
||||
let
|
||||
pkgs = nixpkgs.legacyPackages.${system};
|
||||
tests = import ./. { inherit pkgs; };
|
||||
in
|
||||
tests.run
|
||||
);
|
||||
|
||||
packages = forAllSystems (
|
||||
system:
|
||||
(buildTests system)
|
||||
// (integrationTestPackages system)
|
||||
// (buildTestsNoBig system)
|
||||
// (buildTestsNoBigIfd system)
|
||||
// (testChunks system)
|
||||
// (integrationTests system)
|
||||
);
|
||||
};
|
||||
}
|
||||
17
tests/integration/standalone/kitty-auto-theme-bad-home.nix
Normal file
17
tests/integration/standalone/kitty-auto-theme-bad-home.nix
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
{
|
||||
home.username = "alice";
|
||||
home.homeDirectory = "/home/alice";
|
||||
home.stateVersion = "24.11";
|
||||
|
||||
# Let Home Manager install and manage itself.
|
||||
programs.home-manager.enable = true;
|
||||
|
||||
programs.kitty = {
|
||||
enable = true;
|
||||
autoThemeFiles = {
|
||||
light = "GitHub";
|
||||
dark = "No Such Theme";
|
||||
noPreference = "OneDark";
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -59,6 +59,14 @@
|
|||
assert expected in actual, \
|
||||
f"expected home-manager switch to contain {expected}, but got {actual}"
|
||||
|
||||
with subtest("Switch to Bad Kitty Auto Theme"):
|
||||
succeed_as_alice("cp ${./kitty-auto-theme-bad-home.nix} /home/alice/.config/home-manager/home.nix")
|
||||
|
||||
actual = fail_as_alice("home-manager switch")
|
||||
expected = "kitty-themes does not contain the theme file"
|
||||
assert expected in actual, \
|
||||
f"expected home-manager switch to contain {expected}, but got {actual}"
|
||||
|
||||
with subtest("Switch to Good Kitty"):
|
||||
succeed_as_alice("cp ${./kitty-theme-good-home.nix} /home/alice/.config/home-manager/home.nix")
|
||||
|
||||
|
|
|
|||
|
|
@ -2,5 +2,7 @@
|
|||
lib-types-dag-submodule = ./dag-submodule.nix;
|
||||
lib-types-dag-merge = ./dag-merge.nix;
|
||||
|
||||
lib-types-either-suboptions-docs-lib = ./either-suboptions-docs-lib.nix;
|
||||
|
||||
lib-types-gvariant-merge = ./gvariant-merge.nix;
|
||||
}
|
||||
|
|
|
|||
49
tests/lib/types/either-suboptions-docs-lib.nix
Normal file
49
tests/lib/types/either-suboptions-docs-lib.nix
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
inherit (lib) mkOption;
|
||||
|
||||
docs = import ../../../docs {
|
||||
inherit pkgs lib;
|
||||
inherit (config.home.version) release isReleaseBranch;
|
||||
};
|
||||
|
||||
inherit (docs._internal.docsLib) types;
|
||||
|
||||
scalarOrSubmodule = types.either types.str (
|
||||
types.submodule {
|
||||
options = {
|
||||
foo = mkOption { type = types.str; };
|
||||
bar = mkOption { type = types.int; };
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
scalarOrSubmoduleSubOptions = scalarOrSubmodule.getSubOptions [ ];
|
||||
nullOrScalarOrSubmoduleSubOptions = (types.nullOr scalarOrSubmodule).getSubOptions [ ];
|
||||
in
|
||||
{
|
||||
assertions = [
|
||||
{
|
||||
assertion = scalarOrSubmoduleSubOptions ? foo;
|
||||
message = "docsLib.types.either should expose submodule options when one side is scalar.";
|
||||
}
|
||||
{
|
||||
assertion = scalarOrSubmoduleSubOptions ? bar;
|
||||
message = "docsLib.types.either should expose all submodule options when one side is scalar.";
|
||||
}
|
||||
{
|
||||
assertion = nullOrScalarOrSubmoduleSubOptions ? foo;
|
||||
message = "docsLib.types.nullOr (types.either ...) should keep submodule options visible.";
|
||||
}
|
||||
{
|
||||
assertion = nullOrScalarOrSubmoduleSubOptions ? bar;
|
||||
message = "docsLib.types.nullOr (types.either ...) should keep all submodule options visible.";
|
||||
}
|
||||
];
|
||||
}
|
||||
|
|
@ -5,4 +5,5 @@
|
|||
nix-keep-old-nix-path = ./keep-old-nix-path.nix;
|
||||
nix-example-channels = ./example-channels.nix;
|
||||
nix-example-channels-xdg = ./example-channels-xdg.nix;
|
||||
nix-use-xdg = ./use-xdg.nix;
|
||||
}
|
||||
|
|
|
|||
92
tests/modules/misc/nix/use-xdg.nix
Normal file
92
tests/modules/misc/nix/use-xdg.nix
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
{ lib, pkgs, ... }:
|
||||
let
|
||||
nixosLib = import /${pkgs.path}/nixos/lib { inherit lib; };
|
||||
getUseXdg =
|
||||
osNix: userNix:
|
||||
(nixosLib.evalTest {
|
||||
hostPkgs = pkgs;
|
||||
nodes.machine.imports = [
|
||||
../../../../nixos
|
||||
{
|
||||
nix = osNix;
|
||||
home-manager.users.user = {
|
||||
home.stateVersion = "26.05";
|
||||
nix = userNix;
|
||||
};
|
||||
}
|
||||
];
|
||||
}).config.nodes.machine.home-manager.users.user.nix.useXdg;
|
||||
in
|
||||
{
|
||||
nmt.script =
|
||||
# Defaults to false
|
||||
assert !getUseXdg { } { };
|
||||
|
||||
# Test OS config
|
||||
assert !getUseXdg { enable = true; } { };
|
||||
assert
|
||||
!getUseXdg {
|
||||
enable = false;
|
||||
settings.use-xdg-base-directories = true;
|
||||
} { };
|
||||
assert getUseXdg {
|
||||
enable = true;
|
||||
settings.use-xdg-base-directories = true;
|
||||
} { };
|
||||
|
||||
# Test user config
|
||||
assert !getUseXdg { } { enable = true; };
|
||||
assert
|
||||
!getUseXdg { } {
|
||||
enable = false;
|
||||
settings.use-xdg-base-directories = true;
|
||||
};
|
||||
assert getUseXdg { } {
|
||||
enable = true;
|
||||
settings.use-xdg-base-directories = true;
|
||||
};
|
||||
|
||||
# Fallback to OS config if user config is unset
|
||||
assert getUseXdg
|
||||
{
|
||||
enable = true;
|
||||
settings.use-xdg-base-directories = true;
|
||||
}
|
||||
{
|
||||
enable = true;
|
||||
};
|
||||
|
||||
# But user config takes precedence
|
||||
assert
|
||||
!getUseXdg
|
||||
{
|
||||
enable = true;
|
||||
settings.use-xdg-base-directories = true;
|
||||
}
|
||||
{
|
||||
enable = true;
|
||||
settings.use-xdg-base-directories = false;
|
||||
};
|
||||
assert getUseXdg
|
||||
{
|
||||
enable = true;
|
||||
settings.use-xdg-base-directories = false;
|
||||
}
|
||||
{
|
||||
enable = true;
|
||||
settings.use-xdg-base-directories = true;
|
||||
};
|
||||
|
||||
# assumeXdg also takes precedence
|
||||
assert getUseXdg { } { assumeXdg = true; };
|
||||
assert getUseXdg
|
||||
{
|
||||
enable = true;
|
||||
settings.use-xdg-base-directories = false;
|
||||
}
|
||||
{
|
||||
enable = false;
|
||||
assumeXdg = true;
|
||||
};
|
||||
"";
|
||||
}
|
||||
|
|
@ -4,4 +4,7 @@
|
|||
xdg-mime-disabled = ./mime-disabled.nix;
|
||||
xdg-autostart = ./autostart.nix;
|
||||
xdg-autostart-readonly = ./autostart-readonly.nix;
|
||||
xdg-user-dirs-mixed = ./user-dirs-mixed.nix;
|
||||
xdg-user-dirs-null = ./user-dirs-null.nix;
|
||||
xdg-user-dirs-short = ./user-dirs-short.nix;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
xdg-mime-apps-basics = ./mime-apps-basics.nix;
|
||||
xdg-system-dirs = ./system-dirs.nix;
|
||||
xdg-desktop-entries = ./desktop-entries.nix;
|
||||
xdg-user-dirs-null = ./user-dirs-null.nix;
|
||||
xdg-portal = ./portal.nix;
|
||||
xdg-mime = ./mime.nix;
|
||||
xdg-mime-package = ./mime-packages.nix;
|
||||
|
|
|
|||
35
tests/modules/misc/xdg/user-dirs-mixed.nix
Normal file
35
tests/modules/misc/xdg/user-dirs-mixed.nix
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
{
|
||||
config,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
|
||||
{
|
||||
config = {
|
||||
home.stateVersion = "25.11";
|
||||
|
||||
xdg.userDirs = {
|
||||
enable = true;
|
||||
extraConfig.PROJECTS = "${config.home.homeDirectory}/Projects";
|
||||
## This will trigger a warning.
|
||||
extraConfig.XDG_MISC_DIR = "${config.home.homeDirectory}/Misc";
|
||||
};
|
||||
|
||||
nmt.script = ''
|
||||
configFile=home-files/.config/user-dirs.dirs
|
||||
assertFileExists $configFile
|
||||
assertFileContent $configFile ${pkgs.writeText "expected" ''
|
||||
XDG_DESKTOP_DIR="/home/hm-user/Desktop"
|
||||
XDG_DOCUMENTS_DIR="/home/hm-user/Documents"
|
||||
XDG_DOWNLOAD_DIR="/home/hm-user/Downloads"
|
||||
XDG_MISC_DIR="/home/hm-user/Misc"
|
||||
XDG_MUSIC_DIR="/home/hm-user/Music"
|
||||
XDG_PICTURES_DIR="/home/hm-user/Pictures"
|
||||
XDG_PROJECTS_DIR="/home/hm-user/Projects"
|
||||
XDG_PUBLICSHARE_DIR="/home/hm-user/Public"
|
||||
XDG_TEMPLATES_DIR="/home/hm-user/Templates"
|
||||
XDG_VIDEOS_DIR="/home/hm-user/Videos"
|
||||
''}
|
||||
'';
|
||||
};
|
||||
}
|
||||
30
tests/modules/misc/xdg/user-dirs-short.nix
Normal file
30
tests/modules/misc/xdg/user-dirs-short.nix
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
{
|
||||
config,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
|
||||
{
|
||||
config = {
|
||||
xdg.userDirs = {
|
||||
enable = true;
|
||||
extraConfig.PROJECTS = "${config.home.homeDirectory}/Projects";
|
||||
};
|
||||
|
||||
nmt.script = ''
|
||||
configFile=home-files/.config/user-dirs.dirs
|
||||
assertFileExists $configFile
|
||||
assertFileContent $configFile ${pkgs.writeText "expected" ''
|
||||
XDG_DESKTOP_DIR="/home/hm-user/Desktop"
|
||||
XDG_DOCUMENTS_DIR="/home/hm-user/Documents"
|
||||
XDG_DOWNLOAD_DIR="/home/hm-user/Downloads"
|
||||
XDG_MUSIC_DIR="/home/hm-user/Music"
|
||||
XDG_PICTURES_DIR="/home/hm-user/Pictures"
|
||||
XDG_PROJECTS_DIR="/home/hm-user/Projects"
|
||||
XDG_PUBLICSHARE_DIR="/home/hm-user/Public"
|
||||
XDG_TEMPLATES_DIR="/home/hm-user/Templates"
|
||||
XDG_VIDEOS_DIR="/home/hm-user/Videos"
|
||||
''}
|
||||
'';
|
||||
};
|
||||
}
|
||||
|
|
@ -8,16 +8,6 @@
|
|||
profileExtra = "profile extra commands";
|
||||
};
|
||||
|
||||
nixpkgs.overlays = [
|
||||
(self: super: {
|
||||
xorg = super.xorg // {
|
||||
setxkbmap = super.xorg.setxkbmap // {
|
||||
outPath = "@setxkbmap@";
|
||||
};
|
||||
};
|
||||
})
|
||||
];
|
||||
|
||||
nmt.script = ''
|
||||
assertFileExists home-files/.xprofile
|
||||
assertFileContent \
|
||||
|
|
|
|||
|
|
@ -17,16 +17,6 @@
|
|||
profileExtra = "profile extra commands";
|
||||
};
|
||||
|
||||
nixpkgs.overlays = [
|
||||
(self: super: {
|
||||
xorg = super.xorg // {
|
||||
setxkbmap = super.xorg.setxkbmap // {
|
||||
outPath = "@setxkbmap@";
|
||||
};
|
||||
};
|
||||
})
|
||||
];
|
||||
|
||||
nmt.script = ''
|
||||
assertFileExists home-files/.config/systemd/user/setxkbmap.service
|
||||
assertFileContent \
|
||||
|
|
|
|||
|
|
@ -38,14 +38,14 @@
|
|||
assertFileExists home-files/.claude/commands/path-command.md
|
||||
assertFileExists home-files/.claude/agents/inline-agent.md
|
||||
assertFileExists home-files/.claude/agents/path-agent.md
|
||||
assertFileExists home-files/.claude/skills/inline-skill.md
|
||||
assertFileExists home-files/.claude/skills/path-skill.md
|
||||
assertFileExists home-files/.claude/skills/inline-skill/SKILL.md
|
||||
assertFileExists home-files/.claude/skills/path-skill/SKILL.md
|
||||
|
||||
assertFileContent home-files/.claude/commands/path-command.md \
|
||||
${./test-command.md}
|
||||
assertFileContent home-files/.claude/agents/path-agent.md \
|
||||
${./test-agent.md}
|
||||
assertFileContent home-files/.claude/skills/path-skill.md \
|
||||
assertFileContent home-files/.claude/skills/path-skill/SKILL.md \
|
||||
${./test-skill.md}
|
||||
'';
|
||||
}
|
||||
|
|
|
|||
12
tests/modules/programs/claude-code/skill-subdir/SKILL.md
Normal file
12
tests/modules/programs/claude-code/skill-subdir/SKILL.md
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
---
|
||||
name: data-processing
|
||||
description: Process and transform structured data files.
|
||||
---
|
||||
|
||||
# Data Processing Skill
|
||||
|
||||
Use this skill for data-processing tasks.
|
||||
|
||||
## Supporting files
|
||||
- `extract.md`: extraction workflow details
|
||||
- `convert.md`: conversion workflow details
|
||||
|
|
@ -5,10 +5,10 @@
|
|||
};
|
||||
|
||||
nmt.script = ''
|
||||
assertFileExists home-files/.claude/skills/test-skill.md
|
||||
assertLinkExists home-files/.claude/skills/test-skill.md
|
||||
assertFileExists home-files/.claude/skills/test-skill/SKILL.md
|
||||
assertLinkExists home-files/.claude/skills/test-skill/SKILL.md
|
||||
assertFileContent \
|
||||
home-files/.claude/skills/test-skill.md \
|
||||
${./skills/test-skill.md}
|
||||
home-files/.claude/skills/test-skill/SKILL.md \
|
||||
${./skills/test-skill/SKILL.md}
|
||||
'';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@
|
|||
};
|
||||
|
||||
nmt.script = ''
|
||||
assertFileExists home-files/.claude/skills/test-skill.md
|
||||
assertFileContent home-files/.claude/skills/test-skill.md \
|
||||
assertFileExists home-files/.claude/skills/test-skill/SKILL.md
|
||||
assertFileContent home-files/.claude/skills/test-skill/SKILL.md \
|
||||
${./test-skill.md}
|
||||
'';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,10 +7,15 @@
|
|||
};
|
||||
|
||||
nmt.script = ''
|
||||
assertFileExists home-files/.claude/skills/data-processing/SKILL.md
|
||||
assertFileExists home-files/.claude/skills/data-processing/extract.md
|
||||
assertFileExists home-files/.claude/skills/data-processing/convert.md
|
||||
assertLinkExists home-files/.claude/skills/data-processing/SKILL.md
|
||||
assertLinkExists home-files/.claude/skills/data-processing/extract.md
|
||||
assertLinkExists home-files/.claude/skills/data-processing/convert.md
|
||||
assertFileContent \
|
||||
home-files/.claude/skills/data-processing/SKILL.md \
|
||||
${./skill-subdir/SKILL.md}
|
||||
assertFileContent \
|
||||
home-files/.claude/skills/data-processing/extract.md \
|
||||
${./skill-subdir/extract.md}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@
|
|||
codex-custom-instructions = ./custom-instructions.nix;
|
||||
codex-custom-instructions-prefer-xdg-directories = ./custom-instructions-prefer-xdg-directories.nix;
|
||||
codex-empty-custom-instructions = ./empty-custom-instructions.nix;
|
||||
codex-mcp-integration = ./mcp-integration.nix;
|
||||
codex-mcp-integration-with-override = ./mcp-integration-with-override.nix;
|
||||
codex-skills-inline = ./skills-inline.nix;
|
||||
codex-skills-dir = ./skills-dir.nix;
|
||||
codex-skills-path-not-directory = ./skills-path-not-directory.nix;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,49 @@
|
|||
{
|
||||
programs.mcp = {
|
||||
enable = true;
|
||||
servers = {
|
||||
everything = {
|
||||
command = "npx";
|
||||
args = [
|
||||
"-y"
|
||||
"@modelcontextprotocol/server-everything"
|
||||
];
|
||||
};
|
||||
context7 = {
|
||||
url = "https://mcp.context7.com/mcp";
|
||||
headers = {
|
||||
CONTEXT7_API_KEY = "{env:CONTEXT7_API_KEY}";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
programs.codex = {
|
||||
enable = true;
|
||||
enableMcpIntegration = true;
|
||||
settings = {
|
||||
model = "gpt-5-codex";
|
||||
mcp_servers = {
|
||||
custom-server = {
|
||||
url = "http://localhost:3000/mcp";
|
||||
enabled = true;
|
||||
enabled_tools = [
|
||||
"open"
|
||||
"screenshot"
|
||||
];
|
||||
};
|
||||
everything = {
|
||||
command = "final-command";
|
||||
enabled = false;
|
||||
tool_timeout_sec = 45;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
nmt.script = ''
|
||||
assertFileExists home-files/.codex/config.toml
|
||||
assertFileContent home-files/.codex/config.toml \
|
||||
${./mcp-integration-with-override.toml}
|
||||
'';
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
model = "gpt-5-codex"
|
||||
|
||||
[mcp_servers.context7]
|
||||
enabled = true
|
||||
url = "https://mcp.context7.com/mcp"
|
||||
|
||||
[mcp_servers.context7.http_headers]
|
||||
CONTEXT7_API_KEY = "{env:CONTEXT7_API_KEY}"
|
||||
|
||||
[mcp_servers.custom-server]
|
||||
enabled = true
|
||||
enabled_tools = ["open", "screenshot"]
|
||||
url = "http://localhost:3000/mcp"
|
||||
|
||||
[mcp_servers.everything]
|
||||
command = "final-command"
|
||||
enabled = false
|
||||
tool_timeout_sec = 45
|
||||
36
tests/modules/programs/codex/mcp-integration.nix
Normal file
36
tests/modules/programs/codex/mcp-integration.nix
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
{
|
||||
programs.mcp = {
|
||||
enable = true;
|
||||
servers = {
|
||||
everything = {
|
||||
command = "npx";
|
||||
args = [
|
||||
"-y"
|
||||
"@modelcontextprotocol/server-everything"
|
||||
];
|
||||
};
|
||||
context7 = {
|
||||
url = "https://mcp.context7.com/mcp";
|
||||
headers = {
|
||||
CONTEXT7_API_KEY = "{env:CONTEXT7_API_KEY}";
|
||||
};
|
||||
};
|
||||
disabled-server = {
|
||||
command = "echo";
|
||||
args = [ "test" ];
|
||||
disabled = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
programs.codex = {
|
||||
enable = true;
|
||||
enableMcpIntegration = true;
|
||||
};
|
||||
|
||||
nmt.script = ''
|
||||
assertFileExists home-files/.codex/config.toml
|
||||
assertFileContent home-files/.codex/config.toml \
|
||||
${./mcp-integration.toml}
|
||||
'';
|
||||
}
|
||||
16
tests/modules/programs/codex/mcp-integration.toml
Normal file
16
tests/modules/programs/codex/mcp-integration.toml
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
[mcp_servers.context7]
|
||||
enabled = true
|
||||
url = "https://mcp.context7.com/mcp"
|
||||
|
||||
[mcp_servers.context7.http_headers]
|
||||
CONTEXT7_API_KEY = "{env:CONTEXT7_API_KEY}"
|
||||
|
||||
[mcp_servers.disabled-server]
|
||||
args = ["test"]
|
||||
command = "echo"
|
||||
enabled = false
|
||||
|
||||
[mcp_servers.everything]
|
||||
args = ["-y", "@modelcontextprotocol/server-everything"]
|
||||
command = "npx"
|
||||
enabled = true
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue