Nix Language

NixOS

Resources

https://nixos.org/manual/nixpkgs/stable/

https://nix.dev/manual/nix/2.32/

https://nix.dev/tutorials/

https://nix.dev/reference/

https://nix.dev/guides/

https://nix.dev/concepts/

nixos-and-flakes-book

Concepts

flake

flake.nix 核心文件

</home/disk/Dev/hlissner-dotfiles/flake.nix>

• flake.nix 是 Nix flake 的“入口文件”,在这个仓库里基本就是整套配置的中枢,大致做这些事:

  1. 声明依赖 (inputs)

    比如用到的 Nixpkgs 版本、外部 flake(home-manager 等),都在 flake.nix 里统一锁定和引用。
  2. 导出结果 (outputs)

    定义这个仓库对外提供什么:
    • NixOS 主机配置(hosts/ 下的机器)
    • 模块、包、overlay、devShell 等

      这样你可以用 nix build、nix flake check、nix develop 等直接调用。
  3. 自动发现项目结构

    按本仓库的约定,它会自动发现并挂上:
    • hosts/ 里的主机
    • modules/ 里的模块
    • packages/ 里的包
    • overlays/、test/ 等
  4. 给工具链提供统一入口

    像 bin/hey sync、bin/hey build、nix flake check、nix develop 等命令,最终都是围绕 flake.nix 中的定义在跑。

简单说:flake.nix 定义了“这套 dotfiles/系统配置由哪些依赖组成、导出哪些配置和命令”,其它目录 (hosts/, modules/ 等) 都是被它组织起来的。

module

在 NixOS / home-manager 体系里,module = 一块可组合的配置单元,专门用来描述“这个功能需要哪些选项、怎么启用”。

更形式化一点,一个 Nix 模块基本就是这样的函数:

{ config, lib, pkgs, ... }:
 
let
  cfg = config.modules.desktop.hyprland;
in {
  # 1. 声明这个模块有哪些配置项(options)
  options.modules.desktop.hyprland.enable = lib.mkOption {
    type = lib.types.bool;
    default = false;
    description = "Enable Hyprland desktop.";
  };
 
  # 2. 根据这些配置项,实际写系统配置(config)
  config = lib.mkIf cfg.enable {
    services.xserver.enable = true;
    # ...
  };
}

可以这样理解:

  1. options:声明“我提供哪些设置”
    • 起名:modules.desktop.hyprland.enable 这种 kebab-case 分层命名。
    • 指明类型(bool/string/list)、默认值、说明等。
    • 其它模块/主机就可以设置这些选项,比如 modules.desktop.hyprland.enable = true;。
  2. config:根据选项生成最终系统配置
    • 里面通常写的是 NixOS / home-manager 的标准选项:比如 services.*, users.*, programs.*。
    • 多个 module 可以同时给同一个 config.services.sshd 之类的字段赋值,Nix 会按规则自动合并(列表拼接、attrset 合并等)。
  3. 模块是“可合并的配置片段”
    • 顶层会把所有模块(官方模块、自定义模块、host 自己写的模块)收集起来,一起 merge 成一个巨大的 config。
    • 你不需要有“主配置文件把所有内容写满”,而是拆成很多小模块,每个模块负责一个功能/子系统。

overlay

pakcages

nix cli

develop

nix develop builds a development shell defined by a flake (or shell.nix) and drops you into it with the declared tools on PATH.

What it does here

  • Evaluates devShells.<system>.default in flake.nix.
  • Builds required Nix packages (python, sdcv, mpv, etc.), then runs the shellHook.
  • In our flake, shellHook sets NLTK_DATA/PATH, creates a local .venv on first run, installs the pip-only bits, and downloads NLTK data.
  • You get an interactive shell with all those tools available; they vanish when you exit.

Common flags

  • nix develop (no args): uses devShells.<system>.default in flake.nix in the current dir.
  • nix develop .#name: pick a specific devShell output (e.g., .#default or .#docs).
  • nix develop —command <cmd> …: run one command inside the dev shell without opening an interactive shell.
  • nix develop —impure: allow environment variables from your session to pass through (useful if the flake wants them).
  • nix develop —accept-flake-config: needed if the flake sets nixConfig options and you trust them.

How it differs from nix shell

  • nix shell only provides packages; nix develop also runs shellHook and honors a richer dev environment description (useful for bootstrapping venvs, exporting vars, etc.).

Typical workflow

  1. nix develop inside the repo.
  2. Work; the PATH and env are already set up.
  3. Exit with exit/Ctrl-D—your global system stays untouched.