emacs: Add basic tree-sitter support (#219559)

This commit adds basic support for tree-sitter in the emacs build,
such that (if the user opts into tree-sitter support), tree-sitter
will be enabled and binary library files for tree-sitter can be
included in the `lib` directory of packages passed to
`emacsWithPackages`. The libraries will be aggregated and included in
treesit-extra-load-path.

The previous pattern for this in the community was to add tree-sitter
libaries by patching emacs's `RUNPATH` with `patchelf` in a post-fixup
phase. However, this has the substantial drawback that two different
emacs installations with different lists of available tree-sitter
libraries must be entirely separate builds. By supplying the
tree-sitter libraries in the wrapping layer of `emacsWithpackages`, it
becomes possible to share a single, more-cacheable "core emacs".

This support defaults to "on" only in emacs 29 and up, since previous
versions do not support tree-sitter out of the box.
This commit is contained in:
Chris Hodapp 2023-03-14 20:51:29 -07:00 committed by GitHub
parent 28b44d37a2
commit 1a8edfe192
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 17 additions and 1 deletions

View file

@ -45,6 +45,7 @@
else if withAthena then "athena"
else "lucid")
, withSystemd ? lib.meta.availableOn stdenv.hostPlatform systemd, systemd
, withTreeSitter ? lib.versionAtLeast version "29", tree-sitter ? null
}:
assert (libXft != null) -> libpng != null; # probably a bug
@ -58,6 +59,7 @@ assert withGTK2 -> !withGTK3 && gtk2-x11 != null && !withPgtk;
assert withGTK3 -> !withGTK2 && ((gtk3-x11 != null) || withPgtk);
assert withPgtk -> withGTK3 && !withX && gtk3 != null;
assert withXwidgets -> withGTK3 && webkitgtk != null;
assert withTreeSitter -> tree-sitter != null;
(if withMacport then llvmPackages_6.stdenv else stdenv).mkDerivation (finalAttrs: (lib.optionalAttrs nativeComp {
@ -164,7 +166,8 @@ assert withXwidgets -> withGTK3 && webkitgtk != null;
ImageCaptureCore GSS ImageIO
]
++ lib.optionals stdenv.isDarwin [ sigtool ]
++ lib.optionals nativeComp [ libgccjit ];
++ lib.optionals nativeComp [ libgccjit ]
++ lib.optionals withTreeSitter [ tree-sitter ];
hardeningDisable = [ "format" ];
@ -193,6 +196,7 @@ assert withXwidgets -> withGTK3 && webkitgtk != null;
++ lib.optional withImageMagick "--with-imagemagick"
++ lib.optional withXinput2 "--with-xinput2"
++ lib.optional (!withToolkitScrollBars) "--without-toolkit-scroll-bars"
++ lib.optional withTreeSitter "--with-tree-sitter"
;
installTargets = [ "tags" "install" ];
@ -241,6 +245,7 @@ assert withXwidgets -> withGTK3 && webkitgtk != null;
passthru = {
inherit nativeComp;
treeSitter = withTreeSitter;
pkgs = recurseIntoAttrs (emacsPackagesFor finalAttrs.finalPackage);
tests = { inherit (nixosTests) emacs-daemon; };
};

View file

@ -42,6 +42,8 @@ let
nativeComp = emacs.nativeComp or false;
treeSitter = emacs.treeSitter or false;
in
packagesFun: # packages explicitly requested by the user
@ -109,6 +111,9 @@ runCommand
${optionalString nativeComp ''
mkdir -p $out/share/emacs/native-lisp
''}
${optionalString treeSitter ''
mkdir -p $out/lib
''}
local requires
for pkg in $explicitRequires; do
@ -133,6 +138,9 @@ runCommand
${optionalString nativeComp ''
linkPath "$1" "share/emacs/native-lisp" "share/emacs/native-lisp"
''}
${optionalString treeSitter ''
linkPath "$1" "lib" "lib"
''}
}
# Iterate over the array of inputs (avoiding nix's own interpolation)
@ -164,6 +172,9 @@ runCommand
${optionalString nativeComp ''
(add-to-list 'native-comp-eln-load-path "$out/share/emacs/native-lisp/")
''}
${optionalString treeSitter ''
(add-to-list 'treesit-extra-load-path "$out/lib/")
''}
EOF
# Generate a subdirs.el that statically adds all subdirectories to load-path.