Use Doom profile loader to load our profile

This seems like a relatively sane way of loading our profile from the
Nix store. The alternatives I see are patching Doom (which I'm trying to
avoid) or setting DOOMLOCALDIR. If we set DOOMLOCALDIR, Doom sets enough
variables based on it it would be a pain to clean them up after we gain
control.

Using the profile loader lets us set doom-profile-data-dir early, which
currently only contains the profile and env file.
This commit is contained in:
Marien Zwart 2024-03-29 22:54:58 +11:00
parent 5a8220ab09
commit c1a9df33d4
No known key found for this signature in database
2 changed files with 50 additions and 9 deletions

View file

@ -12,6 +12,11 @@ it. Just skip it entirely."
:override #'doom-initialize-core-packages :override #'doom-initialize-core-packages
t) t)
(defcli! build-profile-loader-for-nix-build ()
"Write Doom's profile loader."
(let ((new-profiles (doom-profiles-autodetect)))
(doom-profiles-save new-profiles)))
(defcli! build-profile-for-nix-build () (defcli! build-profile-for-nix-build ()
"Write a Doom profile." "Write a Doom profile."
;; HACK: this initializes enough of straight (particularly ;; HACK: this initializes enough of straight (particularly

View file

@ -10,6 +10,8 @@
/* Whether to enable all default dependencies. Primarily useful for CI / /* Whether to enable all default dependencies. Primarily useful for CI /
testing. */ testing. */
full ? false, full ? false,
/* Name of doom profile to use. */
profileName ? "nix",
callPackages, callPackages,
git, git,
@ -19,6 +21,7 @@
runCommand, runCommand,
runtimeShell, runtimeShell,
writeText, writeText,
makeBinaryWrapper,
}: }:
let let
inherit (lib) optional optionalAttrs optionalString; inherit (lib) optional optionalAttrs optionalString;
@ -214,7 +217,13 @@ let
# the set from step 2. # the set from step 2.
emacsWithPackages = doomEmacsPackages.emacsWithPackages (epkgs: (map (p: epkgs.${p}) (builtins.attrNames doomPackageSet))); emacsWithPackages = doomEmacsPackages.emacsWithPackages (epkgs: (map (p: epkgs.${p}) (builtins.attrNames doomPackageSet)));
# Step 4: build a Doom profile. # Step 4: build a Doom profile and profile loader.
#
# Create both in the same derivation: we want the path to the generated
# profile in the loader (so building the loader depends on the profile), but
# I'm currently using the loader to set up Doom to write the profile to the
# right place (so building the profile depends on the loader).
stage2DoomDir = linkFarm "doom-dir-stage2" ( stage2DoomDir = linkFarm "doom-dir-stage2" (
[{ name = "cli.el"; path = ./cli2.el; } [{ name = "cli.el"; path = ./cli2.el; }
{ name = "packages.el"; path = "${doomIntermediates}/packages.el"; }] { name = "packages.el"; path = "${doomIntermediates}/packages.el"; }]
@ -232,20 +241,47 @@ let
}; };
# Required to avoid Doom erroring out at startup. # Required to avoid Doom erroring out at startup.
nativeBuildInputs = [ git ]; nativeBuildInputs = [ git ];
} } ''
# Explicitly create `straight` to get an empty build cache written there mkdir $out
# instead of an error printed on Emacs shutdown.
'' echo '
mkdir -p $out/straight ((${profileName} (user-emacs-directory . "${doomSource}")
export DOOMLOCALDIR=$out (doom-profile-data-dir . "'$out'/profiles")
("DOOMDIR" . "${stage2DoomDir}")))
' > profiles.el
export DOOMPROFILELOADFILE=$out/init.el
export DOOMPROFILELOADPATH=$PWD/profiles.el
export DOOMLOCALDIR=$(mktemp -d)
# Prevent error on Emacs shutdown writing empty build cache.
mkdir $DOOMLOCALDIR/straight
${runtimeShell} ${doomSource}/bin/doom build-profile-loader-for-nix-build
# With DOOMPROFILE set, doom-state-dir and friends are HOME-relative.
export HOME=$(mktemp -d)
export DOOMPROFILE='${profileName}';
${runtimeShell} ${doomSource}/bin/doom build-profile-for-nix-build ${runtimeShell} ${doomSource}/bin/doom build-profile-for-nix-build
rm -rf $out/state/logs
''; '';
# TODO: test HOME and DOOMPROFILE tmpdirs don't leak into profile init?
# Currently doesn't happen.
# TODO: write a package.el equiv of doom-profile--generate-package-autoloads. # TODO: write a package.el equiv of doom-profile--generate-package-autoloads.
# Doom already picks up load-path because in cli mode it inits packages.el # Doom already picks up load-path because in cli mode it inits packages.el
# But during normal startup it suppresses packages.el's auto-activation, # But during normal startup it suppresses packages.el's auto-activation,
# which means elpa/*/*-autoloads.el don't load. # which means elpa/*/*-autoloads.el don't load.
# TODO: don't set DOOMDIR in profiles.el.
pkg = runCommand "doom" {
nativeBuildInputs = [ makeBinaryWrapper ];
}
''
makeWrapper ${emacsWithPackages}/bin/emacs $out/bin/emacs \
--set DOOMPROFILELOADFILE ${doomProfile}/init.el \
--add-flags "--init-directory=${doomSource} --profile ${profileName}"
'';
in in
doomProfile pkg