Merge pull request #920 from Ruixi-rebirth/main
Some checks are pending
Generate Nix Options Docs / update-docs (push) Waiting to run
Sync website / sync-website (push) Waiting to run
Sync wiki / sync-wiki (push) Waiting to run

feat(nix): generate module options docs and sync to website
This commit is contained in:
DreamMaoMao 2026-05-13 08:16:03 +08:00 committed by GitHub
commit 0b39255831
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 569 additions and 5 deletions

112
.github/scripts/generate-nix-options-docs.py vendored Executable file
View file

@ -0,0 +1,112 @@
#!/usr/bin/env python3
"""
Converts NixOS options JSON into clean Markdown documentation.
"""
import json
import sys
import re
SECTIONS = [
{
"title": "NixOS",
"subtitle": "**System-level options via `programs.mango`.**",
},
{
"title": "Home Manager",
"subtitle": "**Configure mangowm declaratively via `wayland.windowManager.mango`.**",
},
]
HEADER = (
"---\n"
"title: Nix Module Options\n"
"description: NixOS and Home Manager configuration options for mangowm.\n"
"---\n\n"
"> **Note:** This document is automatically generated from the Nix module source code.\n\n"
)
def clean_description(desc: str) -> str:
"""Strips Nix inline markup tags, fixes dangling periods, and formats blockquotes."""
if not desc:
return "*No description provided.*"
# Strip Nix inline markup: {tag}`content` → `content`; bare tags → ""
desc = re.sub(r'\{(?:var|option|manpage|file|env|command|program)\}(`[^`]+`)', r'\1', desc)
desc = re.sub(r'\{(?:var|option|manpage|file|env|command|program)\}', '', desc)
# Remove period left on its own line after tag removal
desc = re.sub(r'\n\s*\.(\s|$)', r'.\1', desc)
lines = desc.splitlines()
cleaned = []
in_block = False
for line in lines:
m = re.match(r':::\s*\{\.(\w+)\}', line)
if m:
block_type = m.group(1).capitalize()
in_block = True
cleaned.append(f"> **{block_type}:**\n>")
elif line.startswith(":::"):
in_block = False
else:
cleaned.append(f"> {line}" if in_block else line)
return "\n".join(cleaned)
def format_value(val_data) -> str:
"""Formats a value as inline code or a nix code block."""
if val_data is None:
return None
if isinstance(val_data, dict) and val_data.get("_type") == "literalMD":
return val_data.get("text", "").strip()
elif isinstance(val_data, dict) and val_data.get("_type") == "literalExpression":
text = val_data.get("text", "").strip()
elif isinstance(val_data, bool):
text = "true" if val_data else "false"
elif val_data == {} or val_data == []:
text = "{ }" if val_data == {} else "[ ]"
else:
text = str(val_data).strip()
if '\n' in text:
return f"\n```nix\n{text}\n```"
return f"`{text}`"
def write_section(out, data, title, subtitle):
out.write(f"## {title}\n\n{subtitle}\n\n")
for key, opt in sorted(data.items()):
if key.startswith("_module"):
continue
desc = clean_description(opt.get("description", ""))
opt_type = str(opt.get("type", "unknown"))
default_val = format_value(opt.get("default"))
example_val = format_value(opt.get("example"))
block = f"### `{key}`\n\n{desc}\n\n**Type:** `{opt_type}`\n\n"
if default_val is not None:
block += f"**Default:** {default_val}\n\n"
if example_val is not None:
block += f"**Example:** {example_val}\n\n"
block += "---\n\n"
out.write(block)
def main():
if len(sys.argv) != 4:
sys.exit("Usage: generate-nix-options-docs.py <nixos.json> <hm.json> <output.md>")
nixos_json, hm_json, output_md = sys.argv[1:4]
inputs = [nixos_json, hm_json]
with open(output_md, 'w', encoding='utf-8') as out:
out.write(HEADER)
for path, section in zip(inputs, SECTIONS):
with open(path, 'r', encoding='utf-8') as f:
data = json.load(f)
write_section(out, data, section["title"], section["subtitle"])
print(f"Written {section['title']} section.")
if __name__ == "__main__":
main()

View file

@ -0,0 +1,49 @@
name: Generate Nix Options Docs
on:
push:
paths:
- 'nix/**-modules.nix'
- 'nix/generate-options.nix'
- 'flake.nix'
- '.github/scripts/generate-nix-options-docs.py'
pull_request:
paths:
- 'nix/**-modules.nix'
jobs:
update-docs:
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
ref: ${{ github.head_ref }}
- name: Install Nix
uses: cachix/install-nix-action@v30
with:
extra_nix_config: |
experimental-features = nix-command flakes
- name: Build Options JSON
run: |
nix build .#nixos-options-json --out-link result-nixos
nix build .#hm-options-json --out-link result-hm
- name: Format to Markdown
run: |
python3 ./.github/scripts/generate-nix-options-docs.py \
result-nixos/share/doc/nixos/options.json \
result-hm/share/doc/nixos/options.json \
docs/nix-options.md
- name: Auto-commit changes
uses: stefanzweifel/git-auto-commit-action@v5
with:
commit_message: "docs: auto-generate Nix module options"
file_pattern: 'docs/*-options.md'
branch: ${{ github.head_ref }}

View file

@ -58,6 +58,7 @@ dnf install mangowm
The package is hosted in the community-maintained **GURU** repository. The package is hosted in the community-maintained **GURU** repository.
1. **Add the GURU repository** 1. **Add the GURU repository**
```bash ```bash
emerge --ask --verbose eselect-repository emerge --ask --verbose eselect-repository
eselect repository enable guru eselect repository enable guru
@ -82,6 +83,7 @@ The package definition is described in the source repository.
1. **Add mango channel** 1. **Add mango channel**
Add to `$HOME/.config/guix/channels.scm`: Add to `$HOME/.config/guix/channels.scm`:
```scheme ```scheme
(cons (channel (cons (channel
(name 'mangowm) (name 'mangowm)
@ -92,11 +94,13 @@ The package definition is described in the source repository.
2. **Install** 2. **Install**
After running `guix pull`, you can install mangowm: After running `guix pull`, you can install mangowm:
```bash ```bash
guix install mangowm guix install mangowm
``` ```
Or add it to your system configuration using the mangowm module: Or add it to your system configuration using the mangowm module:
```scheme ```scheme
(use-modules (mangowm)) (use-modules (mangowm))
@ -115,6 +119,7 @@ The package definition is described in the source repository.
The repository provides a Flake with a NixOS module. The repository provides a Flake with a NixOS module.
1. **Add flake input** 1. **Add flake input**
```nix ```nix
# flake.nix # flake.nix
{ {
@ -132,6 +137,7 @@ The repository provides a Flake with a NixOS module.
2. **Import the NixOS module** 2. **Import the NixOS module**
**Option A — Import in `configuration.nix`:** **Option A — Import in `configuration.nix`:**
```nix ```nix
# configuration.nix (or any other file that you import) # configuration.nix (or any other file that you import)
{inputs, ...}: { {inputs, ...}: {
@ -145,6 +151,7 @@ The repository provides a Flake with a NixOS module.
``` ```
**Option B — Import directly in flake:** **Option B — Import directly in flake:**
```nix ```nix
# flake.nix # flake.nix
{ {
@ -165,6 +172,7 @@ The repository provides a Flake with a NixOS module.
``` ```
3. **Enable the module** 3. **Enable the module**
```nix ```nix
# configuration.nix (or any other file that you import) # configuration.nix (or any other file that you import)
{ {
@ -172,9 +180,67 @@ The repository provides a Flake with a NixOS module.
} }
``` ```
4. **Extra options** 4. **Start mango on login**
- `programs.mango.package` — the mango package to use, allows usage of custom mango drvs
- `programs.mango.addLoginEntry` (default: `true`) — adds login entry to the display manager The following are common examples. Refer to the official NixOS documentation for full configuration options.
**Option A — greetd:** Autologin on first start; login screen after logout.
```nix
services.greetd = {
enable = true;
settings = {
initial_session = {
command = "mango";
user = "your-username"; # auto-login on first start, no password required
};
default_session = {
command = "${pkgs.greetd.tuigreet}/bin/tuigreet --cmd mango";
user = "greeter";
};
};
};
```
**Option B — Display manager autologin:** Autologin via an existing display manager (e.g. SDDM, GDM). [`addLoginEntry`](/docs/nix-module#addloginentry) (default: `true`) automatically registers mango as a session.
```nix
services.displayManager = {
defaultSession = "mango"; # derived from mango.desktop filename
autoLogin = {
enable = true;
user = "your-username";
};
};
```
**Option C — getty autologin:** No login screen, boots directly into mango on TTY1.
For bash/zsh:
```nix
services.getty.autologinUser = "your-username";
environment.loginShellInit = ''
[ "$(tty)" = /dev/tty1 ] && exec mango
'';
```
For fish:
```nix
services.getty.autologinUser = "your-username";
programs.fish.loginShellInit = ''
if test (tty) = /dev/tty1
exec mango
end
'';
```
5. **All available options**
See [Nix Module Options](/docs/nix-module) for the full list of NixOS and Home Manager options.
--- ---
@ -195,6 +261,7 @@ pikman install mangowm
If your distribution isn't listed above, or you want the latest unreleased changes, you can build mangowm from source. If your distribution isn't listed above, or you want the latest unreleased changes, you can build mangowm from source.
> **Info:** Ensure the following dependencies are installed before proceeding: > **Info:** Ensure the following dependencies are installed before proceeding:
>
> - `wayland` > - `wayland`
> - `wayland-protocols` > - `wayland-protocols`
> - `libinput` > - `libinput`
@ -213,6 +280,7 @@ You will need to build `wlroots` and `scenefx` manually as well.
1. **Build wlroots** 1. **Build wlroots**
Clone and install the specific version required (check README for latest version). Clone and install the specific version required (check README for latest version).
```bash ```bash
git clone -b 0.19.3 https://gitlab.freedesktop.org/wlroots/wlroots.git git clone -b 0.19.3 https://gitlab.freedesktop.org/wlroots/wlroots.git
cd wlroots cd wlroots
@ -222,6 +290,7 @@ You will need to build `wlroots` and `scenefx` manually as well.
2. **Build scenefx** 2. **Build scenefx**
This library handles the visual effects. This library handles the visual effects.
```bash ```bash
git clone -b 0.4.1 https://github.com/wlrfx/scenefx.git git clone -b 0.4.1 https://github.com/wlrfx/scenefx.git
cd scenefx cd scenefx

View file

@ -11,6 +11,7 @@
"window-management", "window-management",
"bindings", "bindings",
"---Reference---", "---Reference---",
"nix-options",
"ipc", "ipc",
"faq" "faq"
] ]

296
docs/nix-options.md Normal file
View file

@ -0,0 +1,296 @@
---
title: Nix Module Options
description: NixOS and Home Manager configuration options for mangowm.
---
> **Note:** This document is automatically generated from the Nix module source code.
## NixOS
**System-level options via `programs.mango`.**
### `addLoginEntry`
Whether to add a login entry to the display manager for mango. Only has effect if a display manager is configured (e.g. SDDM, GDM via `services.displayManager`).
**Type:** `boolean`
**Default:** `true`
---
### `enable`
Whether to enable mango, a wayland compositor based on dwl.
**Type:** `boolean`
**Default:** `false`
**Example:** `true`
---
### `package`
The mango package to use
**Type:** `package`
**Default:** `<derivation mango-nightly>`
---
## Home Manager
**Configure mangowm declaratively via `wayland.windowManager.mango`.**
### `autostart_sh`
Shell script to run on mango startup. No shebang needed.
When this option is set, the script will be written to
`~/.config/mango/autostart.sh` and an `exec-once` line
will be automatically added to the config to execute it.
**Type:** `strings concatenated with "\n"`
**Default:** `""`
**Example:**
```nix
''
waybar &
dunst &
''
```
---
### `bottomPrefixes`
List of prefixes for attributes that should appear at the bottom of the config file.
Attributes starting with these prefixes will be sorted to the end.
**Type:** `list of string`
**Default:** `[ ]`
**Example:**
```nix
[
"source"
]
```
---
### `enable`
Whether to enable mangowm, a Wayland compositor based on dwl.
**Type:** `boolean`
**Default:** `false`
---
### `extraConfig`
Extra configuration lines to add to `~/.config/mango/config.conf`.
This is useful for advanced configurations that don't fit the structured
settings format, or for options that aren't yet supported by the module.
**Type:** `strings concatenated with "\n"`
**Default:** `""`
**Example:**
```nix
''
# Advanced config that doesn't fit structured format
special_option = 1
''
```
---
### `package`
The mango package to use
**Type:** `package`
**Default:** `<derivation mango-nightly>`
---
### `settings`
Mango configuration written in Nix. Entries with the same key
should be written as lists. Variables and colors names should be
quoted. See <https://mangowm.github.io/docs> for more examples.
> **Note:**
>
> This option uses a structured format that is converted to Mango's
> configuration syntax. Nested attributes are flattened with underscore separators.
> For example: `animation.duration_open = 400` becomes `animation_duration_open = 400`
>
> Keymodes (submaps) are supported via the special `keymode` attribute. Each keymode
> is a nested attribute set under `keymode` that contains its own bindings.
**Type:** `Mango configuration value`
**Default:** `{ }`
**Example:**
```nix
{
# Window effects
blur = 1;
blur_optimized = 1;
blur_params = {
radius = 5;
num_passes = 2;
};
border_radius = 6;
focused_opacity = 1.0;
# Animations - use underscores for multi-part keys
animations = 1;
animation_type_open = "slide";
animation_type_close = "slide";
animation_duration_open = 400;
animation_duration_close = 800;
# Or use nested attrs (will be flattened with underscores)
animation_curve = {
open = "0.46,1.0,0.29,1";
close = "0.08,0.92,0,1";
};
# Use lists for duplicate keys like bind and tagrule
bind = [
"SUPER,r,reload_config"
"Alt,space,spawn,rofi -show drun"
"Alt,Return,spawn,foot"
"ALT,R,setkeymode,resize" # Enter resize mode
];
tagrule = [
"id:1,layout_name:tile"
"id:2,layout_name:scroller"
];
# Keymodes (submaps) for modal keybindings
keymode = {
resize = {
bind = [
"NONE,Left,resizewin,-10,0"
"NONE,Escape,setkeymode,default"
];
};
};
}
```
---
### `systemd.enable`
Whether to enable `mango-session.target` on
mango startup. This links to
`graphical-session.target`.
Some important environment variables will be imported to systemd
and dbus user environment before reaching the target, including
* `DISPLAY`
* `WAYLAND_DISPLAY`
* `XDG_CURRENT_DESKTOP`
* `XDG_SESSION_TYPE`
* `NIXOS_OZONE_WL`
You can extend this list using the `systemd.variables` option.
**Type:** `boolean`
**Default:** `true`
**Example:** `false`
---
### `systemd.extraCommands`
Extra commands to run after D-Bus activation.
**Type:** `list of string`
**Default:**
```nix
[
"systemctl --user reset-failed"
"systemctl --user start mango-session.target"
]
```
---
### `systemd.variables`
Environment variables imported into the systemd and D-Bus user environment.
**Type:** `list of string`
**Default:**
```nix
[
"DISPLAY"
"WAYLAND_DISPLAY"
"XDG_CURRENT_DESKTOP"
"XDG_SESSION_TYPE"
"NIXOS_OZONE_WL"
"XCURSOR_THEME"
"XCURSOR_SIZE"
]
```
**Example:**
```nix
[
"--all"
]
```
---
### `systemd.xdgAutostart`
Whether to enable autostart of applications using
`systemd-xdg-autostart-generator(8)`.
**Type:** `boolean`
**Default:** `false`
**Example:** `true`
---
### `topPrefixes`
List of prefixes for attributes that should appear at the top of the config file.
Attributes starting with these prefixes will be sorted to the beginning.
**Type:** `list of string`
**Default:** `[ ]`
**Example:**
```nix
[
"source"
]
```
---

View file

@ -43,6 +43,14 @@
}; };
packages = { packages = {
inherit mango; inherit mango;
hm-options-json = pkgs.callPackage (import ./nix/generate-options.nix self) {
module = ./nix/hm-modules.nix;
optionPrefix = "wayland.windowManager.mango.";
};
nixos-options-json = pkgs.callPackage (import ./nix/generate-options.nix self) {
module = ./nix/nixos-modules.nix;
optionPrefix = "programs.mango.";
};
}; };
devShells.default = mango.overrideAttrs shellOverride; devShells.default = mango.overrideAttrs shellOverride;
formatter = pkgs.alejandra; formatter = pkgs.alejandra;

28
nix/generate-options.nix Normal file
View file

@ -0,0 +1,28 @@
self:
{
pkgs,
lib ? pkgs.lib,
module,
optionPrefix,
}:
let
eval = lib.evalModules {
modules = [
(import module self)
{ _module.check = false; }
];
specialArgs = { inherit pkgs; };
};
optionsDoc = pkgs.nixosOptionsDoc {
options = eval.options;
transformOptions =
opt:
opt
// {
visible = opt.visible && !opt.internal;
name = lib.removePrefix optionPrefix opt.name;
};
};
in
optionsDoc.optionsJSON

View file

@ -22,6 +22,7 @@ in
enable = mkOption { enable = mkOption {
type = types.bool; type = types.bool;
default = false; default = false;
description = "Whether to enable mangowm, a Wayland compositor based on dwl.";
}; };
package = lib.mkOption { package = lib.mkOption {
type = lib.types.package; type = lib.types.package;
@ -101,7 +102,7 @@ in
description = '' description = ''
Mango configuration written in Nix. Entries with the same key Mango configuration written in Nix. Entries with the same key
should be written as lists. Variables and colors names should be should be written as lists. Variables and colors names should be
quoted. See <https://mangowc.vercel.app/docs> for more examples. quoted. See <https://mangowm.github.io/docs> for more examples.
::: {.note} ::: {.note}
This option uses a structured format that is converted to Mango's This option uses a structured format that is converted to Mango's

View file

@ -12,7 +12,7 @@ in {
addLoginEntry = lib.mkOption { addLoginEntry = lib.mkOption {
type = lib.types.bool; type = lib.types.bool;
default = true; default = true;
description = "Whether to add a login entry to the display manager for mango"; description = "Whether to add a login entry to the display manager for mango. Only has effect if a display manager is configured (e.g. SDDM, GDM via `services.displayManager`).";
}; };
package = lib.mkOption { package = lib.mkOption {
type = lib.types.package; type = lib.types.package;