Use --init-directory
in Emacs 29+ (#191)
* Use `--init-directory` in Emacs 29+ This will allow a few advantages: - We can load `early-init.el` file properly, fixing Flash Of Unstyled Contents (FOUC) issues and improving the performance slightly - Eventually we can drop `default.el` file loading in Home-Manager module. Not done here since this would complicate the code without necessity, however this can be done once Emacs 29+ is default * Fix build in Emacs <29 * Add #checks.<arch>.init-example-el-emacsGit * Add .#checks.x86_64-linux.init-example-el-emacsGit to CI * Fix review issues * Move config files to share/emacs.d * Separate tests in two steps * Add TODOS * Simplify emacs-dir generation
This commit is contained in:
committed by
GitHub
parent
a59295c11e
commit
9111d480a8
40
.github/workflows/check-build.yml
vendored
40
.github/workflows/check-build.yml
vendored
@ -6,8 +6,8 @@ on:
|
|||||||
- master
|
- master
|
||||||
- develop
|
- develop
|
||||||
jobs:
|
jobs:
|
||||||
check:
|
check-emacs:
|
||||||
name: Flake Check (x86_64 only)
|
name: Flake Check emacs (x86_64 only)
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
@ -34,9 +34,43 @@ jobs:
|
|||||||
nix-store --import < nix-store.dump || true
|
nix-store --import < nix-store.dump || true
|
||||||
rm nix-store.dump
|
rm nix-store.dump
|
||||||
fi
|
fi
|
||||||
- run: |
|
- name: Run checks in emacs
|
||||||
|
run: |
|
||||||
nix build .#checks.x86_64-linux.init-example-el
|
nix build .#checks.x86_64-linux.init-example-el
|
||||||
- name: Export /nix/store contents
|
- name: Export /nix/store contents
|
||||||
if: ${{ !steps.cache-nix-store.outputs.cache-hit }}
|
if: ${{ !steps.cache-nix-store.outputs.cache-hit }}
|
||||||
run: |
|
run: |
|
||||||
nix-store --export $(nix-store -qR /nix/store/*-doom-emacs) > nix-store.dump
|
nix-store --export $(nix-store -qR /nix/store/*-doom-emacs) > nix-store.dump
|
||||||
|
check-emacsGit:
|
||||||
|
name: Flake Check emacsGit (x86_64 only)
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
# Nix Flakes doesn't work on shallow clones
|
||||||
|
fetch-depth: 0
|
||||||
|
- uses: cachix/install-nix-action@v17
|
||||||
|
with:
|
||||||
|
name: nix-community
|
||||||
|
- name: Retrieve /nix/store archive
|
||||||
|
uses: actions/cache@v3
|
||||||
|
id: cache-nix-store-emacsGit
|
||||||
|
with:
|
||||||
|
path: nix-store.dump
|
||||||
|
key: nix-store-emacsGit-${{ hashFiles('flake.*') }}
|
||||||
|
restore-keys: |
|
||||||
|
nix-store-emacsGit-
|
||||||
|
- name: Import /nix/store contents
|
||||||
|
if: ${{ steps.cache-nix-store-emacsGit.outputs.cache-hit }}
|
||||||
|
run: |
|
||||||
|
if [[ -f nix-store.dump ]]; then
|
||||||
|
nix-store --import < nix-store.dump || true
|
||||||
|
rm nix-store.dump
|
||||||
|
fi
|
||||||
|
- name: Run checks in emacsGit
|
||||||
|
run: |
|
||||||
|
nix build .#checks.x86_64-linux.init-example-el-emacsGit
|
||||||
|
- name: Export /nix/store contents
|
||||||
|
if: ${{ !steps.cache-nix-store-emacsGit.outputs.cache-hit }}
|
||||||
|
run: |
|
||||||
|
nix-store --export $(nix-store -qR /nix/store/*-doom-emacs) > nix-store.dump
|
||||||
|
53
default.nix
53
default.nix
@ -1,5 +1,5 @@
|
|||||||
{ # The files would be going to ~/.config/doom (~/.doom.d)
|
{ # The files would be going to ~/.config/doom (~/.doom.d)
|
||||||
doomPrivateDir
|
doomPrivateDir
|
||||||
/* Extra packages to install
|
/* Extra packages to install
|
||||||
|
|
||||||
Useful for non-emacs packages containing emacs bindings (e.g.
|
Useful for non-emacs packages containing emacs bindings (e.g.
|
||||||
@ -8,8 +8,7 @@ doomPrivateDir
|
|||||||
Example:
|
Example:
|
||||||
extraPackages = epkgs: [ pkgs.mu ];
|
extraPackages = epkgs: [ pkgs.mu ];
|
||||||
*/
|
*/
|
||||||
, extraPackages ? epkgs:
|
, extraPackages ? epkgs: [ ]
|
||||||
[ ]
|
|
||||||
/* Extra configuration to source during initialization
|
/* Extra configuration to source during initialization
|
||||||
|
|
||||||
Use this to refer other nix derivations.
|
Use this to refer other nix derivations.
|
||||||
@ -36,8 +35,7 @@ doomPrivateDir
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
*/
|
*/
|
||||||
, emacsPackagesOverlay ? self: super:
|
, emacsPackagesOverlay ? self: super: { }
|
||||||
{ }
|
|
||||||
/* Use bundled revision of github.com/nix-community/emacs-overlay
|
/* Use bundled revision of github.com/nix-community/emacs-overlay
|
||||||
as `emacsPackages`.
|
as `emacsPackages`.
|
||||||
*/
|
*/
|
||||||
@ -54,7 +52,8 @@ doomPrivateDir
|
|||||||
"emacs-overlay" = fetchFromGitHub { owner = /* ...*\/; };
|
"emacs-overlay" = fetchFromGitHub { owner = /* ...*\/; };
|
||||||
};
|
};
|
||||||
*/
|
*/
|
||||||
, dependencyOverrides ? { }, lib, pkgs, stdenv, buildEnv, makeWrapper
|
, dependencyOverrides ? { }
|
||||||
|
, lib, pkgs, stdenv, buildEnv, makeWrapper
|
||||||
, runCommand, fetchFromGitHub, substituteAll, writeShellScript
|
, runCommand, fetchFromGitHub, substituteAll, writeShellScript
|
||||||
, writeShellScriptBin, writeTextDir }:
|
, writeShellScriptBin, writeTextDir }:
|
||||||
|
|
||||||
@ -63,6 +62,7 @@ assert (lib.assertMsg ((builtins.isPath doomPrivateDir)
|
|||||||
"doomPrivateDir must be either a path, a derivation or a stringified store path");
|
"doomPrivateDir must be either a path, a derivation or a stringified store path");
|
||||||
|
|
||||||
let
|
let
|
||||||
|
isEmacs29 = lib.versionAtLeast emacsPackages.emacs.version "29";
|
||||||
flake =
|
flake =
|
||||||
(import
|
(import
|
||||||
(let lock = with builtins; fromJSON (readFile ./flake.lock); in
|
(let lock = with builtins; fromJSON (readFile ./flake.lock); in
|
||||||
@ -193,7 +193,7 @@ let
|
|||||||
};
|
};
|
||||||
|
|
||||||
# Stage 4: `extraConfig` is merged into private configuration
|
# Stage 4: `extraConfig` is merged into private configuration
|
||||||
doomDir = pkgs.runCommand "doom-private" {
|
doomDir = runCommand "doom-private" {
|
||||||
inherit extraConfig;
|
inherit extraConfig;
|
||||||
passAsFile = [ "extraConfig" ];
|
passAsFile = [ "extraConfig" ];
|
||||||
} ''
|
} ''
|
||||||
@ -202,23 +202,38 @@ let
|
|||||||
chmod u+w $out/config.el
|
chmod u+w $out/config.el
|
||||||
cat $extraConfigPath > $out/config.extra.el
|
cat $extraConfigPath > $out/config.extra.el
|
||||||
cat > $out/config.el << EOF
|
cat > $out/config.el << EOF
|
||||||
(load "${builtins.toString doomPrivateDir}/config.el")
|
(load "${doomPrivateDir}/config.el")
|
||||||
(load "$out/config.extra.el")
|
(load "$out/config.extra.el")
|
||||||
EOF
|
EOF
|
||||||
'';
|
'';
|
||||||
|
|
||||||
# Stage 5: catch-all wrapper capable to run doom-emacs even
|
# Stage 5: catch-all wrapper capable to run doom-emacs even
|
||||||
# without installing ~/.emacs.d
|
# without installing ~/.emacs.d
|
||||||
|
# TODO: remove once Emacs 29+ is released and commonly available
|
||||||
emacs = let
|
emacs = let
|
||||||
load-config-from-site = writeTextDir "share/emacs/site-lisp/default.el" ''
|
load-config-from-site = writeTextDir "share/emacs/site-lisp/default.el" ''
|
||||||
(message "doom-emacs is not placed in `doom-private-dir',
|
(message "doom-emacs is not placed in `doom-private-dir',
|
||||||
loading from `site-lisp'")
|
loading from `site-lisp'")
|
||||||
(when (> emacs-major-version 26)
|
${lib.optionalString (!isEmacs29) ''
|
||||||
(load "${doom-emacs}/early-init.el"))
|
(load "${doom-emacs}/early-init.el")
|
||||||
(load "${doom-emacs}/core/core-start.el")
|
(load "${doom-emacs}/core/core-start.el")
|
||||||
|
''}
|
||||||
'';
|
'';
|
||||||
in (emacsPackages.emacsWithPackages (epkgs: [ load-config-from-site ]));
|
in (emacsPackages.emacsWithPackages (epkgs: [ load-config-from-site ]));
|
||||||
|
|
||||||
|
# create a `emacs.d` dir to be loaded using `--init-directory` flag from Emacs 29+
|
||||||
|
# this will allow proper usage of `early-init.el`, fixing FOUC issues and improving
|
||||||
|
# startup performance
|
||||||
|
emacs-dir = runCommand "emacs-dir" { } ''
|
||||||
|
mkdir -p $out
|
||||||
|
cat > $out/early-init.el << EOF
|
||||||
|
(load "${doom-emacs}/early-init.el")
|
||||||
|
EOF
|
||||||
|
cat > $out/init.el << EOF
|
||||||
|
(load "${doom-emacs}/core/core-start.el")
|
||||||
|
EOF
|
||||||
|
'';
|
||||||
|
|
||||||
build-summary = writeShellScript "build-summary" ''
|
build-summary = writeShellScript "build-summary" ''
|
||||||
printf "\n${fmt.green}Successfully built nix-doom-emacs!${fmt.reset}\n"
|
printf "\n${fmt.green}Successfully built nix-doom-emacs!${fmt.reset}\n"
|
||||||
printf "${fmt.bold} ==> doom-emacs is installed to ${doom-emacs}${fmt.reset}\n"
|
printf "${fmt.bold} ==> doom-emacs is installed to ${doom-emacs}${fmt.reset}\n"
|
||||||
@ -227,13 +242,23 @@ let
|
|||||||
'';
|
'';
|
||||||
in emacs.overrideAttrs (esuper:
|
in emacs.overrideAttrs (esuper:
|
||||||
let
|
let
|
||||||
|
# `--init-directory` is supported by Emacs 29+ only
|
||||||
|
initDirArgs = lib.optionalString isEmacs29 ''
|
||||||
|
if [[ $(basename $1) == emacs ]] || [[ $(basename $1) == emacs-* ]]; then
|
||||||
|
wrapArgs+=(--add-flags '--init-directory ${emacs-dir}')
|
||||||
|
fi
|
||||||
|
'';
|
||||||
cmd = ''
|
cmd = ''
|
||||||
wrapEmacs() {
|
wrapEmacs() {
|
||||||
wrapProgram $1 \
|
local -a wrapArgs=(
|
||||||
--set DOOMDIR ${doomDir} \
|
--set DOOMDIR ${doomDir}
|
||||||
--set NIX_DOOM_EMACS_BINARY $1 \
|
--set NIX_DOOM_EMACS_BINARY $1
|
||||||
--set __DEBUG_doom_emacs_DIR ${doom-emacs} \
|
--set __DEBUG_doom_emacs_DIR ${doom-emacs}
|
||||||
--set __DEBUG_doomLocal_DIR ${doomLocal}
|
--set __DEBUG_doomLocal_DIR ${doomLocal}
|
||||||
|
)
|
||||||
|
${initDirArgs}
|
||||||
|
|
||||||
|
wrapProgram $1 "''${wrapArgs[@]}"
|
||||||
}
|
}
|
||||||
|
|
||||||
for prog in $out/bin/*; do
|
for prog in $out/bin/*; do
|
||||||
|
19
flake.nix
19
flake.nix
@ -87,7 +87,7 @@
|
|||||||
flake-compat.flake = false;
|
flake-compat.flake = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
outputs = { self, nixpkgs, flake-utils, ... }@inputs:
|
outputs = { self, nixpkgs, flake-utils, emacs-overlay, ... }@inputs:
|
||||||
let inherit (flake-utils.lib) eachDefaultSystem eachSystem;
|
let inherit (flake-utils.lib) eachDefaultSystem eachSystem;
|
||||||
in eachDefaultSystem (system:
|
in eachDefaultSystem (system:
|
||||||
let pkgs = import nixpkgs { inherit system; };
|
let pkgs = import nixpkgs { inherit system; };
|
||||||
@ -100,11 +100,26 @@
|
|||||||
pkgs.callPackage self
|
pkgs.callPackage self
|
||||||
(args // { dependencyOverrides = (inputs // dependencyOverrides); });
|
(args // { dependencyOverrides = (inputs // dependencyOverrides); });
|
||||||
}) // eachSystem [ "x86_64-linux" "aarch64-darwin" ] (system: {
|
}) // eachSystem [ "x86_64-linux" "aarch64-darwin" ] (system: {
|
||||||
checks = {
|
checks =
|
||||||
|
let
|
||||||
|
pkgs = import nixpkgs {
|
||||||
|
inherit system;
|
||||||
|
# we are not using emacs-overlay's flake.nix here,
|
||||||
|
# to avoid unnecessary inputs to be added to flake.lock;
|
||||||
|
# this means we need to import the overlay in a hack-ish way
|
||||||
|
overlays = [ (import emacs-overlay) ];
|
||||||
|
};
|
||||||
|
in
|
||||||
|
{
|
||||||
init-example-el = self.outputs.package.${system} {
|
init-example-el = self.outputs.package.${system} {
|
||||||
doomPrivateDir = ./test/doom.d;
|
doomPrivateDir = ./test/doom.d;
|
||||||
dependencyOverrides = inputs;
|
dependencyOverrides = inputs;
|
||||||
};
|
};
|
||||||
|
init-example-el-emacsGit = self.outputs.package.${system} {
|
||||||
|
doomPrivateDir = ./test/doom.d;
|
||||||
|
dependencyOverrides = inputs;
|
||||||
|
emacsPackages = with pkgs; emacsPackagesFor emacsGit;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}) // {
|
}) // {
|
||||||
hmModule = import ./modules/home-manager.nix inputs;
|
hmModule = import ./modules/home-manager.nix inputs;
|
||||||
|
@ -91,6 +91,7 @@ in
|
|||||||
in
|
in
|
||||||
mkMerge ([
|
mkMerge ([
|
||||||
{
|
{
|
||||||
|
# TODO: remove once Emacs 29+ is released and commonly available
|
||||||
home.file.".emacs.d/init.el".text = ''
|
home.file.".emacs.d/init.el".text = ''
|
||||||
(load "default.el")
|
(load "default.el")
|
||||||
'';
|
'';
|
||||||
|
Reference in New Issue
Block a user