Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
66 changes: 66 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# Contributing to the catalog

This repository holds the LimaNix catalog, the NixOS modules that
`limanix.toml` chooses, and the base disk every new VM boots from. The
[organization guide](https://github.com/limanix/.github/blob/main/CONTRIBUTING.md)
covers issues, release labels and the license; this guide covers the work in
this repository.

## Set up

You need [Task](https://taskfile.dev) 3.53.1 or newer and Docker. Every task
runs in the container that CI uses; `task -l` lists them.

## Find the rules for your change

| You want to | Read | Check with |
| -- | -- | -- |
| Add or change a module | [Catalog contract](catalog/README.md) | `task ci/catalog/modules MODULES="<name>"` |
| Use shared helpers, capabilities or theme colors | [Shared helpers](catalog/_shared/README.md) | `task ci/catalog/layer` |
| Give a tool the guest's colors | [Colors and themes](catalog/README.md#colors-and-themes) | The module's checks |
| Add a theme | [Colors and themes](catalog/README.md#colors-and-themes) | `task generate/previews`, then the layer and the modules with colors |
| Change the harness in `tools/` or `checks/` | [Repository layout](README.md#repository-layout) | `task ci/python/test` and the other `ci/python/*` tasks |
| Move a Nixpkgs pin | [Releases](README.md#releases) | `task harness -- update nixpkgs` |

`task harness -- plan --base main` prints the checks CI will select for your
branch, dependent modules included.

## Add a module

1. Create `catalog/<kind>/<name>/` with `module.toml`, `default.nix`, `test.nix`
and `README.md`, as the [catalog contract](catalog/README.md#add-a-module)
describes.
2. Give every public entry a help card, and every setting a user may replace
`lib.mkDefault`.
3. Use other modules only through their public options and the shared
capabilities.
4. If the tool draws colors, take them from the theme by role.
5. Write `eval` checks for the configuration, `run` checks for behavior that
runs offline, and list in `builds` each derivation the checks build locally.
6. Write the README for a user: select, versions, use, settings and corner
cases. It becomes the module's page on docs.limanix.dev.
7. Add a `graph.toml` node and run `task generate/graph` if the module belongs
on the site's catalog graph.

## Before you open a pull request

| Step | Command |
| -- | -- |
| Check the modules you changed, or the layer for `_shared` | `task ci/catalog/modules MODULES="<names>"`, `task ci/catalog/layer` |
| Check formatting and lint | `task ci/nix/fmt`, `task ci/nix/lint`, `task ci/markdown/fmt` |
| Check the harness after a change in `tools/` | `task ci/python/fmt`, `task ci/python/lint`, `task ci/python/typecheck`, `task ci/python/test` |
| Regenerate generated files | `task generate/graph` after a `graph.toml` change; `task generate/previews` after a theme or color change |

The `nix/fmt/fix`, `nix/lint/fix`, `markdown/fmt/fix`, `python/fmt/fix` and
`python/lint/fix` tasks rewrite files in place. Update a module's README in the
same pull request as its behavior. Keep one change per pull request, and give it
a release label.

## Releases and the client

A tag `v<N>` on `main` releases the catalog and its disks; the
[README](README.md#releases) lists what creates a tag. Each client build bundles
one catalog release. A change to selectors, metadata, public options,
capabilities or the list of themes reaches users only with a client release that
bundles it; release the catalog first, then open the client pull request that
moves to it.
12 changes: 8 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ modules/
├── catalog/ the catalog: _shared/, shell/, toolchains/, modules/ and graph.json
├── checks/ the harness in Nix: discovery, contract validation and test aggregation
├── tools/ the harness in Python: the check runner, updates, the disk build, releases and the graph
├── previews/ the theme previews that the site shows, written by task generate/previews
├── interface.nix the options every VM gets: account identity, sessions and help cards
├── platform.nix the guest platform: disk layout, boot loader and Lima integration
├── image.nix the base disk, built from platform.nix
Expand Down Expand Up @@ -98,6 +99,7 @@ library; ruff, mypy and pytest are development tools in that image.
| `task ci/catalog/modules MODE=eval MODULES="go docker"` | Checks the named modules, or all of them; `MODE` is `check`, `eval` or `run` |
| `task ci/catalog/layer SUITE=shared MODE=eval` | Checks the shared layer, or the harness with `SUITE=platform` |
| `task generate/graph` | Writes `catalog/graph.json`, the site's catalog graph, from the `graph.toml` of each module |
| `task generate/previews` | Writes `previews/`, a picture of tmux, Neovim, eza and delta in each theme and the themes' palettes, for the site |
| `task harness -- plan --base main` | Prints the checks selected by committed changes from `main` to `HEAD`, including dependent modules |
| `task harness -- update nixpkgs` | Updates a pinned input; accepts `nixpkgs`, `unstable` or `nixos` |
| `task release/build` | Builds the base disk of this machine's architecture into `dist/` |
Expand All @@ -112,7 +114,9 @@ change.

## Contributing

Follow the
[contribution guide](https://github.com/limanix/.github/blob/main/CONTRIBUTING.md).
Use [Issues](https://github.com/limanix/modules/issues) for questions, bug
reports and feature requests. Licensed under [Apache 2.0](LICENSE).
Follow [CONTRIBUTING.md](CONTRIBUTING.md) for the work in this repository and
the
[organization guide](https://github.com/limanix/.github/blob/main/CONTRIBUTING.md)
for issues and release labels. Use
[Issues](https://github.com/limanix/modules/issues) for questions, bug reports
and feature requests. Licensed under [Apache 2.0](LICENSE).
7 changes: 7 additions & 0 deletions Taskfile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,13 @@ tasks:
CLI_ARGS: graph
CONTAINER_USER: host

generate/previews:
desc: Write previews/, the theme previews the site shows
cmds:
- task: harness
vars:
CLI_ARGS: previews

release/build:
desc: Build the base disk of ARCH into dist/
requires:
Expand Down
39 changes: 38 additions & 1 deletion catalog/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Catalog contract

Rules for catalog module authors, revision 6. NixOS combines modules into one
Rules for catalog module authors, revision 7. NixOS combines modules into one
configuration. Nix evaluates that configuration; builds and system activation
are separate steps.

Expand Down Expand Up @@ -95,6 +95,43 @@ name. See [language tools](_shared/README.md#share-language-tools) and
capabilities. A tool provider must not enable an editor just by declaring its
tools.

## Colors and themes

The guest has one theme, chosen with `[theme]` in `limanix.toml`. A module that
draws colors takes them from `lmx.capabilities.theme` by role, so one choice
recolors the whole guest; [theme colors](_shared/README.md#theme-colors)
describes the roles and the options.

| Do | Do not |
| -- | -- |
| Draw each element with `colors.<role>`, and use `palette.<role>` only for a tool that needs explicit colors even with `system` | Name a theme or write a color literal in a module |
| With `system`, draw with the terminal colors that `colors` holds and leave backgrounds to the terminal, or keep the tool's own terminal-color mode | Fall back to the terminal's colors when another theme is chosen |
| Set colors with `lib.mkDefault`, an environment variable or a system file that a personal setting replaces | Override a user's own configuration |
| Draw a template written for Catppuccin through [`lib/catppuccin.nix`](_shared/lib/catppuccin.nix) and a Textual theme through [`lib/textual.nix`](_shared/lib/textual.nix) | Copy the colors of one theme into a module |
| Say in the module README which settings carry the colors and how a user replaces them | Leave a tool that has colors out of the theme without saying why |

The editor is the only exception to drawing by role: a theme may bring its own
Neovim colorscheme, listed in
[`shell/neovim/colorschemes.nix`](shell/neovim/colorschemes.nix), and a theme
without one draws its palette with catppuccin-nvim. A tool that takes no colors
a module can set system-wide keeps its own colors, and its README names it.

To add a theme:

1. Add a table to [`_shared/themes.toml`](_shared/themes.toml) with `title`,
`homepage`, `dark` and all 18 roles. Take the values from the theme's own
Neovim colorscheme and its published palette, name the source in a comment,
and give a role the theme has no color for its nearest one.
1. Add the theme's colorscheme to `shell/neovim/colorschemes.nix` when Nixpkgs
packages it.
1. Run `task generate/previews` to write the preview that the site shows for the
theme.
1. Run `task ci/catalog/layer` and the checks of the modules that read the
theme:
`task ci/catalog/modules MODULES="tmux lazygit yazi zsh cli-tools astronvim neovim harlequin posting"`.
1. The client accepts the theme once its `[theme] name` lists it: add the name
to the client's choices and release the client with this catalog.

## Version lines

`lmx:<name>` selects `default.nix`; `lmx:<name>-<line>` selects
Expand Down
62 changes: 42 additions & 20 deletions catalog/_shared/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ flowchart LR
subgraph shared[_shared]
schemas[Schemas: languageSupport, pins, theme]
helpers[Test helpers in test/]
data[palette.toml, unstable.toml]
data[themes.toml, unstable.toml]
end
default -- sets and reads lmx options --> schemas
default -. reads .-> data
Expand Down Expand Up @@ -370,36 +370,58 @@ python ${../../../_shared/test/lsp-smoke.py} --timeout 10 ${profile}/bin/gopls
## Theme colors

`lmx.capabilities.theme` holds the guest's colors: the terminal's own colors, or
a Catppuccin flavor and its colors. Read it in configuration values:
one of the themes in [themes.toml](themes.toml). Every module that draws colors
takes them from here, by role, so that one choice in `limanix.toml` recolors the
whole guest. Read it in configuration values:

```nix
{ config, ... }:
let
inherit (config.lmx.capabilities.theme) flavor palette ansi;
inherit (config.lmx.capabilities.theme) name palette colors dark;
in
{
# flavor == "system" by default: ansi.blue == 4, the terminal's blue
# flavor == "mocha": palette.blue == "#89b4fa"
# name == "system" by default: colors.accent == 5, the terminal's magenta
# name == "tokyo-night": colors.accent == palette.accent == "#7aa2f7"
}
```

- `flavor` is `system`, the default, or `latte`, `frappe`, `macchiato` or
`mocha`. A system has one flavor: equal definitions agree, different
definitions at the same priority fail. The user selects it with `[theme]` in
`limanix.toml`; modules never set it. Every catalog module with colors reads
- `name` is `system`, the default, or a table of `themes.toml`. A system has one
theme: equal definitions agree, different definitions at the same priority
fail. The user selects it with `[theme]` in `limanix.toml`; modules never set
it.
- `palette` is read-only: the flavor's 26 colors by name, such as `blue`, as
`#rrggbb`. With `system` it holds Mocha's colors, for a tool that knows only
- `palette` is read-only: the theme's 18 colors by role, as `#rrggbb`. With
`system` it holds catppuccin-mocha's colors, for a tool that knows only
explicit colors.
- `ansi` is read-only: for each name of `palette`, the terminal color that
stands for it with `system`. A number from 0 to 15 is one of the terminal's 16
colors; `null` is its default foreground or background, so the terminal's own
background shows through. [ansi.toml](ansi.toml) holds the table.
- With `system`, use `ansi` and leave backgrounds to the terminal: the colors
then follow the theme of the terminal on the Mac, and change with it.
- [palette.toml](palette.toml) copies the four flavors of Catppuccin palette
v1.8.0 from the revision that `pkgs.catppuccin` packages; a check compares the
two.
- `dark` is read-only: whether the palette's colors sit on a dark background.
- `ansi` is read-only: for each role, the terminal color that stands for it with
`system`. A number from 0 to 15 is one of the terminal's 16 colors; `null` is
its default foreground or background, so the terminal's own background shows
through. [ansi.toml](ansi.toml) holds the table.
- `colors` is read-only: what to draw each role with, `ansi`'s value with
`system` and `palette`'s otherwise. With `system`, leave backgrounds to the
terminal: the colors then follow the theme of the terminal on the Mac, and
change with it.

| Role | Draws |
| -- | -- |
| `background` | Main background |
| `background_dark` | Panels and bars one step darker, such as a status line |
| `background_darker` | The deepest background, such as a border between panels |
| `surface` | Raised elements: the current line, a menu, a message |
| `selection` | Selected text and items |
| `border` | Borders, separators and inactive outlines |
| `muted` | Comments, hints and disabled text |
| `subtle` | Secondary text and labels |
| `foreground` | Main text |
| `accent` | The theme's signature color: focus, the active item, highlights |
| `red`, `orange`, `yellow`, `green`, `cyan`, `blue`, `purple`, `pink` | Hues; red marks errors, yellow warnings, green success, blue information |

A theme that has no color for a role takes its nearest one, so two roles may
share a color. `themes.toml` names the source of each theme: its own Neovim
colorscheme in the locked Nixpkgs and its published palette. Add a theme as one
more table with `title`, `homepage`, `dark` and all 18 roles; every module then
draws it without a change. A check compares catppuccin-mocha with the palette
that `pkgs.catppuccin` packages.

## Change `_shared`

Expand Down
44 changes: 18 additions & 26 deletions catalog/_shared/ansi.toml
Original file line number Diff line number Diff line change
@@ -1,31 +1,23 @@
# The terminal colors that stand for the palette's names with the system flavor: the number of one
# of the terminal's 16 colors, 0 to 15, or "default" for its own foreground or background. Accents
# take their ANSI hue; quiet text and surfaces take bright black, which terminal themes keep
# readable on their background, light or dark.
# The terminal colors that stand for the palette's roles with the system theme: the number of one
# of the terminal's 16 colors, 0 to 15, or "default" for its own foreground or background. Hues
# and the accent take their ANSI color; quiet text and surfaces take bright black, which terminal
# themes keep readable on their background, light or dark.

rosewater = 13
flamingo = 13
pink = 13
mauve = 5
background = "default"
background_dark = "default"
background_darker = "default"
surface = 8
selection = 8
border = 8
muted = 8
subtle = 8
foreground = "default"
accent = 5
red = 1
maroon = 9
peach = 11
orange = 11
yellow = 3
green = 2
teal = 6
sky = 14
sapphire = 14
cyan = 6
blue = 4
lavender = 12
text = "default"
subtext1 = "default"
subtext0 = 8
overlay2 = 8
overlay1 = 8
overlay0 = 8
surface2 = 8
surface1 = 8
surface0 = 8
base = "default"
mantle = "default"
crust = "default"
purple = 5
pink = 13
2 changes: 1 addition & 1 deletion catalog/_shared/graph.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
[theme]
name = "`[theme]`"
text = "One `[theme]` in `limanix.toml` colors the editor, the prompt, tmux, Lazygit, Yazi, bat, delta, Harlequin and Posting."
text = "One `[theme]` in `limanix.toml` colors the editor, the prompt, tmux, Lazygit, Yazi, bat, delta, Harlequin and Posting by the same roles."
32 changes: 32 additions & 0 deletions catalog/_shared/lib/catppuccin.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# The 26 colors of a Catppuccin flavor drawn from a theme's palette, so that a template written
# for Catppuccin draws any theme by role.
palette: {
rosewater = palette.pink;
flamingo = palette.pink;
inherit (palette)
pink
red
yellow
green
blue
;
mauve = palette.purple;
maroon = palette.red;
peach = palette.orange;
teal = palette.cyan;
sky = palette.cyan;
sapphire = palette.blue;
lavender = palette.accent;
text = palette.foreground;
subtext1 = palette.subtle;
subtext0 = palette.subtle;
overlay2 = palette.muted;
overlay1 = palette.muted;
overlay0 = palette.border;
surface2 = palette.border;
surface1 = palette.selection;
surface0 = palette.surface;
base = palette.background;
mantle = palette.background_dark;
crust = palette.background_darker;
}
8 changes: 8 additions & 0 deletions catalog/_shared/lib/textual.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# The keyword arguments of a Textual Theme that draws the guest's palette by role.
theme:
let
inherit (theme) palette;
in
''primary="${palette.accent}", secondary="${palette.blue}", accent="${palette.orange}", warning="${palette.yellow}", error="${palette.red}", success="${palette.green}", foreground="${palette.foreground}", background="${palette.background}", surface="${palette.surface}", panel="${palette.selection}", dark=${
if theme.dark then "True" else "False"
}''
Loading
Loading