nix-inspect

repository·main·Indexed 19 days ago

https://github.com/bluskript/nix-inspect

A ranger-like Terminal User Interface (TUI) for inspecting NixOS configurations and arbitrary Nix expressions. It provides an interactive way to browse complex Nix structures, replacing manual REPL navigation. The tool supports loading configurations via filesystem paths, raw Nix expressions, or NIX_PATH, and includes Vim-like keybindings and a bookmarking system via config.json.

Tokens
2.2K
Snippets
10
Records
11
Agent score
65%

What's inside nix-inspect

  1. Install nix-inspect via Nix Flakes

    main

    To add nix-inspect to your NixOS configuration using Flakes, add the repository as an input and then include the default package in your environment.systemPackages.

    # In your flake inputs
    { 
      inputs = {
        nix-inspect.url = "github:bluskript/nix-inspect";
      };
    }
    
    # In your configuration module
    { inputs, ... }: {
      environment.systemPackages = [
        inputs.nix-inspect.packages.default
      ];
    }
  2. Run nix-inspect without installation

    main

    You can quickly try out nix-inspect using nix run without needing to install it into your system configuration.

    nix run github:bluskript/nix-inspect
  3. Configure nix-inspect via config.json

    main

    The application uses a config.json file to manage bookmarks for different Nix configurations. This file is stored in the local project configuration directory.

    Config Structure

    The configuration is a JSON object containing a list of bookmarks. Each bookmark includes a display name and a path (represented as a BrowserPath).

    {
      "bookmarks": [
        {
          "display": "hostname-config",
          "path": "/etc/nixos/nixos-config.nix"
        }
      ]
    }

    Automatic Configuration Generation

    If no configuration file exists, nix-inspect will automatically generate one based on your system's hostname and current user. It creates bookmarks for:

    1. The hostname-based NixOS configuration: .nixosConfigurations.<hostname>
    2. The user-specific Home Manager configuration: .nixosConfigurations.<hostname>.config.home-manager.users.<user>
    {
      "bookmarks": [
        {
          "display": "my-machine",
          "path": ".nixosConfigurations.my-machine"
        }
      ]
    }
  4. Use nix-inspect key bindings

    main

    The TUI uses Vim-like keybindings for navigation and specialized modes for path manipulation and searching.

    Key             | Behavior
    ----------------|---------------------------
    q               | Exit
    h / left arrow  | Navigate up a level
    j / down arrow  | Select lower item
    k / up arrow   | Select upper item
    l / right arrow | Enter selected item
    f / "/"         | Search
    ctrl+d          | Half-Page Down
    ctrl+u          | Half-Page Up
    s               | Save bookmark
    .               | Path Navigator mode
    n               | Next Search Occurence
    N               | Previous Search Occurence
  5. Reference the nix-inspect CLI flags

    main

    Use these flags to control which Nix expression or path the TUI inspects.

    --expr, -e   load an arbitrary expression
    --path, -p    load a config at a specific path
  6. Load arbitrary Nix expressions or specific paths

    main

    By default, nix-inspect attempts to load your configuration from /etc/nixos (for Flakes) or the path defined in NIX_PATH (for legacy Nix). You can override this behavior using the following flags:

    # Load an arbitrary expression
    nix-inspect -e "{ a = 1; }"
    
    # Load a config at a specific path
    nix-inspect -p /persist/etc/nixos
  7. Use the nix-inspect CLI to inspect Nix expressions or paths

    main

    The nix-inspect CLI allows you to inspect Nix configurations by providing either a specific Nix expression or a filesystem path. The tool automatically determines whether to treat a path as a Flake or a standard Nix configuration.

    CLI Arguments

    FlagShortDescription
    --path-pA filesystem path to a Nix file or directory.
    --expr-eA raw Nix expression string.

    Resolution Logic

    1. If --expr is provided: The tool uses the provided string directly as the Nix expression.
    2. If --path is provided:
      • If the path is a file ending in flake.nix (or contains a flake.nix), it is treated as a Flake using builtins.getFlake "<path>".
      • Otherwise, it is treated as a standard Nix configuration using an import statement.
    3. If no arguments are provided:
      • It first checks /etc/nixos/flake.nix.
      • If not found, it searches for the nixos-config entry in your NIX_PATH environment variable.
      • It falls back to treating the directory found in NIX_PATH (or the current directory) as a standard Nix configuration.
    # Inspect a specific path
    nix-inspect --path /path/to/my/config
    
    # Inspect a specific flake
    nix-inspect --path /path/to/flake-dir
    
    # Inspect a raw Nix expression
    nix-inspect --expr "{ options = {}; config = {}; }"
  8. Use WorkerHost to interact with Nix workers

    main

    The WorkerHost struct manages the lifecycle of a Nix worker process. It uses a background thread to communicate with a worker binary via stdin and stdout.

    To use it, call WorkerHost::new(expr) with a Nix expression. This returns a host containing two channels:

    1. tx: A kanal::Sender<BrowserPath> used to send new paths (expressions) to the worker for inspection.
    2. rx: A kanal::Receiver<(BrowserPath, PathData)> used to receive the results of those inspections.

    When a path is sent via tx, the receiver will first emit a PathData::Loading state for that path, followed by either the parsed NixValue or a PathData::Error if the inspection fails.

    // Example conceptual usage
    let host = WorkerHost::new("builtins.attrset".to_string());
    
    // Send a path to inspect
    host.tx.send(some_browser_path).unwrap();
    
    // Receive the result
    if let Ok((path, data)) = host.rx.recv() {
        match data {
            PathData::Loading => println!("Loading..."),
            PathData::Error(e) => eprintln!("Error: {}", e),
            _ => println!("Received data for {:?}", path),
        }
    }
  9. Find Nix configuration path via NIX_PATH

    main

    The find_in_nix_path function resolves the Nix configuration path by inspecting the NIX_PATH environment variable. It specifically looks for the nixos-config key.

    It splits the NIX_PATH string by :, then parses each segment for an = to find the value associated with nixos-config. If no such key is found, it defaults to the current directory (.).

  10. The NixValue data format

    main

    The NixValue enum represents the serialized data types returned by the Nix worker. When consuming the worker's output, values are tagged with a type field and the actual data is contained within a data field. The following mapping is used for serialization:

    TypeJSON TagData TypeDescription
    Thunk"0"N/AA deferred Nix computation
    Int"1"i64A 64-bit integer
    Float"2"f64A 64-bit float
    Bool"3"boolA boolean value
    String"4"StringA text string
    Path"5"StringA Nix path
    Null"6"N/AA null value
    Attrs"7"Vec<String>A list of attribute names
    List"8"usizeThe length of a list
    Function"9"N/AA Nix function
    External"10"N/AAn external value
    Error"11"StringAn error message string
    {
      "type": "4",
      "data": "example string"
    }