{ config, lib, pkgs, ... }: with lib; let cfg = config.home.roles.emacs; doomEmacs = pkgs.fetchFromGitHub { owner = "doomemacs"; repo = "doomemacs"; rev = "38d94da67dc84897a4318714dcc48494c016d8c4"; sha256 = "sha256-Uc6qONH3jjUVDgW+pPBCGC7mh88ZY05u1y37fQrsxq0="; }; # Shared emacs packages emacsPackages = epkgs: [ epkgs.vterm epkgs.treesit-grammars.with-all-grammars ]; # Default emacs configuration with vterm support defaultEmacsPackage = if pkgs.stdenv.isDarwin then pkgs.emacs-macport.pkgs.withPackages emacsPackages else pkgs.emacs.pkgs.withPackages emacsPackages; # Path to doom config directory (relative to this file) doomConfigDir = ./doom; in { options.home.roles.emacs = { enable = mkEnableOption "Doom Emacs with vterm and tree-sitter support"; prebuiltDoom = mkOption { type = types.bool; default = false; description = '' Use nix-doom-emacs-unstraightened to pre-build all Doom packages at nix build time. This eliminates the need to run `doom sync` after first boot, making it ideal for live USB images or immutable systems. When enabled, the doom configuration is read-only (stored in nix store). ''; }; }; config = mkIf cfg.enable (mkMerge [ # Common configuration for both modes { home.packages = [ pkgs.emacs-all-the-icons-fonts pkgs.fira-code pkgs.fontconfig pkgs.graphviz pkgs.isort pkgs.nerd-fonts.fira-code pkgs.nerd-fonts.droid-sans-mono pkgs.nil # nix lsp language server pkgs.nixfmt-rfc-style (pkgs.ripgrep.override {withPCRE2 = true;}) pkgs.pipenv pkgs.poetry pkgs.python3 ]; fonts.fontconfig.enable = true; } # Standard Doom Emacs mode (requires doom sync at runtime) (mkIf (!cfg.prebuiltDoom) { programs.emacs = { enable = true; package = defaultEmacsPackage; }; # Mount emacs and tree-sitter grammars from nix store home.file = { "${config.xdg.configHome}/emacs".source = doomEmacs; }; home.sessionPath = [ "${config.xdg.configHome}/emacs/bin" ]; home.sessionVariables = { DOOMDIR = "${config.xdg.configHome}/doom"; DOOMLOCALDIR = "${config.xdg.dataHome}/doom"; }; # TODO: Use mkOutOfStoreSymlink instead? home.activation.doomConfig = lib.hm.dag.entryAfter ["writeBoundary"] '' # Always remove and recreate the symlink to ensure it points to the source directory rm -rf "${config.xdg.configHome}/doom" ln -sf "${config.home.homeDirectory}/nixos-configs/home/roles/emacs/doom" "${config.xdg.configHome}/doom" ''; }) # Pre-built Doom Emacs mode (no doom sync needed - ideal for live USB) (mkIf cfg.prebuiltDoom { programs.doom-emacs = { enable = true; doomDir = doomConfigDir; doomLocalDir = "${config.xdg.dataHome}/doom"; # Add extra packages that aren't part of Doom but needed for our config extraPackages = epkgs: [ epkgs.vterm epkgs.treesit-grammars.with-all-grammars ]; }; }) ]); }