nix-ide

repository·main·Indexed 18 days ago

https://github.com/nix-community/vscode-nix-ide

Visual Studio Code extension providing Nix language support, including syntax highlighting, linting via nix-instantiate, snippets, and formatting. It supports integration with Nix Language Servers (LSP) such as nil and nixd, allowing for advanced completion and configuration for NixOS, Home Manager, and Nix-Darwin Flakes. Version 0.5.13.

Tokens
2.2K
Snippets
5
Records
13
Agent score
66%

What's inside nix-ide

  1. Quickstart for Nix IDE

    main

    To get started with Nix support in Visual Studio Code:

    1. Install the extension and open a .nix file.
    2. Syntax Highlighting: Works automatically for Nix files and Nix code blocks inside markdown files.
    3. Formatting: Auto-formatting works out of the box if nixfmt is in your $PATH.
    4. Linting: Syntax errors are linted using nix-instantiate.
    5. Snippets: Includes snippets for conditional expressions, let/with expressions, and recursive sets.
    6. Path Completion: For path completion, install the Path Intellisense extension.
  2. Enable and configure LSP support

    main

    Full language support (advanced linting, completion, etc.) requires a Nix Language Server (LSP). You can enable it and configure the server path and its specific settings in your VS Code settings.json.

    Key settings:

    • nix.enableLanguageServer: Set to true to enable LSP.
    • nix.serverPath: The executable for your chosen LSP (e.g., nil, nixd, or an array of ["executable", "arg"]).
    • nix.serverSettings.{lsp_name}: An object containing configuration specific to the chosen LSP.
    {
      "nix.enableLanguageServer": true,
      "nix.serverPath": "nil",
      "nix.serverSettings": {
        "nil": {
          "formatting": {
            "command": ["nixfmt"]
          }
        }
      }
    }
  3. Nix Language Grammar Overview

    main

    The Nix language grammar provides syntax highlighting for .nix files. It is a regex-based highlighter designed to be compatible with nixpkgs.

    Limitations & Known Issues:

    • Regex Constraints: Because it uses regex rather than a full parser, it is 'looser' than the actual Nix parser. Some legal Nix constructs may be incorrectly marked as invalid/illegal.
    • Multi-line Matches: Multi-line matches are not supported by the grammar.
    • Attrset Issue: If the closing brace } of an empty { } block is located at column 1 of a line, the grammar may prematurely terminate the expression and mark subsequent rules as invalid.

    Supported File Types:

    • .nix
  4. How the Nix language server is resolved

    main

    The extension automatically attempts to find a compatible Nix language server on your system. It follows this priority order:

    1. Configured Path: If nix.serverPath is set in your VS Code settings, the extension uses those specific commands.
    2. Default Candidates: If no path is configured, the extension searches for nixd or nil in your system $PATH.
    3. Fallback: If no candidates are found, it defaults to attempting to run nixd.

    If no valid language server is found, the extension will display an error message with a link to the installation instructions in the README.

  5. How Nix linting works

    main

    The extension provides linting by running nix-instantiate --parse <filename> against saved Nix files.

    It parses the stderr output from the command to identify:

    • Syntax errors: e.g., error: syntax error, unexpected ']', expecting ';', at /path/to/file.nix:19:3
    • Symbol errors: e.g., error: undefined variable 'openjdk' at /path/to/file.nix:14:5

    Diagnostics are automatically updated when you open a document, save a document, or close a document. Note that linting only triggers for documents that are:

    1. Saved to disk (not "dirty").
    2. Using the nix language identifier.
    3. Using the file scheme.
  6. Configure a custom formatter

    main

    You can specify a custom formatter by setting nix.formatterPath. The command must accept file contents on stdin and return formatted text on stdout.

    Important: If you have configured an LSP plugin (via nix.enableLanguageServer), the nix.formatterPath setting is ignored in favor of the LSP's formatting configuration.

    {
        "nix.formatterPath": "nixfmt"
        // or "alejandra"
        // or an array of args: "nix.formatterPath": ["treefmt", "--stdin", "{file}"]
    }
  7. Configure nixd options for Flakes

    main

    When using nixd as your language server, you can provide Nix expressions to populate the available options. This is particularly useful for Flake-based configurations. You can use the ${workspaceFolder} variable to define paths relative to your project.

    Common patterns include:

    • NixOS: Use builtins.getFlake to point to your flake and access nixosConfigurations.<name>.options.
    • Home Manager: Access homeConfigurations.<name>.options.
    • Nix-Darwin: Access darwinConfigurations.<name>.options.

    If Home Manager is integrated as a NixOS module, use the specific expression pattern to extract the sub-options from the NixOS configuration.

    {
      "nix.serverSettings": {
        "nixd": {
          "options": {
            "nixos": {
              "expr": "(builtins.getFlake "/absolute/path/to/flake").nixosConfigurations.<name>.options",
            },
            "home-manager": {
              "expr": "(builtins.getFlake "/absolute/path/to/flake").homeConfigurations.<name>.options",
            },
            "nix-darwin": {
              "expr": "(builtins.getFlake "${workspaceFolder}/path/to/flake").darwinConfigurations.<name>.options",
            }
          }
        }
      }
    }
  8. Configure a custom Nix formatter

    main

    The Nix IDE extension supports custom formatters by allowing you to specify a command path via the formatterPath configuration setting.

    When a formatting request is made, the extension replaces the {file} placeholder in your configured command with the absolute path of the current document. The extension then executes this command, passing the selected text (or the entire document) via standard input (stdin) and expects the formatted text to be returned via standard output (stdout).

    Requirements for the formatter command:

    • It must accept the text to be formatted via stdin.
    • It must output the formatted text via stdout.
    • It must return an exit code of 0 for successful formatting. If the exit code is non-zero, no formatting changes will be applied.
  9. Configure the Language Server (LSP)

    main

    The extension supports using a Language Server for Nix development. You can control its behavior via the following settings:

    • nix.enableLanguageServer: A boolean to enable or disable the LSP (defaults to false).
    • nix.serverPath: The path to the language server executable (defaults to nixd). This can be a string or an array of strings.
    • nix.serverSettings: An object containing settings to be passed directly to the language server.
    • nix.hiddenLanguageServerErrors: An array of error kinds (strings) that should be hidden from the user.
    {
      "nix": {
        "enableLanguageServer": true,
        "serverPath": "nixd",
        "serverSettings": {
          "some-lsp-setting": true
        },
        "hiddenLanguageServerErrors": ["someErrorType"]
      }
    }
  10. Configure the Nix formatter

    main

    The extension uses the nix.formatterPath setting to determine which tool to use for formatting Nix files. You can provide a direct path to an executable or use one of the supported shorthand aliases:

    • nixfmt (default): Uses the provided path as the command.
    • nix3-fmt: Automatically expands to nix fmt -- --.
    • treefmt: Automatically expands to treefmt --stdin {file}.

    If you provide a custom path, it must be a string or an array of strings representing the command and its arguments.

    {
      "nix": {
        "formatterPath": "nix3-fmt"
      }
    }
  11. Configure Nix server settings

    main

    The extension supports passing custom settings to the language server via the nix.serverSettings configuration key. These settings are mapped to the language server's configuration requests via middleware.

    When the language server requests configuration for a specific section, the extension looks up that section within your nix.serverSettings object and returns it to the server.