query
On this page

scopedImport

builtins.scopedImport

Primop
Docs pulled from | This Revision | about 19 hours ago


Nix manual

Takes 2 arguments

Load, parse, and return the Nix expression in the file path, with the attributes from scope available as variables in the lexical scope of the imported file.

This function is similar to import, but allows you to provide additional variables that will be available in the scope of the imported expression. The scope argument must be an attribute set; each attribute becomes a variable available in the imported file. Built-in functions and values remain accessible unless shadowed by scope attributes.

Note

Variables from scope shadow built-ins with the same name, allowing you to override built-ins for the imported expression.

Note

Unlike import, scopedImport does not memoize evaluation results. While the parsing result may be reused, each call produces a distinct value. This is observable through performance and side effects such as builtins.trace.

The path argument must meet the same criteria as an interpolated expression.

If path is a directory, the file default.nix in that directory is used if it exists.

Example

Create a file greet.nix:

# greet.nix
"${greeting}, ${name}!"

Import it with additional variables in scope:

scopedImport { greeting = "Hello"; name = "World"; } ./greet.nix
"Hello, World!"

Evaluation aborts if the file doesn't exist or contains an invalid Nix expression.

Implementation

This function is implemented in c++ and is part of the native nix runtime.

src/libexpr/primops.cc:316

static RegisterPrimOp primop_scopedImport(
    {.name = "scopedImport",
     .args = {"scope", "path"},
     .doc = R"(
      Load, parse, and return the Nix expression in the file *path*, with the attributes from *scope* available as variables in the lexical scope of the imported file.

      This function is similar to [`import`](#builtins-import), but allows you to provide additional variables that will be available in the scope of the imported expression.
      The *scope* argument must be an attribute set; each attribute becomes a variable available in the imported file.
      Built-in functions and values remain accessible unless shadowed by *scope* attributes.

      > **Note**
      >
      > Variables from *scope* shadow built-ins with the same name, allowing you to override built-ins for the imported expression.

      > **Note**
      >
      > Unlike [`import`](#builtins-import), `scopedImport` does not memoize evaluation results.
      > While the parsing result may be reused, each call produces a distinct value.
      > This is observable through performance and side effects such as [`builtins.trace`](#builtins-trace).

      The *path* argument must meet the same criteria as an [interpolated expression](@docroot@/language/string-interpolation.md#interpolated-expression).

      If *path* is a directory, the file `default.nix` in that directory is used if it exists.

      > **Example**
      >
      > Create a file `greet.nix`:
      >
      > ```nix
      > # greet.nix
      > "${greeting}, ${name}!"
      > ```
      >
      > Import it with additional variables in scope:
      >
      > ```nix
      > scopedImport { greeting = "Hello"; name = "World"; } ./greet.nix
      > ```
      >
      >     "Hello, World!"

      Evaluation aborts if the file doesn't exist or contains an invalid Nix expression.
    )",
     .impl = [](EvalState & state, const PosIdx pos, Value ** args, Value & v) {
         import(state, pos, *args[1], args[0], v);
     }})