Finding things in nixpkgs and NixOS source
Jade Lovelace <jade at jade dot fyi>
Get the slides at
https://jade.fyi/nixcon2023/slides
# whoami * Author of nix-doc (not to be confused with nixdoc) * Most involved in Nix for Haskell and Rust packaging * I use NixOS as a dev workstation and server
# the sources are for everyone * We *do* need to improve our documentation * Nix is uniquely participatory: a *lot* of us write modules and packages, which means reading sources * Navigating the source is a bit of witchcraft, and there's a lot of it * With good tooling, the sources of the docs sometimes are faster than the docs * We should have more interactive docs!
# motivation (2.94 million lines of it)
# roadmap * nix * static analysis * nixd * ctags * dynamic analysis * using the repl * using nix-doc * nixos * ctags * repl usage
# Static analysis * Any method that takes 15 seconds or less and doesn't involve running any code * First way to try: * Extremely fast * Objective: "works most of the time" * I am showing the fancy ways of doing it here * ripgrep is static analysis too * Objective of fancy ways: faster and less stuff to sort through
# nixd Newish language server, using Nix as a library. In nixpkgs as `nixd`. Good for: * need go-to-definition * interactive help writing nix code Limitations: * does not eval everything * needs some setup per-project * imperfect go-to-definition
# nixd setup Install from nixpkgs and configure in your editor. Then: `.nixd.json`:
# demo (nixd)
# ctags * Very old and simple source code index format * Usually gets through abstraction by being too naive to get broken * Typically generated by simple parse-tree traversal * Wide editor support ([VSCode extension](https://marketplace.visualstudio.com/items?itemName=jaydenlin.ctags-support); also built into vim/emacs) Sample: ```text boot.initrd.luks.reusePassphrases nixos/modules/system/boot/luksroot.nix 533 ```
# ctags on nix * `nix-doc tags .` in nixpkgs, then in vim you can `:tj fixedPoints`, `C-]`, etc. * [WIP ctags for NixOS options (#249243)](https://github.com/NixOS/nixpkgs/pull/249243)
# demo (ctags on nix)
# summary (static analysis) First try language server, then ctags, then ripgrep.
# dynamic analysis * Static analysis often doesn't cut it, power tools time! * `nix repl` is your friend
# using the repl (nix) * `nix repl -f .`, `nix repl -f '<nixpkgs>` * `:lf flake-ref` (more on this later) * `:e derivation-or-function` to open in editor
# getting docs in the repl
# getting docs in the repl (ii)
Oops. Related: * [RFC 0145](https://github.com/NixOS/rfcs/pull/145) * [nix#3904](https://github.com/NixOS/nix/issues/3904)
# nix-doc?
# using nix-doc with the repl
# bonus: using the debugger * pass `--debugger` to nix * use `builtins.break (value)` somewhere in the evaluation path * NOTE: `(v: builtins.break v) value` may get more locals (see [nix#8827](https://github.com/NixOS/nix/issues/8827)) * then use `unsafeGetAttrPos` and others to figure out the source of a value
# summary (dynamic analysis) * `:e function/package` * \+ works pretty well * \+ built-in * \- issues with wrappers (e.g. `fetchFromGitHub`: `lib.makeOverridable`) * \- doesn't help for attr sets * `builtins.doc` (nix-doc) * \+ concise output on functions * \- issues with wrappers
# summary (dynamic analysis) * `builtins.unsafeGetAttrPos` * \+ gets close even with abstraction * \- unergonomic args and return value for interactive use
# NixOS ctags ([PR #249243](https://github.com/NixOS/nixpkgs/pull/249243)) With the PR checked out:
Then add `opts-tags` to ctags search path (`:set tags+=opts-tags` in vim).
# NixOS ctags (demo)
# NixOS in the repl Getting the configuration into the repl: * Non-flakes: `nix repl -I nixos-config=/path/to/configuration.nix -f <nixpkgs/nixos>` * Flakes: `nix repl` then `:lf .` then `nixosConfigurations.xx.{....}`
# NixOS in the repl (demo)
# questions? slides: https://jade.fyi/nixcon2023 masto: @leftpaddotpy\@hachyderm.io email: jade at jade dot fyi code: https://github.com/LF- github sponsors: https://github.com/sponsors/LF-