diff options
author | Alyssa Ross <hi@alyssa.is> | 2019-01-07 02:18:36 +0000 |
---|---|---|
committer | Alyssa Ross <hi@alyssa.is> | 2019-01-07 02:18:47 +0000 |
commit | 36f56d99fa0a0765c9f1de4a5f17a9b05830c3f2 (patch) | |
tree | b3faaf573407b32aa645237a4d16b82778a39a92 /nixpkgs/pkgs/build-support/emacs/wrapper.nix | |
parent | 4e31070265257dc67d120c27e0f75c2344fdfa9a (diff) | |
parent | abf060725d7614bd3b9f96764262dfbc2f9c2199 (diff) | |
download | nixlib-36f56d99fa0a0765c9f1de4a5f17a9b05830c3f2.tar nixlib-36f56d99fa0a0765c9f1de4a5f17a9b05830c3f2.tar.gz nixlib-36f56d99fa0a0765c9f1de4a5f17a9b05830c3f2.tar.bz2 nixlib-36f56d99fa0a0765c9f1de4a5f17a9b05830c3f2.tar.lz nixlib-36f56d99fa0a0765c9f1de4a5f17a9b05830c3f2.tar.xz nixlib-36f56d99fa0a0765c9f1de4a5f17a9b05830c3f2.tar.zst nixlib-36f56d99fa0a0765c9f1de4a5f17a9b05830c3f2.zip |
Add 'nixpkgs/' from commit 'abf060725d7614bd3b9f96764262dfbc2f9c2199'
git-subtree-dir: nixpkgs git-subtree-mainline: 4e31070265257dc67d120c27e0f75c2344fdfa9a git-subtree-split: abf060725d7614bd3b9f96764262dfbc2f9c2199
Diffstat (limited to 'nixpkgs/pkgs/build-support/emacs/wrapper.nix')
-rw-r--r-- | nixpkgs/pkgs/build-support/emacs/wrapper.nix | 173 |
1 files changed, 173 insertions, 0 deletions
diff --git a/nixpkgs/pkgs/build-support/emacs/wrapper.nix b/nixpkgs/pkgs/build-support/emacs/wrapper.nix new file mode 100644 index 000000000000..e161daffbd37 --- /dev/null +++ b/nixpkgs/pkgs/build-support/emacs/wrapper.nix @@ -0,0 +1,173 @@ +/* + +# Usage + +`emacsWithPackages` takes a single argument: a function from a package +set to a list of packages (the packages that will be available in +Emacs). For example, +``` +emacsWithPackages (epkgs: [ epkgs.evil epkgs.magit ]) +``` +All the packages in the list should come from the provided package +set. It is possible to add any package to the list, but the provided +set is guaranteed to have consistent dependencies and be built with +the correct version of Emacs. + +# Overriding + +`emacsWithPackages` inherits the package set which contains it, so the +correct way to override the provided package set is to override the +set which contains `emacsWithPackages`. For example, to override +`emacsPackagesNg.emacsWithPackages`, +``` +let customEmacsPackages = + emacsPackagesNg.overrideScope' (self: super: { + # use a custom version of emacs + emacs = ...; + # use the unstable MELPA version of magit + magit = self.melpaPackages.magit; + }); +in customEmacsPackages.emacsWithPackages (epkgs: [ epkgs.evil epkgs.magit ]) +``` + +*/ + +{ lib, lndir, makeWrapper, runCommand, stdenv }: self: + +with lib; let inherit (self) emacs; in + +packagesFun: # packages explicitly requested by the user + +let + explicitRequires = + if lib.isFunction packagesFun + then packagesFun self + else packagesFun; +in + +stdenv.mkDerivation { + name = (appendToName "with-packages" emacs).name; + nativeBuildInputs = [ emacs lndir makeWrapper ]; + inherit emacs explicitRequires; + + # Store all paths we want to add to emacs here, so that we only need to add + # one path to the load lists + deps = runCommand "emacs-packages-deps" + { inherit explicitRequires lndir emacs; } + '' + findInputsOld() { + local pkg="$1"; shift + local var="$1"; shift + local propagatedBuildInputsFiles=("$@") + + # TODO(@Ericson2314): Restore using associative array once Darwin + # nix-shell doesn't use impure bash. This should replace the O(n) + # case with an O(1) hash map lookup, assuming bash is implemented + # well :D. + local varSlice="$var[*]" + # ''${..-} to hack around old bash empty array problem + case "''${!varSlice-}" in + *" $pkg "*) return 0 ;; + esac + unset -v varSlice + + eval "$var"'+=("$pkg")' + + if ! [ -e "$pkg" ]; then + echo "build input $pkg does not exist" >&2 + exit 1 + fi + + local file + for file in "''${propagatedBuildInputsFiles[@]}"; do + file="$pkg/nix-support/$file" + [[ -f "$file" ]] || continue + + local pkgNext + for pkgNext in $(< "$file"); do + findInputsOld "$pkgNext" "$var" "''${propagatedBuildInputsFiles[@]}" + done + done + } + mkdir -p $out/bin + mkdir -p $out/share/emacs/site-lisp + + local requires + for pkg in $explicitRequires; do + findInputsOld $pkg requires propagated-user-env-packages + done + # requires now holds all requested packages and their transitive dependencies + + linkPath() { + local pkg=$1 + local origin_path=$2 + local dest_path=$3 + + # Add the path to the search path list, but only if it exists + if [[ -d "$pkg/$origin_path" ]]; then + $lndir/bin/lndir -silent "$pkg/$origin_path" "$out/$dest_path" + fi + } + + linkEmacsPackage() { + linkPath "$1" "bin" "bin" + linkPath "$1" "share/emacs/site-lisp" "share/emacs/site-lisp" + } + + # Iterate over the array of inputs (avoiding nix's own interpolation) + for pkg in "''${requires[@]}"; do + linkEmacsPackage $pkg + done + + siteStart="$out/share/emacs/site-lisp/site-start.el" + siteStartByteCompiled="$siteStart"c + + # A dependency may have brought the original siteStart, delete it and + # create our own + # Begin the new site-start.el by loading the original, which sets some + # NixOS-specific paths. Paths are searched in the reverse of the order + # they are specified in, so user and system profile paths are searched last. + rm -f $siteStart $siteStartByteCompiled + cat >"$siteStart" <<EOF +(load-file "$emacs/share/emacs/site-lisp/site-start.el") +(add-to-list 'load-path "$out/share/emacs/site-lisp") +(add-to-list 'exec-path "$out/bin") +EOF + + # Byte-compiling improves start-up time only slightly, but costs nothing. + $emacs/bin/emacs --batch -f batch-byte-compile "$siteStart" + ''; + + phases = [ "installPhase" ]; + installPhase = '' + mkdir -p "$out/bin" + + # Wrap emacs and friends so they find our site-start.el before the original. + for prog in $emacs/bin/*; do # */ + local progname=$(basename "$prog") + rm -f "$out/bin/$progname" + makeWrapper "$prog" "$out/bin/$progname" \ + --suffix EMACSLOADPATH ":" "$deps/share/emacs/site-lisp:" + done + + # Wrap MacOS app + # this has to pick up resources and metadata + # to recognize it as an "app" + if [ -d "$emacs/Applications/Emacs.app" ]; then + mkdir -p $out/Applications/Emacs.app/Contents/MacOS + cp -r $emacs/Applications/Emacs.app/Contents/Info.plist \ + $emacs/Applications/Emacs.app/Contents/PkgInfo \ + $emacs/Applications/Emacs.app/Contents/Resources \ + $out/Applications/Emacs.app/Contents + makeWrapper $emacs/Applications/Emacs.app/Contents/MacOS/Emacs $out/Applications/Emacs.app/Contents/MacOS/Emacs \ + --suffix EMACSLOADPATH ":" "$deps/share/emacs/site-lisp:" + fi + + mkdir -p $out/share + # Link icons and desktop files into place + for dir in applications icons info man; do + ln -s $emacs/share/$dir $out/share/$dir + done + ''; + inherit (emacs) meta; +} |