about summary refs log tree commit diff
path: root/pkgs/build-support/emacs/wrapper.nix
blob: 4020a1aca33720a07c1a9d6509899d6ac0478c50 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
{ stdenv, makeWrapper, emacs }:

with stdenv.lib;

explicitRequires: # packages explicitly requested by the user

stdenv.mkDerivation {
  name = (appendToName "with-packages" emacs).name;
  nativeBuildInputs = [ emacs makeWrapper ];
  inherit emacs explicitRequires;
  phases = [ "installPhase" ];
  installPhase = ''
    requires=""
    for pkg in $explicitRequires; do
      findInputs $pkg requires propagated-user-env-packages
    done
    # requires now holds all requested packages and their transitive dependencies

    siteStart="$out/share/emacs/site-lisp/site-start.el"

    addEmacsPath() {
      local list=$1
      local path=$2
      # Add the path to the search path list, but only if it exists
      if [[ -d "$path" ]]; then
        echo "(add-to-list '$list \"$path\")" >>"$siteStart"
      fi
    }

    # Add a dependency's paths to site-start.el
    addToEmacsPaths() {
      addEmacsPath "exec-path" "$1/bin"
      addEmacsPath "load-path" "$1/share/emacs/site-lisp"
      addEmacsPath "package-directory-list" "$1/share/emacs/site-lisp/elpa"
    }

    mkdir -p $out/share/emacs/site-lisp
    # 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.
    echo "(load-file \"$emacs/share/emacs/site-lisp/site-start.el\")" >"$siteStart"
    echo "(require 'package)" >>"$siteStart"

    # Set paths for the dependencies of the requested packages. These paths are
    # searched before the profile paths, but after the explicitly-required paths.
    for pkg in $requires; do
      # The explicitly-required packages are also in the list, but we will add
      # those paths last.
      if ! ( echo "$explicitRequires" | grep "$pkg" >/dev/null ) ; then
        addToEmacsPaths $pkg
      fi
    done

    # Finally, add paths for all the explicitly-required packages. These paths
    # will be searched first.
    for pkg in $explicitRequires; do
      addToEmacsPaths $pkg
    done

    # Byte-compiling improves start-up time only slightly, but costs nothing.
    emacs --batch -f batch-byte-compile "$siteStart"

    mkdir -p $out/bin
    # Wrap emacs and friends so they find our site-start.el before the original.
    for prog in $emacs/bin/*; do # */
      makeWrapper "$prog" $out/bin/$(basename "$prog") \
        --suffix EMACSLOADPATH ":" "$out/share/emacs/site-lisp:"
    done

    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;
}