Low-level nix integration to straight.el
This commit is contained in:
committed by
László Vaskó
parent
41090724c9
commit
a5d40e9754
@ -1 +1,5 @@
|
||||
# nix-straight.el
|
||||
# nix-straight.el
|
||||
|
||||
Low-level integration to [straight.el](https://github.com/raxod502/straight.el)
|
||||
|
||||
See [nix-doom-emacs](https://github.com/vlaci/nix-doom-emacs) for a usage example.
|
||||
|
73
default.nix
Normal file
73
default.nix
Normal file
@ -0,0 +1,73 @@
|
||||
{ # Package set to build the Emacs environment from
|
||||
emacsPackages
|
||||
# You may override to use your version of `straight`
|
||||
, straight ? null
|
||||
# Your `init.el` file to use for discovering and installing packages
|
||||
, emacsInitFile
|
||||
# Additional argument to pass to Emacs or your init file
|
||||
, emacsArgs ? []
|
||||
# Additional files you wish to load prior to executing package discovery
|
||||
# Good place to place to call `advice-add` from
|
||||
, emacsLoadFiles ? [] }:
|
||||
|
||||
let
|
||||
libstraight = epkgs.callPackage ./libstraight.nix { inherit epkgs; };
|
||||
epkgs =
|
||||
if straight == null then
|
||||
emacsPackages.overrideScope' (self: super:
|
||||
{ straight = self.callPackage ./straight { }; })
|
||||
else
|
||||
emacsPackages;
|
||||
|
||||
|
||||
packageJSON = libstraight.packagesJSON {
|
||||
inherit emacsInitFile emacsLoadFiles emacsArgs;
|
||||
};
|
||||
|
||||
packageList = override:
|
||||
libstraight.parsePackagesJSON (packageJSON.overrideAttrs override);
|
||||
|
||||
emacsEnv = libstraight.emacsEnv { inherit emacsInitFile emacsLoadFiles emacsArgs; };
|
||||
|
||||
in {
|
||||
/* Final environment (.emacs.d) with the populated `straight`` repository
|
||||
|
||||
The required packages can be acquired from a call to
|
||||
`packageList` function.
|
||||
|
||||
Type: emacsEnv :: { straightDir :: string, packages :: [derivation] } -> derivation
|
||||
|
||||
Example:
|
||||
emacsEnv {
|
||||
straightDir = "$out/straight";
|
||||
packages = packageList (super: { ... } );
|
||||
};
|
||||
*/
|
||||
inherit emacsEnv;
|
||||
/* Package list inferred from processing `emacsInitFile`
|
||||
|
||||
The passed function will be called via an `overrideAttrs
|
||||
call on the`underlying derivation.
|
||||
|
||||
Type: packageList :: attrs -> attrs -> derivation
|
||||
|
||||
Example:
|
||||
packageList (super: {
|
||||
src = ...;
|
||||
preInstall = ''
|
||||
...
|
||||
''
|
||||
});
|
||||
*/
|
||||
inherit packageList;
|
||||
|
||||
/* JSON formatted list of packages
|
||||
|
||||
These are the packages needed to be populated in the
|
||||
`straight` repository. Mostly for diagnostic purposes.
|
||||
|
||||
Type: packageJSON :: derivation
|
||||
|
||||
*/
|
||||
inherit packageJSON;
|
||||
}
|
82
libstraight.nix
Normal file
82
libstraight.nix
Normal file
@ -0,0 +1,82 @@
|
||||
{ lib, stdenv, epkgs, writeScript }:
|
||||
|
||||
let
|
||||
inherit (builtins) filter trace;
|
||||
inherit (lib) concatMapStringsSep escapeShellArgs importJSON flatten unique optionalString;
|
||||
|
||||
expandDependencies = packages:
|
||||
let
|
||||
withDeps = p:
|
||||
map (x:
|
||||
if x == null then [ ] else
|
||||
[ x ] ++ withDeps x.propagatedBuildInputs
|
||||
) (flatten p);
|
||||
in (unique (filter (d: d ? ename) (flatten (withDeps packages))));
|
||||
|
||||
install = repo: packages:
|
||||
let
|
||||
installPkg = repo: pkg: (''
|
||||
REPO=${repo}
|
||||
psrc=(${pkg}/share/emacs/*/*/${pkg.ename}*)
|
||||
if [[ ! -d $psrc ]]; then
|
||||
ln -snf ${pkg}/share/emacs/site-lisp $REPO/${pkg.ename}
|
||||
else
|
||||
ln -snf $psrc $REPO/${pkg.ename}
|
||||
fi
|
||||
${optionalString (pkg.src.meta ? homepage) ''
|
||||
if [[ ! -d $REPO/${baseNameOf pkg.src.meta.homepage} ]]; then
|
||||
ln -snf $psrc $REPO/${baseNameOf pkg.src.meta.homepage}
|
||||
fi
|
||||
''}
|
||||
'');
|
||||
in writeScript "install-repo" ''
|
||||
mkdir -p ${repo}
|
||||
${(concatMapStringsSep "\n" (installPkg repo) (expandDependencies packages))}
|
||||
'';
|
||||
|
||||
parsePackagesJSON = json:
|
||||
let
|
||||
list = importJSON json;
|
||||
in map (x:
|
||||
if epkgs ? "${x}" then epkgs.${x}
|
||||
else (trace "XXX no attribute found for use-package ${x}") null) list;
|
||||
|
||||
packagesJSON = { emacsInitFile, emacsLoadFiles, emacsArgs }: stdenv.mkDerivation {
|
||||
name = "emacs-straight-packages.json";
|
||||
buildInputs = [ epkgs.emacs ];
|
||||
buildPhase = ":";
|
||||
installPhase = ''
|
||||
runHook preInstall
|
||||
emacs -q \
|
||||
--batch \
|
||||
--directory=${epkgs.straight}/share/emacs/site-lisp \
|
||||
--load=${./setup.el} \
|
||||
${concatMapStringsSep "\n" (f: "--load=${f}") emacsLoadFiles} \
|
||||
--eval="(nix-straight-get-used-packages \"${emacsInitFile}\")" \
|
||||
${escapeShellArgs emacsArgs} > $out
|
||||
runHook postInstall
|
||||
'';
|
||||
};
|
||||
|
||||
emacsEnv = { emacsInitFile, emacsLoadFiles, emacsArgs }: { packages, straightDir }: stdenv.mkDerivation {
|
||||
name = "straight-emacs-env";
|
||||
buildPhase = ":";
|
||||
buildInputs = [ epkgs.emacs ];
|
||||
installPhase = ''
|
||||
runHook preInstall
|
||||
|
||||
mkdir -p $out
|
||||
${(install "${straightDir}/repos" packages)}
|
||||
emacs -q \
|
||||
--batch \
|
||||
--directory=${epkgs.straight}/share/emacs/site-lisp \
|
||||
--load=${./setup.el} \
|
||||
${concatMapStringsSep "\n" (f: "--load=${f}") emacsLoadFiles} \
|
||||
--eval="(nix-straight-build-packages \"${emacsInitFile}\")" ${escapeShellArgs emacsArgs}
|
||||
|
||||
runHook postInstall
|
||||
'';
|
||||
};
|
||||
in {
|
||||
inherit install parsePackagesJSON packagesJSON emacsEnv;
|
||||
}
|
39
setup.el
Normal file
39
setup.el
Normal file
@ -0,0 +1,39 @@
|
||||
;;; -*- lexical-binding: t; -*-
|
||||
(require 'json)
|
||||
(require 'straight)
|
||||
|
||||
(defun nix-straight-get-used-packages (init-file)
|
||||
(let ((nix-straight--packages nil))
|
||||
(advice-add 'straight-use-package
|
||||
:override (lambda (recipe &rest r)
|
||||
(let ((pkg (if (listp recipe)
|
||||
(car recipe)
|
||||
recipe)))
|
||||
(message "straight-use-package %s %s; pkg=%s" recipe r pkg)
|
||||
(add-to-list 'nix-straight--packages pkg))))
|
||||
(advice-add 'straight-recipes-retrieve
|
||||
:override (lambda (pkg)
|
||||
(list)))
|
||||
|
||||
(load init-file nil nil t)
|
||||
(princ (if (null nix-straight--packages)
|
||||
"[]"
|
||||
(json-encode nix-straight--packages)))
|
||||
|
||||
nix-straight--packages))
|
||||
|
||||
(defun nix-straight-build-packages (init-file)
|
||||
(setq straight-default-files-directive '("*" (:exclude "*.elc")))
|
||||
(advice-add 'straight-vc-git-clone
|
||||
:override (lambda (&rest r)))
|
||||
(advice-add 'straight-recipes-retrieve
|
||||
:override (lambda (pkg &rest r)
|
||||
(message " Crafting recipe %s" pkg)
|
||||
(if (file-exists-p (straight--repos-dir (format "%s" pkg)))
|
||||
`(,pkg :local-repo ,(format "%s" pkg))
|
||||
(message " --> Repo directory for package not exists, assuming built-in; %s" pkg)
|
||||
`(,pkg :type built-in))))
|
||||
(load init-file nil nil t))
|
||||
|
||||
(provide 'setup)
|
||||
;;; setup.el ends here
|
12
straight/default.nix
Normal file
12
straight/default.nix
Normal file
@ -0,0 +1,12 @@
|
||||
{ fetchFromGitHub, trivialBuild }:
|
||||
|
||||
trivialBuild rec {
|
||||
pname = "straight.el";
|
||||
ename = pname;
|
||||
src = fetchFromGitHub {
|
||||
owner = "raxod502";
|
||||
repo = "straight.el";
|
||||
rev = "388bf37f30f0934c8ef1b52edfd65875e945da21";
|
||||
sha256 = "1d8kg63yamkanrx6l8mi8ybj2xb8zmkhqc10q5p3xn319gs36jgp";
|
||||
};
|
||||
}
|
Reference in New Issue
Block a user