Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
70 commits
Select commit Hold shift + click to select a range
028b3e4
docs(wrapperModules.neovim): actual link to template in docs (#379)
BirdeeHub Mar 25, 2026
5464597
docs(wrapperModules.neovim): add basic example to docs page as well (…
BirdeeHub Mar 25, 2026
15d740b
docs(modules.constructFiles): explain `.key` further (#382)
BirdeeHub Mar 26, 2026
89c7dea
feat(wrapperModules.emacs): init (#381)
boundless-recursion Mar 27, 2026
ea66fed
fix(wrapperModules.emacs): conditional for setting --init-directory (…
BirdeeHub Mar 27, 2026
9de61fe
docs(wrapperModules.emacs): docs escaping for readability (#385)
BirdeeHub Mar 27, 2026
364e000
docs(wrapperModules.emacs): Remove misleading documentation (#384)
boundless-recursion Mar 27, 2026
24e250b
chore(deps): update flake.lock files (#388)
BirdeeHub Mar 29, 2026
23b8770
feat(wrapperModules.tofi): init (#387)
nikitawootten Mar 29, 2026
01cb23e
feat(lib.toKdl): and update niri to use it (#386)
BirdeeHub Mar 29, 2026
70795f6
docs(wrapperModules.niri): show setting outputs position (#391)
BirdeeHub Mar 29, 2026
6b45ba9
fix(wrapperModules.zathura): add extraSettings option (#396)
iynaix Mar 30, 2026
ca4b81b
chore(deps): bump actions/configure-pages from 5 to 6 (#398)
dependabot[bot] Mar 30, 2026
38355ca
chore(deps): bump actions/deploy-pages from 4 to 5 (#397)
dependabot[bot] Mar 30, 2026
676cb60
docs(CONTRIBUTING.md): fixed incorrect path (#400)
BirdeeHub Mar 30, 2026
bab35ff
feat(modules.constructFiles): auto-sanitize .key value to always be v…
BirdeeHub Mar 30, 2026
4e1aba2
fix(wrapperModules.niri): mkDefault config.package (#406)
nouritsu Apr 2, 2026
74a1aee
feat(wrapperModules.mangowc): init (#401)
pengolord Apr 2, 2026
708dd61
refactor(wrapperModules.neovim): unique (#407)
BirdeeHub Apr 4, 2026
d41216e
refactor(helix,btop,noctalia-shell): constructFiles.<name>.key self-s…
BirdeeHub Apr 5, 2026
7c1e2ea
fix(modules.wrapperVariants): wrapperVariants.<name>.wrapperImplement…
BirdeeHub Apr 5, 2026
72b3796
fix(wrapperModules.niri): support spawn-sh-at-startup (#412)
iynaix Apr 5, 2026
483f1b2
feat(wrapperModules.halloy): init (#402)
ricardomaps Apr 6, 2026
5369f45
feat(wrapperModules.himalaya): init (#417)
rachitvrma Apr 7, 2026
2ff8e87
feat(wrapperModules.eww): init (#420)
clay53 Apr 8, 2026
0ef325b
chore(deps): update flake.lock files (#411)
BirdeeHub Apr 8, 2026
08fe943
feat(wrapperModules.mpv): expand script and config options (#421)
BirdeeHub Apr 8, 2026
f50065f
docs(wrapperModules.mpv): close markdown block (#423)
BirdeeHub Apr 8, 2026
79cf9d6
feat(wlib.partitionAttrs): lib.partition but for attrsets (#424)
BirdeeHub Apr 8, 2026
df7d060
fix(wrapperModules.wezterm): allow placeholders in wezterm.lua conten…
BirdeeHub Apr 8, 2026
d64767b
fix(wrapperModules.zathura): default wrapper should support pdf (#426)
iynaix Apr 9, 2026
d79d2f9
feat(wrapperModules.kitty): init (#415)
rachitvrma Apr 9, 2026
4c7a13d
feat(wrapperModules.hyfetch): init (#419)
ricardomaps Apr 11, 2026
fb62851
feat(wrapperModules.mako): support section entries in settings (#429)
xavwe Apr 11, 2026
5e5ac5f
feat(wrapperModules.glance): init (#427)
jtrrll Apr 13, 2026
51b9e9e
feat(wrapperModules.wlr-which-key): init (#428)
nouritsu Apr 13, 2026
7620e25
fix(lib.types.specWith): main field detection made lazier (#433)
BirdeeHub Apr 14, 2026
40559c0
refactor(lib.core): discard string context to make these slightly eas…
BirdeeHub Apr 14, 2026
252e9b5
refactor(tests): move helper module tests to their relevant helper mo…
BirdeeHub Apr 15, 2026
0e699fc
refactor(isNull val): val == null (#440)
BirdeeHub Apr 15, 2026
e8abcc0
feat(wrapperModules.tmux): improve plugins option (#442)
BirdeeHub Apr 16, 2026
f11469c
feat(wrapperModules.tmux): allow function type submodules in plugins …
BirdeeHub Apr 16, 2026
5d8fa10
fix(wrapperModules.yazi): provide some way of installing plugins (#444)
BirdeeHub Apr 17, 2026
75febed
ci(tests.lib.specWith): added wlib.types.specWith checks (#445)
BirdeeHub Apr 17, 2026
3e6c285
chore(deps): bump actions/upload-pages-artifact from 4 to 5 (#448)
dependabot[bot] Apr 20, 2026
8629849
fix(wlib.types.file): made it slightly less cumbersome to use properl…
BirdeeHub Apr 21, 2026
7e1b8c7
ci(tests): add ... to internal test arguments to avoid future problem…
BirdeeHub Apr 21, 2026
5990dee
feat(wrapperModules.hyprlock): init (#435)
nouritsu Apr 21, 2026
8c89399
feat(wlib.genStr): now takes function as well (#453)
BirdeeHub Apr 22, 2026
f19dbc4
fix(wrapperModules.yazi): fix script for generating flavors (#458)
iynaix Apr 23, 2026
1b25ebb
feat(wrapperModules.niri): disableConfigValidation option (#459)
BirdeeHub Apr 24, 2026
787ec64
fix(wrapperModules.niri): change extraConfig to lib.types.lines (#460)
iynaix Apr 24, 2026
fd6d1dc
fix(lib.toKdl): added version 1 and version 2 syntax option (#463)
BirdeeHub Apr 25, 2026
81701c9
docs(lib.toKdl): add new version argument to docs (#468)
BirdeeHub Apr 27, 2026
9e9cbd6
fix(wrapperModules.neovim): option to choose if some host items are p…
BirdeeHub Apr 28, 2026
9c41163
ci(lib.makeCustomizable): just test the function (#474)
BirdeeHub Apr 28, 2026
e6758c0
feat(wrapperModules.mangowc): use new official mango configuration sy…
pengolord Apr 28, 2026
0980d26
feat(wrapperModules.fish): init (#408)
ormoyo Apr 28, 2026
d0f0d0d
ci(wrapperModules.fish): add ... to test args in preparation for test…
BirdeeHub Apr 28, 2026
25aa38a
feat(tests): add test-lib (tlib) (#439)
zenoli Apr 28, 2026
a35811d
test(makeCustomizable): refactor tests with tlib (#478)
zenoli Apr 28, 2026
289036f
feat(wrapperModules.niri): option for auto translated repeated values
BirdeeHub Apr 28, 2026
2a16280
docs(wrapperModules.niri): improve examples in documentation
BirdeeHub Apr 28, 2026
099514f
fix(tlib): handle singleton assertions in set form (#477)
zenoli Apr 29, 2026
472d261
feat(scheduled deprecations): flake wrapperModules output now has mod…
BirdeeHub Apr 29, 2026
c11c41d
feat(core.install): integration module options (#405)
BirdeeHub Apr 29, 2026
1375097
docs(wrapperModules.niri): minor doc improvements (#479)
BirdeeHub Apr 29, 2026
3ceec51
fix(templates.neovim): flake was using outdated function (#480)
BirdeeHub Apr 29, 2026
d3e027a
fix(wrapperModules.neovim): upstream moved the desktop file (#481)
BirdeeHub Apr 29, 2026
ccee9fc
fix(tlib): formatting
zenoli Apr 30, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/deploy-website.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@ jobs:
- name: Checkout repository
uses: actions/checkout@v6
- name: Setup Pages
uses: actions/configure-pages@v5
uses: actions/configure-pages@v6
- name: Install Nix
uses: DeterminateSystems/nix-installer-action@main
- name: Update Site
run: |
nix run --show-trace ./ci#docs
- name: Upload artifact
uses: actions/upload-pages-artifact@v4
uses: actions/upload-pages-artifact@v5
with:
path: ./_site

Expand All @@ -36,6 +36,6 @@ jobs:
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
uses: actions/deploy-pages@v5
with:
token: ${{ secrets.PAT }}
174 changes: 124 additions & 50 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
# Adding Modules!
## Adding Modules!

There are 2 kinds of modules in this repository. One kind which defines the `package` option, and one kind which does not.

### Wrapper Modules

If you are making a wrapper module, i.e. one which **does** define the `config.package` option, and thus wraps a package:

You must define a `wrapperModules/<first_letter>/<your_package_name>/wrapper.nix` file.
You must define a `wrapperModules/<first_letter>/<your_package_name>/module.nix` file.
The file must contain a single, unevaluated module. In other words, it must be importable without calling it like a function first.

All wrapper modules must have a `config.meta.maintainers = [ <your wlib.maintainers listing> ];` entry.
Expand Down Expand Up @@ -45,31 +45,34 @@ You may optionally set the `meta.description` option to provide a short descript

`pre` will be added after the title and before the content. `post` will be added after the content.

Do not name an option `options` or `config` if there is a chance the module system will try to use them as if they were top level module declarations.

## Guidelines and Examples:

When you provide an option to `enable` or `disable` something, you should call it `enable` regardless of its default value.

This prevents people from needing to look it up to use it, and prevents contributors from having to think too hard about which to call it.

When you provide a `wlib.types.file` option, you should name it the actual filename, especially if there are multiple, but `configFile` is also OK, especially if it is unambiguous.
- Placeholders and `config.constructFiles.<name>`

Keep in mind that even if you do not choose to use `wlib.types.file`, the user can usually still override the option that you set to provide the generated path if needed.
When you generate a file, it is generally better to do so as a string, and create it using the `constructFiles` option.

However, this makes the user of your module search for it, and in some situations, such as when your module is adding stuff to `list` or `DAL` type options, this can be slightly harder to override later.
This is because, this will make placeholders such as `${placeholder "out"}` work consistently across all your options,
allowing them to all point to the final wrapper derivation rather than several intermediate ones.

So making use of the `wlib.types.file` type or giving some other method of overriding the filepath when providing a file is generally recommended for this reason.
What this allows you to do, is manually build files via another option like `constructFiles`, and then refer to that created file within your settings!

- Placeholders
Making placeholders work in your module makes your modules generally more easily extensible, and is preferred when it is possible to generate a usable string.

When you generate a file, it is generally better to do so as a string, and create it using the `constructFiles` option.
It works by using `drv.passAsFile` and making a derivation attribute with the file contents, which is copied into place.

This is because, this will make placeholders such as `${placeholder "out"}` work consistently across all your options.
- `wlib.types.file`

What this allows you to do, is manually build files later using `buildCommand` option or a stdenv phase, and then refer to that created file within your settings!
When you provide a `wlib.types.file` option, you should name it the actual filename or something suggestive of it, especially if there are multiple, but `configFile` is also OK, especially if it is unambiguous.

Making placeholders work in your module makes your modules generally more easily extensible, and is preferred when it is possible to generate a usable string.
Keep in mind that even if you do not choose to use `wlib.types.file`, the user can usually still override the option that you set to provide the generated path if needed.

It works by using `drv.passAsFile` and making a derivation attribute with the file contents, which is copied into place.
So using something like `wlib.types.file` is only truly important when the file you are making an option for is passed to a list-style option, but may still be nice more generally.

Example:

Expand All @@ -93,11 +96,11 @@ Example:
'';
};
configFile = lib.mkOption {
type = wlib.types.file pkgs;
default = {
path = config.constructFiles.gitconfig.path; # <- we can refer to the placeholder of our constructed file!
content = "";
type = wlib.types.file {
# we can refer to the placeholder of our constructed file!
path = lib.mkOptionDefault config.constructFiles.gitconfig.path;
};
default = { };
description = "Generated git configuration file.";
};
};
Expand All @@ -118,75 +121,146 @@ Example:
}
```

# Formatting
## Formatting

`nix fmt`

# Tests
## Tests

`nix flake check -Lv ./ci`

# Run Site Generator Locally
## Run Site Generator Locally

`nix run ./ci`

or

`nix run ./ci#docs`

# Writing tests
To run the tests for an individual wrapper only, run

`nix build ./ci#checks.{system}.wrapperModule-{name}`

Example (neovim on `x86_64-linux`):

`nix build ./ci#checks.x86_64-linux.wrapperModule-neovim`

## Writing Tests

You may also include a `check.nix` file in your module's directory.

It will be provided with the flake `self` value and `pkgs`
It will be called via `pkgs.callPackage`, provided with the flake `self` value, as well as a test-library `tlib` value.
(i.e. `pkgs.callPackage your_check.nix { inherit self tlib; }`)

It should build a derivation which tests the wrapper derivation as best you can.

If a command fails, it fails the test. If it builds the derivation successfully, it passes the test.
We provide a testing library `tlib` that provides an easy-to-use interface to write tests.

If the program gives options for running the program to check the generated configuration is correct, you should do that.
### Writing Tests for Wrappers

Sometimes it is not easily possible to run the program within a derivation, in those cases, searching the wrapper derivation and other generated files and their contents is also acceptable.
If you are writing tests for a wrapper module, it is important to pass the name
of the wrapper to the first argument of the `test` function like in the example
below (marked at `(*)`). By doing this, we can grab the specified `wrapper.meta.platforms` config
of the wrapper (if any) and ensure that the tests are only run on the required platforms.

Example:

```nix
{
pkgs,
self,
tlib,
...
}:

let
gitWrapped = self.wrappers.git.wrap {
inherit pkgs;
settings = {
user = {
name = "Test User";
email = "test@example.com";
inherit (tlib)
fileContains
isDirectory
isFile
notIsFile
areEqual
test
;
in
test { wrapper = "direnv"; } { # <-- Specify the name of the wrapper here (*)

"direnv wrapper should be created" =
let
wrapper = self.wrappers.direnv.wrap {
inherit pkgs;
nix-direnv.enable = true;
};
};
in
[
"[[ -d ${wrapper} ]]" # <-- a simple condition to be asserted
{
cond = "[[ -d ${wrapper} ]]";
msg = "No directory found for wrapper."; # <-- you can also specify a custom error message
}
(isDirectory wrapper) # <-- or use pre-defined helpers
];

"wrapper should output correct version" =
let
wrapper = self.wrappers.direnv.wrap {
inherit pkgs;
};
in
'' # <-- no need to provide a list if there is only one assertion
"${wrapper}/bin/direnv" --version |
grep -q "${wrapper.version}"
'';

"math-tests" = { # <-- tests can be arbitrarily grouped
addition = [
(areEqual 2 (1 + 1))
(areEqual 7 (5 + 2))
];
multiplication = [
(areEqual 1 (1 * 1))
(areEqual 10 (5 * 2))
];
};

in
pkgs.runCommand "git-test" { } ''
"${gitWrapped}/bin/git" config user.name | grep -q "Test User"
"${gitWrapped}/bin/git" config user.email | grep -q "test@example.com"
touch $out
''
}
```

If your module declares a list of valid platforms via its `meta.platforms` option, you should disable your test on the relevant platforms like so:

Pre-defined assertions like `isDirectory` or `areEqual` are already available in tlib.
Feel free to contribute more if you find new ones that other maintainers might benefit from.

### Writing Tests for Helper Modules or Library Functions

The syntax is identical to [the example above](#writing-tests-for-wrappers),
except you don't provide a wrapper but a name:

```nix
if builtins.elem pkgs.stdenv.hostPlatform.system self.wrappers.waybar.meta.platforms then
pkgs.runCommand "waybar-test" { } ''
"${waybarWrapped}/bin/waybar" --version | grep -q "${waybarWrapped.version}"
touch $out
''
else
null
{
pkgs,
self,
tlib,
...
}:

let
inherit (tlib)
fileContains
isDirectory
isFile
notIsFile
areEqual
test
;
in
test "my-test" { # <-- Specify an arbitrary name for your test
# test { name = "my-test" } { # <-- This is equivalent

"my first test" = [ ... ]; # <-- nothing new here
"my second test" = [ ... ];
}
```

# Commit Messages
If you are writing a helper module, or something very complex, you may wish to have multiple derivations. Simply return a set of them instead.

## Commit Messages

Changes to wrapper modules should be titled `<type>(wrapperModules.<name>): some description`.
For new additions, the description should be `init`, with any further explanation on subsequent lines
Expand All @@ -206,6 +280,6 @@ For everything else, do the best you can to follow conventional commit message s

Why specify this? I was having trouble figuring out what to title my commits. So now I know.

# Questions?
## Questions?

The [github discussions board](https://github.com/BirdeeHub/nix-wrapper-modules/discussions) is open and a great place to find help!
38 changes: 36 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,14 +108,48 @@ For more information on how to do this, check out the [getting started](https://
It is the ideal of this project to become a hub for everyone to contribute,
so that we can all enjoy our portable configurations with as little individual strife as possible.

In service of that ideal, the immediate goal would be to transfer this repo to nix-community the moment that becomes an option.
In service of that ideal, the plan is that ownership will be transferred to nix-community,
so that there is community ownership of where our contributions will be maintained.

Eventually I hope to have wrapper modules in nixpkgs, but again, nix-community would be the first step.
The road-map before beginning that process consists of at least most of the following items:

- Better doc-generation options, less buggy and made more available to individual modules outside of the main repository.
- Services options for generating service files which can be installed by passing the package to the correct option.
- Non-intrusive `bubblewrap` helper module, for programs that are difficult to wrap.
- Better documentation in general. Things should already be covered in the docs, but not yet always in a way digestible for everyone.
- Maybe 1 or 2 other things.

Once the dust has settled, the process will be started to move it to nix-community,
and we will start building a core team to maintain the repository long into the future!

## Short-term Goals

Help us add more modules! Contributors are what makes projects like these which contain modules for so many programs amazing!

## Related Extension Projects:

There may be projects that offer useful additions or pre-configurations of existing modules,
or new ways of using wrapper modules that do not yet fit in the main repository.

For example, a collection of Neovim modules for various languages would be a good item for this list

- [hm-wrapper-modules](https://github.com/sini/hm-wrapper-modules)
- This is a library designed to run home manager modules, figure out what paths it would add,
and use `bubblewrap` and a wrapper module to use the home manager module as a wrapper module.
- This repository may be useful to create wrapper modules for difficult to wrap programs until more direct ones can be written.
- It does not fit in the main repository, because the correct way to do it is to add a `bubblewrap` helper module to the main repository,
and figure out what files that program actually needs us to wrap via `bubblewrap` or not.

Hopefully more will be listed here soon!

Some examples why something may not fit in the main repository:

- It doesn't fit in an existing category of offered things.

- It requires more flake inputs beyond `nixpkgs` in order to import it from this repository and use it somewhere.

- It is a never ending job of its own (i.e. making modules for new editor language integrations and plugins for an existing wrapper module like the Neovim one)

---

### Why rewrite [lassulus/wrappers](https://github.com/Lassulus/wrappers)?
Expand Down
1 change: 1 addition & 0 deletions ci/checks/all-modules-have-maintainers.nix
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
pkgs,
self,
...
}:

let
Expand Down
1 change: 1 addition & 0 deletions ci/checks/apply.nix
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
pkgs,
self,
...
}:
# TODO: make sure theres no other stuff passing on accident in here
let
Expand Down
1 change: 1 addition & 0 deletions ci/checks/formatting.nix
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
pkgs,
self,
...
}:

pkgs.runCommand "formatting-check" { } ''
Expand Down
Loading