mirror of
https://github.com/NixOS/nixpkgs.git
synced 2024-12-25 03:17:13 +00:00
84d4f874c2
After final improvements to the official formatter implementation, this commit now performs the first treewide reformat of Nix files using it. This is part of the implementation of RFC 166. Only "inactive" files are reformatted, meaning only files that aren't being touched by any PR with activity in the past 2 months. This is to avoid conflicts for PRs that might soon be merged. Later we can do a full treewide reformat to get the rest, which should not cause as many conflicts. A CI check has already been running for some time to ensure that new and already-formatted files are formatted, so the files being reformatted here should also stay formatted. This commit was automatically created and can be verified using nix-builda08b3a4d19
.tar.gz \ --argstr baseRev78e9caf153
result/bin/apply-formatting $NIXPKGS_PATH
247 lines
9 KiB
Nix
247 lines
9 KiB
Nix
/*
|
|
# Usage
|
|
|
|
`emacs.pkgs.withPackages` 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,
|
|
```
|
|
emacs.pkgs.withPackages (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
|
|
|
|
`emacs.pkgs.withPackages` inherits the package set which contains it, so the
|
|
correct way to override the provided package set is to override the
|
|
set which contains `emacs.pkgs.withPackages`. For example, to override
|
|
`emacs.pkgs.emacs.pkgs.withPackages`,
|
|
```
|
|
let customEmacsPackages =
|
|
emacs.pkgs.overrideScope (self: super: {
|
|
# use a custom version of emacs
|
|
emacs = ...;
|
|
# use the unstable MELPA version of magit
|
|
magit = self.melpaPackages.magit;
|
|
});
|
|
in customEmacsPackages.withPackages (epkgs: [ epkgs.evil epkgs.magit ])
|
|
```
|
|
*/
|
|
|
|
{
|
|
lib,
|
|
lndir,
|
|
makeBinaryWrapper,
|
|
runCommand,
|
|
}:
|
|
self:
|
|
let
|
|
inherit (self) emacs;
|
|
withNativeCompilation = emacs.withNativeCompilation or false;
|
|
withTreeSitter = emacs.withTreeSitter or false;
|
|
in
|
|
packagesFun: # packages explicitly requested by the user
|
|
let
|
|
explicitRequires = if lib.isFunction packagesFun then packagesFun self else packagesFun;
|
|
in
|
|
runCommand (lib.appendToName "with-packages" emacs).name
|
|
{
|
|
inherit emacs explicitRequires;
|
|
nativeBuildInputs = [
|
|
emacs
|
|
lndir
|
|
makeBinaryWrapper
|
|
];
|
|
|
|
preferLocalBuild = true;
|
|
allowSubstitutes = false;
|
|
|
|
# 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;
|
|
}
|
|
// lib.optionalAttrs withNativeCompilation {
|
|
inherit (emacs) LIBRARY_PATH;
|
|
}
|
|
)
|
|
''
|
|
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
|
|
${lib.optionalString withNativeCompilation ''
|
|
mkdir -p $out/share/emacs/native-lisp
|
|
''}
|
|
${lib.optionalString withTreeSitter ''
|
|
mkdir -p $out/lib
|
|
''}
|
|
|
|
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"
|
|
${lib.optionalString withNativeCompilation ''
|
|
linkPath "$1" "share/emacs/native-lisp" "share/emacs/native-lisp"
|
|
''}
|
|
${lib.optionalString withTreeSitter ''
|
|
linkPath "$1" "lib" "lib"
|
|
''}
|
|
}
|
|
|
|
# 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
|
|
subdirs="$out/share/emacs/site-lisp/subdirs.el"
|
|
subdirsByteCompiled="$subdirs"c
|
|
|
|
# A dependency may have brought the original siteStart or subdirs, 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.
|
|
#
|
|
# NOTE: Avoid displaying messages early at startup by binding
|
|
# inhibit-message to t. This would prevent the Emacs GUI from showing up
|
|
# prematurely. The messages would still be logged to the *Messages*
|
|
# buffer.
|
|
rm -f $siteStart $siteStartByteCompiled $subdirs $subdirsByteCompiled
|
|
cat >"$siteStart" <<EOF
|
|
(let ((inhibit-message t))
|
|
(load "$emacs/share/emacs/site-lisp/site-start"))
|
|
;; "$out/share/emacs/site-lisp" is added to load-path in wrapper.sh
|
|
;; "$out/share/emacs/native-lisp" is added to native-comp-eln-load-path in wrapper.sh
|
|
(add-to-list 'exec-path "$out/bin")
|
|
${lib.optionalString withTreeSitter ''
|
|
(add-to-list 'treesit-extra-load-path "$out/lib/")
|
|
''}
|
|
EOF
|
|
|
|
# Generate a subdirs.el that statically adds all subdirectories to load-path.
|
|
$emacs/bin/emacs \
|
|
--batch \
|
|
--load ${./mk-wrapper-subdirs.el} \
|
|
--eval "(prin1 (macroexpand-1 '(mk-subdirs-expr \"$out/share/emacs/site-lisp\")))" \
|
|
> "$subdirs"
|
|
|
|
# Byte-compiling improves start-up time only slightly, but costs nothing.
|
|
$emacs/bin/emacs --batch -f batch-byte-compile "$siteStart" "$subdirs"
|
|
|
|
${lib.optionalString withNativeCompilation ''
|
|
$emacs/bin/emacs --batch \
|
|
--eval "(add-to-list 'native-comp-eln-load-path \"$out/share/emacs/native-lisp/\")" \
|
|
-f batch-native-compile "$siteStart" "$subdirs"
|
|
''}
|
|
'';
|
|
|
|
inherit (emacs) meta;
|
|
}
|
|
''
|
|
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"
|
|
|
|
substitute ${./wrapper.sh} $out/bin/$progname \
|
|
--subst-var-by bash ${emacs.stdenv.shell} \
|
|
--subst-var-by wrapperSiteLisp "$deps/share/emacs/site-lisp" \
|
|
--subst-var-by wrapperSiteLispNative "$deps/share/emacs/native-lisp" \
|
|
--subst-var-by wrapperInvocationDirectory "$out/bin/" \
|
|
--subst-var-by wrapperInvocationName "$progname" \
|
|
--subst-var prog
|
|
chmod +x $out/bin/$progname
|
|
# Create a “NOP” binary wrapper for the pure sake of it becoming a
|
|
# non-shebang, actual binary. See the makeBinaryWrapper docs for rationale
|
|
# (summary: it allows you to use emacs as a shebang itself on Darwin,
|
|
# e.g. #!$ {emacs}/bin/emacs --script)
|
|
wrapProgramBinary $out/bin/$progname
|
|
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
|
|
|
|
|
|
substitute ${./wrapper.sh} $out/Applications/Emacs.app/Contents/MacOS/Emacs \
|
|
--subst-var-by bash ${emacs.stdenv.shell} \
|
|
--subst-var-by wrapperSiteLisp "$deps/share/emacs/site-lisp" \
|
|
--subst-var-by wrapperSiteLispNative "$deps/share/emacs/native-lisp" \
|
|
--subst-var-by wrapperInvocationDirectory "$out/Applications/Emacs.app/Contents/MacOS/" \
|
|
--subst-var-by wrapperInvocationName "Emacs" \
|
|
--subst-var-by prog "$emacs/Applications/Emacs.app/Contents/MacOS/Emacs"
|
|
chmod +x $out/Applications/Emacs.app/Contents/MacOS/Emacs
|
|
wrapProgramBinary $out/Applications/Emacs.app/Contents/MacOS/Emacs
|
|
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
|
|
''
|