How to discover automatically scoped nix builtins

My primary intent is to propose a PR to the nix-mode issue #166, completing nix-mode knowledge of available builtins.

At first I thought of using something like

nix eval --expr 'builtins.attrNames builtins'

to produce that list, but I quickly discovered that not all of those names are available in the basic scope of an expression. For example, fromTOML is there while readFile is not.

Now that I understand that, probably the current list of builtins known by nix-mode is nearly complete, but I still like to add missing items, if any.

I tried to dig into the nix sources but failed to understand by which logic some RegisterPrimOp item is actually registered in the base scope (say that is available in a simple nix repl, displayed by hitting TAB on an empty line).

A similar doubt often nags me when I write a nix expression, as obviously I must use builtins.readFile and not simply readFile, as I can with fromTOML: luckily my GNU/Emacs config highlights such errors, thanks to flymake that behind the scenes uses nix-instantiate --parse to verify the syntax.

So the questions:

  1. What is the rationale that drives the selection of directly available builtins names?
  2. Is there a way to programmatically obtain the builtins names that are available in the base scope?

Thanks in advance!

1 Like

Regarding the Nix code: PrimOp registration is handled by the EvalState::addPrimOp function. The logic is, in prose: If the RegisterPrimOp::name is of the form “__name”, it makes the primop available as __name and Otherwise, it makes the primop available as name and So, builtins.readFile is also available as __readFile.

If you’re developing an autocomplete, I’d not offer suggestion for the global __name variants as they are an implementation detail and undocumented.

Re question 1: All I could find in the documentation is: “But to prevent polluting the namespace too much, most built-ins are not in scope.”

1 Like

There is nix __dump-builtins which dumps json with all builtins and a short doc.

Thank you.
I guess the easiest way is to maintain that list (remember, the primary goal was to update nix-mode.el list of builtin names, in the sense “symbols that do not require being qualified”: exemplifying, it should contain toString, but not readFile) manually by syncing it to what I see in the nix repl prompt, not a big hassle given that they do not change so often.