diff --git a/.github/workflows/check-build.yml b/.github/workflows/check-build.yml index 29b3dbf..20ff4d5 100644 --- a/.github/workflows/check-build.yml +++ b/.github/workflows/check-build.yml @@ -6,8 +6,8 @@ on: - master - develop jobs: - check: - name: Flake Check (x86_64 only) + check-emacs: + name: Flake Check emacs (x86_64 only) runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 @@ -34,9 +34,43 @@ jobs: nix-store --import < nix-store.dump || true rm nix-store.dump fi - - run: | + - name: Run checks in emacs + run: | nix build .#checks.x86_64-linux.init-example-el - name: Export /nix/store contents if: ${{ !steps.cache-nix-store.outputs.cache-hit }} run: | 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 diff --git a/default.nix b/default.nix index e159b35..82f4bb8 100644 --- a/default.nix +++ b/default.nix @@ -1,5 +1,5 @@ { # The files would be going to ~/.config/doom (~/.doom.d) -doomPrivateDir + doomPrivateDir /* Extra packages to install Useful for non-emacs packages containing emacs bindings (e.g. @@ -8,8 +8,7 @@ doomPrivateDir Example: extraPackages = epkgs: [ pkgs.mu ]; */ -, extraPackages ? epkgs: - [ ] +, extraPackages ? epkgs: [ ] /* Extra configuration to source during initialization 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 as `emacsPackages`. */ @@ -54,7 +52,8 @@ doomPrivateDir "emacs-overlay" = fetchFromGitHub { owner = /* ...*\/; }; }; */ -, dependencyOverrides ? { }, lib, pkgs, stdenv, buildEnv, makeWrapper +, dependencyOverrides ? { } +, lib, pkgs, stdenv, buildEnv, makeWrapper , runCommand, fetchFromGitHub, substituteAll, writeShellScript , 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"); let + isEmacs29 = lib.versionAtLeast emacsPackages.emacs.version "29"; flake = (import (let lock = with builtins; fromJSON (readFile ./flake.lock); in @@ -193,7 +193,7 @@ let }; # Stage 4: `extraConfig` is merged into private configuration - doomDir = pkgs.runCommand "doom-private" { + doomDir = runCommand "doom-private" { inherit extraConfig; passAsFile = [ "extraConfig" ]; } '' @@ -202,23 +202,38 @@ let chmod u+w $out/config.el cat $extraConfigPath > $out/config.extra.el cat > $out/config.el << EOF - (load "${builtins.toString doomPrivateDir}/config.el") + (load "${doomPrivateDir}/config.el") (load "$out/config.extra.el") EOF ''; # Stage 5: catch-all wrapper capable to run doom-emacs even # without installing ~/.emacs.d + # TODO: remove once Emacs 29+ is released and commonly available emacs = let load-config-from-site = writeTextDir "share/emacs/site-lisp/default.el" '' (message "doom-emacs is not placed in `doom-private-dir', loading from `site-lisp'") - (when (> emacs-major-version 26) - (load "${doom-emacs}/early-init.el")) - (load "${doom-emacs}/core/core-start.el") + ${lib.optionalString (!isEmacs29) '' + (load "${doom-emacs}/early-init.el") + (load "${doom-emacs}/core/core-start.el") + ''} ''; 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" '' 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" @@ -227,13 +242,23 @@ let ''; in emacs.overrideAttrs (esuper: 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 = '' wrapEmacs() { - wrapProgram $1 \ - --set DOOMDIR ${doomDir} \ - --set NIX_DOOM_EMACS_BINARY $1 \ - --set __DEBUG_doom_emacs_DIR ${doom-emacs} \ - --set __DEBUG_doomLocal_DIR ${doomLocal} + local -a wrapArgs=( + --set DOOMDIR ${doomDir} + --set NIX_DOOM_EMACS_BINARY $1 + --set __DEBUG_doom_emacs_DIR ${doom-emacs} + --set __DEBUG_doomLocal_DIR ${doomLocal} + ) + ${initDirArgs} + + wrapProgram $1 "''${wrapArgs[@]}" } for prog in $out/bin/*; do diff --git a/flake.nix b/flake.nix index 86b3971..5308ea3 100644 --- a/flake.nix +++ b/flake.nix @@ -87,7 +87,7 @@ 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; in eachDefaultSystem (system: let pkgs = import nixpkgs { inherit system; }; @@ -100,12 +100,27 @@ pkgs.callPackage self (args // { dependencyOverrides = (inputs // dependencyOverrides); }); }) // eachSystem [ "x86_64-linux" "aarch64-darwin" ] (system: { - checks = { - init-example-el = self.outputs.package.${system} { - doomPrivateDir = ./test/doom.d; - dependencyOverrides = inputs; - }; - }; + 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} { + doomPrivateDir = ./test/doom.d; + 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; }; diff --git a/modules/home-manager.nix b/modules/home-manager.nix index 18807de..63ab768 100644 --- a/modules/home-manager.nix +++ b/modules/home-manager.nix @@ -91,6 +91,7 @@ in in mkMerge ([ { + # TODO: remove once Emacs 29+ is released and commonly available home.file.".emacs.d/init.el".text = '' (load "default.el") '';