diff --git a/.github/scripts/generate-nix-options-docs.py b/.github/scripts/generate-nix-options-docs.py new file mode 100755 index 00000000..6f5d35bd --- /dev/null +++ b/.github/scripts/generate-nix-options-docs.py @@ -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 = 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() diff --git a/.github/workflows/generate-nix-options-docs.yml b/.github/workflows/generate-nix-options-docs.yml new file mode 100644 index 00000000..465146be --- /dev/null +++ b/.github/workflows/generate-nix-options-docs.yml @@ -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 }} diff --git a/docs/installation.md b/docs/installation.md index 6f3927a0..903d7cb9 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -58,6 +58,7 @@ dnf install mangowm The package is hosted in the community-maintained **GURU** repository. 1. **Add the GURU repository** + ```bash emerge --ask --verbose eselect-repository eselect repository enable guru @@ -82,6 +83,7 @@ The package definition is described in the source repository. 1. **Add mango channel** Add to `$HOME/.config/guix/channels.scm`: + ```scheme (cons (channel (name 'mangowm) @@ -92,11 +94,13 @@ The package definition is described in the source repository. 2. **Install** After running `guix pull`, you can install mangowm: + ```bash guix install mangowm ``` Or add it to your system configuration using the mangowm module: + ```scheme (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. 1. **Add flake input** + ```nix # flake.nix { @@ -132,6 +137,7 @@ The repository provides a Flake with a NixOS module. 2. **Import the NixOS module** **Option A — Import in `configuration.nix`:** + ```nix # configuration.nix (or any other file that you import) {inputs, ...}: { @@ -145,6 +151,7 @@ The repository provides a Flake with a NixOS module. ``` **Option B — Import directly in flake:** + ```nix # flake.nix { @@ -165,6 +172,7 @@ The repository provides a Flake with a NixOS module. ``` 3. **Enable the module** + ```nix # 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** - - `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 +4. **Start mango on login** + + 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. > **Info:** Ensure the following dependencies are installed before proceeding: +> > - `wayland` > - `wayland-protocols` > - `libinput` @@ -213,6 +280,7 @@ You will need to build `wlroots` and `scenefx` manually as well. 1. **Build wlroots** Clone and install the specific version required (check README for latest version). + ```bash git clone -b 0.19.3 https://gitlab.freedesktop.org/wlroots/wlroots.git cd wlroots @@ -222,6 +290,7 @@ You will need to build `wlroots` and `scenefx` manually as well. 2. **Build scenefx** This library handles the visual effects. + ```bash git clone -b 0.4.1 https://github.com/wlrfx/scenefx.git cd scenefx diff --git a/docs/meta.json b/docs/meta.json index 74818a9d..8c10c621 100644 --- a/docs/meta.json +++ b/docs/meta.json @@ -11,6 +11,7 @@ "window-management", "bindings", "---Reference---", + "nix-options", "ipc", "faq" ] diff --git a/docs/nix-options.md b/docs/nix-options.md new file mode 100644 index 00000000..2a5d2038 --- /dev/null +++ b/docs/nix-options.md @@ -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:** `` + +--- + +## 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:** `` + +--- + +### `settings` + +Mango configuration written in Nix. Entries with the same key +should be written as lists. Variables and colors names should be +quoted. See 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" +] +``` + +--- + diff --git a/flake.nix b/flake.nix index b7158bbd..33b97c9b 100644 --- a/flake.nix +++ b/flake.nix @@ -43,6 +43,14 @@ }; packages = { 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; formatter = pkgs.alejandra; diff --git a/nix/generate-options.nix b/nix/generate-options.nix new file mode 100644 index 00000000..c2b87a4f --- /dev/null +++ b/nix/generate-options.nix @@ -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 diff --git a/nix/hm-modules.nix b/nix/hm-modules.nix index f00d9c68..eba05e2f 100644 --- a/nix/hm-modules.nix +++ b/nix/hm-modules.nix @@ -22,6 +22,7 @@ in enable = mkOption { type = types.bool; default = false; + description = "Whether to enable mangowm, a Wayland compositor based on dwl."; }; package = lib.mkOption { type = lib.types.package; @@ -101,7 +102,7 @@ in description = '' Mango configuration written in Nix. Entries with the same key should be written as lists. Variables and colors names should be - quoted. See for more examples. + quoted. See for more examples. ::: {.note} This option uses a structured format that is converted to Mango's diff --git a/nix/nixos-modules.nix b/nix/nixos-modules.nix index 7295fffa..9144bbf1 100644 --- a/nix/nixos-modules.nix +++ b/nix/nixos-modules.nix @@ -12,7 +12,7 @@ in { addLoginEntry = lib.mkOption { type = lib.types.bool; 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 { type = lib.types.package;