projects/guix·blob python-team · refs

945 lines · 44.0 KiB

1;;; GNU Guix --- Functional package management for GNU
2;;; Copyright © 2013-2017, 2019, 2021-2022, 2025 Ludovic Courtès <[email protected]>
3;;; Copyright © 2013 Andreas Enge <[email protected]>
4;;; Copyright © 2014 Taylan Ulrich Bayirli/Kammer <[email protected]>
5;;; Copyright © 2014, 2015, 2016, 2017, 2018, 2019, 2020 Mark H Weaver <[email protected]>
6;;; Copyright © 2014, 2015, 2016, 2017 Alex Kost <[email protected]>
7;;; Copyright © 2016, 2018 Arun Isaac <[email protected]>
8;;; Copyright © 2016 Federico Beffa <[email protected]>
9;;; Copyright © 2016 David Thompson <[email protected]>
10;;; Copyright © 2016 Nikita <[email protected]>
11;;; Copyright © 2017 Marius Bakke <[email protected]>
12;;; Copyright © 2017, 2019, 2020, 2023, 2024 Maxim Cournoyer <[email protected]>
13;;; Copyright © 2017 Alex Vong <[email protected]>
14;;; Copyright © 2017, 2018 Ricardo Wurmus <[email protected]>
15;;; Copyright © 2017, 2023, 2024, 2025 Janneke Nieuwenhuizen <[email protected]>
16;;; Copyright © 2018, 2023 Efraim Flashner <[email protected]>
17;;; Copyright © 2018 Mathieu Othacehe <[email protected]>
18;;; Copyright © 2018, 2019, 2021 Tobias Geerinckx-Rice <[email protected]>
19;;; Copyright © 2019 Jesse John Gildersleve <[email protected]>
20;;; Copyright © 2019 Valentin Ignatev <[email protected]>
21;;; Copyright © 2019, 2021 Liliana Marie Prikler <[email protected]>
22;;; Copyright © 2019 Amin Bandali <[email protected]>
23;;; Copyright © 2020 Jack Hill <[email protected]>
24;;; Copyright © 2020 Morgan Smith <[email protected]>
25;;; Copyright © 2022 Zhu Zihao <[email protected]>
26;;; Copyright © 2023 Declan Tsien <[email protected]>
27;;; Copyright © 2023, 2024 Zheng Junjie <[email protected]>
28;;; Copyright © 2025 Nicolas Graves <[email protected]>
29;;; Copyright © 2025 Jake Forster <[email protected]>
30;;; Copyright © 2025 John Kehayias <[email protected]>
31;;; Copyright © 2026 Daniel Littlewood <[email protected]>
32;;;
33;;; This file is part of GNU Guix.
34;;;
35;;; GNU Guix is free software; you can redistribute it and/or modify it
36;;; under the terms of the GNU General Public License as published by
37;;; the Free Software Foundation; either version 3 of the License, or (at
38;;; your option) any later version.
39;;;
40;;; GNU Guix is distributed in the hope that it will be useful, but
41;;; WITHOUT ANY WARRANTY; without even the implied warranty of
42;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
43;;; GNU General Public License for more details.
44;;;
45;;; You should have received a copy of the GNU General Public License
46;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
47
48(define-module (gnu packages emacs)
49 #:use-module (guix deprecation)
50 #:use-module ((guix licenses) #:prefix license:)
51 #:use-module (guix packages)
52 #:use-module (guix gexp)
53 #:use-module (guix download)
54 #:use-module (guix git-download)
55 #:use-module (guix build-system)
56 #:use-module (guix build-system gnu)
57 #:use-module (guix build-system glib-or-gtk)
58 #:use-module (gnu packages)
59 #:use-module (gnu packages acl)
60 #:use-module (gnu packages autotools)
61 #:use-module (gnu packages base)
62 #:use-module (gnu packages bash)
63 #:use-module (gnu packages check)
64 #:use-module (gnu packages compression)
65 #:use-module (gnu packages fontutils)
66 #:use-module (gnu packages freedesktop)
67 #:use-module (gnu packages fribidi)
68 #:use-module (gnu packages gawk)
69 #:use-module (gnu packages gcc)
70 #:use-module (gnu packages gd)
71 #:use-module (gnu packages gettext)
72 #:use-module (gnu packages ghostscript)
73 #:use-module (gnu packages glib)
74 #:use-module (gnu packages gnome) ; for librsvg
75 #:use-module (gnu packages gtk)
76 #:use-module (gnu packages guile)
77 #:use-module (gnu packages image)
78 #:use-module (gnu packages imagemagick)
79 #:use-module (gnu packages language) ; m17n-db, m17n-lib
80 #:use-module (gnu packages toolkits) ; motif
81 #:use-module (gnu packages linux) ; alsa-lib, gpm
82 #:use-module (gnu packages mail) ; for mailutils
83 #:use-module (gnu packages multiprecision)
84 #:use-module (gnu packages ncurses)
85 #:use-module (gnu packages pdf)
86 #:use-module (gnu packages pkg-config)
87 #:use-module (gnu packages selinux)
88 #:use-module (gnu packages sqlite)
89 #:use-module (gnu packages texinfo)
90 #:use-module (gnu packages tls)
91 #:use-module (gnu packages tree-sitter)
92 #:use-module (gnu packages web) ; for jansson
93 #:use-module (gnu packages webkit)
94 #:use-module (gnu packages xml)
95 #:use-module (gnu packages xorg)
96 #:use-module (guix utils)
97 #:use-module (ice-9 match)
98 #:use-module (srfi srfi-1)
99 #:export (emacs->emacs-next))
100
101(define (%emacs-modules build-system)
102 (let ((which (build-system-name build-system)))
103 `((guix build ,(symbol-append which '-build-system))
104 (guix build utils)
105 (srfi srfi-1)
106 (ice-9 ftw))))
107
108(define* (emacs-ert-selector excluded-tests #:key run-nativecomp run-expensive run-unstable)
109 "Create an ERT selector that excludes tests."
110 (string-append
111 "(not (or "
112 (if run-nativecomp
113 ""
114 "(tag :nativecomp) ")
115 (if run-expensive
116 ""
117 "(tag :expensive-test) ")
118 (if run-unstable
119 ""
120 "(tag :unstable) ")
121 (string-join
122 (map
123 (lambda (test)
124 ;; This is a regex
125 (string-append "\\\"^" test "\\$\\\""))
126 (sort excluded-tests string<?)))
127 "))"))
128
129(define %emacs-selector
130 (emacs-ert-selector
131 '("benchmark-tests"
132 "esh-util-test/path/get-remote"
133 "esh-var-test/path-var/preserve-across-hosts"
134 "grep-tests--rgrep-abbreviate-properties-darwin"
135 "grep-tests--rgrep-abbreviate-properties-gnu-linux"
136 "grep-tests--rgrep-abbreviate-properties-windows-nt-dos-semantics"
137 "grep-tests--rgrep-abbreviate-properties-windows-nt-sh-semantics"
138 "info-xref-test-makeinfo"
139 "tramp-test50-remote-load-path"
140
141 ;; These two tests look for header files. We patch them to check
142 ;; "/run/current-system/profile/include" but that doesn't help us in the
143 ;; test suite
144 "man-tests-find-header-file"
145 "ffap-tests--c-path"
146
147 "diary-icalendar-test-import-bug-22092"
148 "diary-icalendar-test-import-bug-33277"
149 "diary-icalendar-test-import-with-timezone"
150
151 ;; This test fails on emacs, but succeeds on emacs-minimal and emacs-no-x.
152 "dired-test-bug25609"
153
154 ;; The following can be removed once upstream closes this bug report:
155 ;; https://debbugs.gnu.org/cgi/bugreport.cgi?bug=80421
156 "python-shell--convert-file-name-to-send-1"
157 "package-vc-tests-install-post-conditions/test-package-eight"
158 "package-vc-tests-install-post-conditions/test-package-five"
159 "package-vc-tests-install-post-conditions/test-package-four"
160 "package-vc-tests-install-post-conditions/test-package-nine"
161 "package-vc-tests-install-post-conditions/test-package-one"
162 "package-vc-tests-install-post-conditions/test-package-seven"
163 "package-vc-tests-install-post-conditions/test-package-six"
164 "package-vc-tests-install-post-conditions/test-package-three"
165 "package-vc-tests-install-post-conditions/test-package-two"
166 "package-vc-tests-pkg-spec-make-shell-command/test-package-five"
167 "package-vc-tests-pkg-spec-make-shell-command/test-package-nine"
168 "package-vc-tests-pkg-spec-make-shell-command/test-package-one"
169 "package-vc-tests-pkg-spec-make-shell-command/test-package-seven"
170 "package-vc-tests-pkg-spec-make-shell-command/test-package-two"
171 "package-vc-tests-rebuild-after-require/test-package-eight"
172 "package-vc-tests-rebuild-after-require/test-package-five"
173 "package-vc-tests-rebuild-after-require/test-package-four"
174 "package-vc-tests-rebuild-after-require/test-package-nine"
175 "package-vc-tests-rebuild-after-require/test-package-one"
176 "package-vc-tests-rebuild-after-require/test-package-seven"
177 "package-vc-tests-rebuild-after-require/test-package-six"
178 "package-vc-tests-rebuild-after-require/test-package-three"
179 "package-vc-tests-rebuild-after-require/test-package-two"
180 "package-vc-tests-require/test-package-eight"
181 "package-vc-tests-require/test-package-five"
182 "package-vc-tests-require/test-package-four"
183 "package-vc-tests-require/test-package-nine"
184 "package-vc-tests-require/test-package-one"
185 "package-vc-tests-require/test-package-seven"
186 "package-vc-tests-require/test-package-six"
187 "package-vc-tests-require/test-package-three"
188 "package-vc-tests-require/test-package-two"
189 "package-vc-tests-upgrade-after-require/test-package-eight"
190 "package-vc-tests-upgrade-after-require/test-package-five"
191 "package-vc-tests-upgrade-after-require/test-package-four"
192 "package-vc-tests-upgrade-after-require/test-package-nine"
193 "package-vc-tests-upgrade-after-require/test-package-one"
194 "package-vc-tests-upgrade-after-require/test-package-seven"
195 "package-vc-tests-upgrade-after-require/test-package-six"
196 "package-vc-tests-upgrade-after-require/test-package-three"
197 "package-vc-tests-upgrade-after-require/test-package-two")))
198
199(define %emacs-next-selector
200 (emacs-ert-selector
201 '("benchmark-tests"
202 "esh-util-test/path/get-remote"
203 "esh-var-test/path-var/preserve-across-hosts"
204 "grep-tests--rgrep-abbreviate-properties-darwin"
205 "grep-tests--rgrep-abbreviate-properties-gnu-linux"
206 "grep-tests--rgrep-abbreviate-properties-windows-nt-dos-semantics"
207 "grep-tests--rgrep-abbreviate-properties-windows-nt-sh-semantics"
208 "info-xref-test-makeinfo"
209 "uuid-v7-generator-known-rnd-and-ts" ; wrong number of arguments
210 "tramp-test50-remote-load-path"
211
212 ;; These two tests look for header files. We patch them to check
213 ;; "/run/current-system/profile/include" but that doesn't help us in the
214 ;; test suite
215 "man-tests-find-header-file"
216 "ffap-tests--c-path"
217
218 "diary-icalendar-test-import-bug-22092"
219 "diary-icalendar-test-import-bug-33277"
220 "diary-icalendar-test-import-with-timezone"
221
222 ;; This test fails on emacs, but succeeds on emacs-minimal and emacs-no-x.
223 "dired-test-bug25609"
224
225 ;; The following can be removed once upstream closes this bug report:
226 ;; https://debbugs.gnu.org/cgi/bugreport.cgi?bug=80421
227 "python-shell--convert-file-name-to-send-1"
228 "package-vc-tests-install-post-conditions/test-package-eight"
229 "package-vc-tests-install-post-conditions/test-package-five"
230 "package-vc-tests-install-post-conditions/test-package-four"
231 "package-vc-tests-install-post-conditions/test-package-nine"
232 "package-vc-tests-install-post-conditions/test-package-one"
233 "package-vc-tests-install-post-conditions/test-package-seven"
234 "package-vc-tests-install-post-conditions/test-package-six"
235 "package-vc-tests-install-post-conditions/test-package-three"
236 "package-vc-tests-install-post-conditions/test-package-two"
237 "package-vc-tests-pkg-spec-make-shell-command/test-package-five"
238 "package-vc-tests-pkg-spec-make-shell-command/test-package-nine"
239 "package-vc-tests-pkg-spec-make-shell-command/test-package-one"
240 "package-vc-tests-pkg-spec-make-shell-command/test-package-seven"
241 "package-vc-tests-pkg-spec-make-shell-command/test-package-two"
242 "package-vc-tests-rebuild-after-require/test-package-eight"
243 "package-vc-tests-rebuild-after-require/test-package-five"
244 "package-vc-tests-rebuild-after-require/test-package-four"
245 "package-vc-tests-rebuild-after-require/test-package-nine"
246 "package-vc-tests-rebuild-after-require/test-package-one"
247 "package-vc-tests-rebuild-after-require/test-package-seven"
248 "package-vc-tests-rebuild-after-require/test-package-six"
249 "package-vc-tests-rebuild-after-require/test-package-three"
250 "package-vc-tests-rebuild-after-require/test-package-two"
251 "package-vc-tests-require/test-package-eight"
252 "package-vc-tests-require/test-package-five"
253 "package-vc-tests-require/test-package-four"
254 "package-vc-tests-require/test-package-nine"
255 "package-vc-tests-require/test-package-one"
256 "package-vc-tests-require/test-package-seven"
257 "package-vc-tests-require/test-package-six"
258 "package-vc-tests-require/test-package-three"
259 "package-vc-tests-require/test-package-two"
260 "package-vc-tests-upgrade-after-require/test-package-eight"
261 "package-vc-tests-upgrade-after-require/test-package-five"
262 "package-vc-tests-upgrade-after-require/test-package-four"
263 "package-vc-tests-upgrade-after-require/test-package-nine"
264 "package-vc-tests-upgrade-after-require/test-package-one"
265 "package-vc-tests-upgrade-after-require/test-package-seven"
266 "package-vc-tests-upgrade-after-require/test-package-six"
267 "package-vc-tests-upgrade-after-require/test-package-three"
268 "package-vc-tests-upgrade-after-require/test-package-two")))
269
270(define-public emacs-minimal
271 (package
272 (name "emacs-minimal")
273 (version "31.1")
274 ;; Note: When using (replacement …), ensure that comp-native-version-dir
275 ;; stays the same across grafts.
276 ;; Run `make check-system TESTS=emacs-native-comp' to ensure that grafts
277 ;; can meaningfully be applied.
278 (source (origin
279 (method url-fetch)
280 (uri (string-append "mirror://gnu/emacs/emacs-"
281 version ".tar.xz"))
282 (sha256
283 (base32
284 "11j59ybvzbkxfsm9zmhj6ixxls2424rhcw5znlr1kj40jl6pk98x"))
285 (patches (search-patches "emacs-disable-jit-compilation.patch"
286 "emacs-fix-scheme-indent-function.patch"
287 "emacs-native-comp-driver-options.patch"
288 "emacs-native-comp-fix-filenames.patch"
289 "emacs-native-comp-pin-packages.patch"))
290 (modules '((guix build utils)))
291 (snippet
292 '(with-directory-excursion "lisp"
293 ;; Delete the bundled byte-compiled elisp files and generated
294 ;; autoloads.
295 (for-each delete-file
296 (append (find-files "." "\\.elc$")
297 (find-files "." "loaddefs\\.el$")
298 (find-files "eshell" "^esh-groups\\.el$")))))))
299 ;; Don't use doc to avoid keeping a reference via EMACS_CONFIG_OPTIONS
300 (outputs '("out" "src"))
301 (build-system gnu-build-system)
302 (arguments
303 (list
304 #:modules (%emacs-modules build-system)
305 #:configure-flags #~(list "--with-gnutls=no" "--disable-build-details"
306 ;; Prevent recursive load of ‘jka-compr’ and
307 ;; enable store reference scanning in .el files.
308 "--without-compress-install")
309 #:make-flags
310 #~(list (string-append "SELECTOR=" #$%emacs-selector)
311 (let ((release-date "2026-08-24 10:35:47"))
312 (string-append "RUN_TEMACS= "
313 #$(this-package-native-input "libfaketime")
314 "/bin/faketime -m -f '" release-date "'"
315 ;; Reduce closure size by cleaning the
316 ;; environment of the emacs dumper
317 " env -i ./temacs")))
318 #:parallel-build? #f
319 #:phases
320 #~(modify-phases %standard-phases
321 (add-after 'unpack 'enable-elogind
322 (lambda _
323 (substitute* "configure.ac"
324 (("libsystemd") "libelogind"))
325 (when (file-exists? "configure")
326 (delete-file "configure"))))
327 (add-after 'unpack 'avoid-sysinfo-call-at-build-time
328 (lambda _
329 ;; This is a useful trick for reproducibility: when we configured
330 ;; with --disable-build-details, (system-name) is nil at build
331 ;; time on the lisp side.
332 ;; Find those places with strace -k -e sysinfo.
333 (substitute* "lisp/jit-lock.el"
334 (("\\(condition-case nil \\(load-average\\) \\(error\\)\\)"
335 all)
336 (format #f "(and (system-name) ~a)" all)))))
337 (add-after 'unpack 'patch-program-file-names
338 (lambda* (#:key inputs #:allow-other-keys)
339 ;; Substitute "sh" command.
340 (substitute* '("src/callproc.c"
341 "lisp/term.el"
342 "lisp/htmlfontify.el"
343 "lisp/mail/feedmail.el"
344 "lisp/man.el"
345 "lisp/obsolete/pgg-pgp.el"
346 "lisp/obsolete/pgg-pgp5.el"
347 "lisp/org/ob-eval.el"
348 "lisp/textmodes/artist.el"
349 "lisp/progmodes/sh-script.el"
350 "lisp/textmodes/artist.el"
351 "lisp/htmlfontify.el"
352 "lisp/term.el")
353 (("\"/bin/sh\"")
354 (format #f "~s" (search-input-file inputs "bin/sh"))))
355 (substitute* '("lisp/gnus/mm-uu.el"
356 "lisp/gnus/nnrss.el"
357 "lisp/mail/blessmail.el")
358 (("\"#!/bin/sh\\\n\"")
359 (format #f "\"#!~a~%\"" (search-input-file inputs "bin/sh"))))
360 (substitute* "lisp/jka-compr.el"
361 (("\"sh\"")
362 (format #f "~s" (search-input-file inputs "bin/sh")))
363 ;; Substitute "dd" command.
364 (("\"/bin/dd\"")
365 (format #f "~s" (search-input-file inputs "bin/dd"))))
366 ;; Substitute "awk" command.
367 (substitute* '("lisp/gnus/nnspool.el"
368 "lisp/org/ob-awk.el"
369 "lisp/man.el")
370 (("\"awk\"")
371 (format #f "~s" (search-input-file inputs "bin/awk"))))
372
373 ;; Substitute "find" command.
374 (substitute* '("lisp/gnus/gnus-search.el"
375 "lisp/obsolete/nnir.el"
376 "lisp/progmodes/executable.el"
377 "lisp/progmodes/grep.el"
378 "lisp/filecache.el"
379 "lisp/ldefs-boot.el"
380 "lisp/mpc.el")
381 (("\"find\"")
382 (format #f "~s" (search-input-file inputs "bin/find"))))
383
384 ;; Substitute "sed" command.
385 (substitute* "lisp/org/ob-sed.el"
386 (("org-babel-sed-command \"sed\"")
387 (format #f "org-babel-sed-command ~s"
388 (search-input-file inputs "bin/sed"))))
389 (substitute* "lisp/man.el"
390 (("Man-sed-command \"sed\"")
391 (format #f "Man-sed-command ~s"
392 (search-input-file inputs "bin/sed"))))
393
394 (substitute* "lisp/doc-view.el"
395 (("\"(gs|dvipdf|ps2pdf|pdftotext)\"" all what)
396 (let ((replacement (false-if-exception
397 (search-input-file
398 inputs
399 (string-append "/bin/" what)))))
400 (if replacement
401 (string-append "\"" replacement "\"")
402 all))))
403
404 ;; Make sure Man and ffap looks for C header files in the right
405 ;; places.
406 (substitute* '("lisp/man.el" "lisp/ffap.el")
407 (("\"/usr/include\" \"/usr/local/include\"" line)
408 (string-join
409 (list line
410 "\"~/.guix-profile/include\""
411 "\"~/.guix-home/include\""
412 "\"/run/current-system/profile/include\"")
413 " ")))))
414 (add-after 'patch-program-file-names 'patch-tramp
415 ;; This phase is duplicated in the emacs-tramp package. Please
416 ;; ensure they stay in sync
417 (lambda* (#:key inputs #:allow-other-keys)
418 (with-directory-excursion "lisp/net"
419 ;; All but one "/bin/" directory refer to remote
420 ;; environments, which may not be Guix. Do not patch them
421 ;; blindly. However, tramp-encoding-shell has to be patched.
422 (substitute* "tramp.el"
423 (("\"/bin/sh\"")
424 (format #f "~s" (search-input-file inputs "bin/sh")))
425
426 ;; Make sure Tramp looks for binaries in the right places on
427 ;; remote Guix System machines, where 'getconf PATH' returns
428 ;; something bogus.
429 ;; Patch the line after "(defcustom tramp-remote-path".
430 (("\\(tramp-default-remote-path")
431 (format
432 #f "(tramp-default-remote-path ~s ~s ~s ~s ~s ~s ~s "
433 "/run/privileged/bin"
434 "~/.guix-profile/bin" "~/.guix-profile/sbin"
435 "~/.guix-home/bin" "~/.guix-home/sbin"
436 "/run/current-system/profile/bin"
437 "/run/current-system/profile/sbin")))
438
439 ;; match ".gvfs-fuse-daemon-real" and ".gvfsd-fuse-real"
440 ;; respectively when looking for GVFS processes.
441 (substitute* "tramp-gvfs.el"
442 (("\\(tramp-process-running-p \"(.*)\"\\)" all process)
443 (format #f "(or ~a (tramp-process-running-p ~s))"
444 all (string-append "." process "-real")))))))
445 (add-before 'configure 'fix-/bin/pwd
446 (lambda _
447 ;; Use `pwd', not `/bin/pwd'.
448 (substitute* (find-files "." "^Makefile\\.in$")
449 (("/bin/pwd")
450 "pwd"))))
451 (add-after 'unpack 'fix-tests
452 (lambda* (#:key tests? inputs #:allow-other-keys)
453 (when tests?
454 (substitute* "test/src/process-tests.el"
455 (("/bin//sh") (search-input-file inputs "bin/sh")))
456 (substitute* "test/lisp/eshell/em-script-tests.el"
457 (("/usr/bin/env") (search-input-file inputs "bin/env"))))))
458 (add-before 'configure 'install-c-source
459 (lambda _
460 (let ((dest (string-append #$output:src "/share/emacs/c-source"))
461 (lisp-dir (string-append #$output:src
462 "/share/emacs/site-lisp")))
463 (mkdir-p dest)
464 (copy-recursively "src" dest)
465 (mkdir-p lisp-dir)
466 (with-output-to-file (string-append lisp-dir
467 "/guix-emacs-c-source.el")
468 (lambda ()
469 (display
470 (string-append
471 ";; -*- lexical-binding: t; -*-\n"
472 "(setq find-function-C-source-directory \"" dest "\")\n\n"
473 "(provide 'guix-emacs-c-source)")))))))
474 (add-after 'install 'install-site-start
475 ;; Use 'guix-emacs' in "site-start.el", which is used autoload the
476 ;; Elisp packages found in EMACSLOADPATH.
477 (lambda* (#:key inputs outputs #:allow-other-keys)
478 (let* ((out (assoc-ref outputs "out"))
479 (lisp-dir (string-append out "/share/emacs/site-lisp"))
480 (emacs (string-append out "/bin/emacs")))
481
482 ;; This is duplicated from emacs-utils to prevent coupling.
483 (define* (emacs-byte-compile-directory dir)
484 (let ((expr `(progn
485 (setq byte-compile-debug t)
486 (byte-recompile-directory
487 (file-name-as-directory ,dir) 0 1))))
488 (invoke emacs "--quick" "--batch"
489 (format #f "--eval=~s" expr))))
490
491 (copy-file #$(local-file
492 (search-auxiliary-file "emacs/guix-emacs.el"))
493 (string-append lisp-dir "/guix-emacs.el"))
494 (with-output-to-file (string-append lisp-dir "/site-start.el")
495 (lambda ()
496 (display
497 (string-append
498 ";; -*- lexical-binding: t; -*-\n"
499 "(when (require 'guix-emacs nil t)\n"
500 " (guix-emacs-autoload-packages 'no-reload)\n"
501 " (advice-add 'package-load-all-descriptors"
502 " :after #'guix-emacs-load-package-descriptors))\n\n"
503 ";; The file guix-emacs-c-source.el is available from the"
504 " 'src' output.\n"
505 "(require 'guix-emacs-c-source nil t)"))))
506 ;; Remove the extraneous subdirs.el file, as it causes Emacs to
507 ;; add recursively all the the sub-directories of a profile's
508 ;; share/emacs/site-lisp union when added to EMACSLOADPATH,
509 ;; which leads to conflicts.
510 (delete-file (string-append lisp-dir "/subdirs.el"))
511 ;; Byte compile the site-start files.
512 (emacs-byte-compile-directory lisp-dir))))
513 (add-after 'install 'wrap-emacs-paths
514 (lambda* (#:key inputs outputs #:allow-other-keys)
515 (let* ((out (assoc-ref outputs "out"))
516 (lisp-dirs (find-files (string-append out "/share/emacs")
517 "^lisp$"
518 #:directories? #t)))
519 (for-each
520 (lambda (prog)
521 (wrap-program prog
522 ;; Some variants rely on uname being in PATH for Tramp.
523 ;; Tramp paths can't be hardcoded, because they need to
524 ;; be portable.
525 `("PATH" suffix
526 ,(map dirname
527 (list (search-input-file inputs "/bin/gzip")
528 ;; for coreutils
529 (search-input-file inputs "/bin/yes"))))
530 `("EMACSLOADPATH" suffix ,lisp-dirs)))
531 (find-files (string-append out "/bin")
532 ;; Matches versioned and unversioned emacs binaries.
533 ;; We don't patch emacsclient, because it takes its
534 ;; environment variables from emacs.
535 ;; Likewise, we don't need to patch helper binaries
536 ;; like etags, ctags or ebrowse.
537 "^emacs(-[0-9]+(\\.[0-9]+)*)?$")))))
538 (add-after 'wrap-emacs-paths 'undo-double-wrap
539 (lambda* (#:key outputs #:allow-other-keys)
540 ;; Directly copy emacs-X.Y to emacs, so that it is not wrapped
541 ;; twice. This also fixes a minor issue, where WMs would not be
542 ;; able to track emacs back to emacs.desktop.
543 (with-directory-excursion (assoc-ref outputs "out")
544 (copy-file
545 (car (find-files "bin" "^emacs-([0-9]+\\.)+[0-9]+$"))
546 "bin/emacs")))))))
547 (inputs (list bash-minimal coreutils findutils gawk gzip ncurses sed))
548 (native-inputs (list autoconf libfaketime pkg-config texinfo))
549 (home-page "https://www.gnu.org/software/emacs/")
550 (synopsis "The extensible text editor (minimal build for byte-compilation)")
551 (description
552 "GNU Emacs is an extensible and highly customizable text editor. It is
553based on an Emacs Lisp interpreter with extensions for text editing. Emacs
554has been extended in essentially all areas of computing, giving rise to a
555vast array of packages supporting, e.g., email, IRC and XMPP messaging,
556spreadsheets, remote server editing, and much more. Emacs includes extensive
557documentation on all aspects of the system, from basic editing to writing
558large Lisp programs. It has full Unicode support for nearly all human
559languages.")
560 (license license:gpl3+)
561 (native-search-paths
562 (list (search-path-specification
563 (variable "EMACSLOADPATH")
564 (files '("share/emacs/site-lisp")))
565 (search-path-specification
566 (variable "EMACSNATIVELOADPATH")
567 (files '("lib/emacs/native-site-lisp")))
568 (search-path-specification
569 (variable "INFOPATH")
570 (files '("share/info")))
571 ;; Most variants support tree-sitter, so let's include it here.
572 (search-path-specification
573 (variable "TREE_SITTER_GRAMMAR_PATH")
574 (files '("lib/tree-sitter")))))
575 (properties `((upstream-name . "emacs")
576 (output-synopsis "src" "C source files")))))
577
578(define-public emacs-no-x
579 (package/inherit emacs-minimal
580 (name "emacs-no-x")
581 (synopsis "The extensible, customizable, self-documenting text
582editor (console only)")
583 (arguments
584 (substitute-keyword-arguments arguments
585 ((#:configure-flags flags #~'())
586 #~(cons* "--with-modules" "--with-native-compilation=aot"
587 (delete "--with-gnutls=no" #$flags)))
588 ((#:phases phases)
589 #~(modify-phases #$phases
590 (add-after 'set-paths 'set-libgccjit-path
591 (lambda* (#:key inputs #:allow-other-keys)
592 (define (first-subdirectory/absolute directory)
593 (let ((files (scandir
594 directory
595 (lambda (file)
596 (and (not (member file '("." "..")))
597 (file-is-directory? (string-append
598 directory "/"
599 file)))))))
600 (and (not (null? files))
601 (string-append directory "/" (car files)))))
602 (let* ((libgccjit-libdir
603 (first-subdirectory/absolute ;; version
604 (first-subdirectory/absolute ;; host type
605 (search-input-directory inputs "lib/gcc")))))
606 (setenv "LIBRARY_PATH"
607 (string-append (getenv "LIBRARY_PATH")
608 ":" libgccjit-libdir)))))
609 (add-after 'unpack 'patch-compilation-driver
610 (lambda* (#:key inputs #:allow-other-keys)
611 (substitute* "lisp/emacs-lisp/comp.el"
612 (("\\(defcustom native-comp-driver-options nil")
613 (format
614 #f "(defcustom native-comp-driver-options '(~@{~s~^ ~})"
615 (string-append
616 "-B" (dirname (search-input-file inputs "/bin/nm")))
617 (string-append
618 "-B" (dirname (search-input-file inputs "/lib/libc.so")))
619 (string-append
620 "-B" (dirname (search-input-file inputs "/lib/libgccjit.so")))
621 (string-append
622 "-B" (string-append
623 (dirname
624 (search-input-file inputs "/lib/libgccjit.so"))
625 "/gcc")))))
626 (substitute* "lisp/emacs-lisp/disass.el"
627 (("\"objdump\"")
628 (string-append "\"" (search-input-file inputs "/bin/objdump") "\"")))))
629 (add-after 'build 'build-trampolines
630 (lambda* (#:key make-flags #:allow-other-keys)
631 (apply invoke "make" "trampolines" make-flags)))
632 (add-after 'validate-runpath 'validate-comp-integrity
633 (lambda* (#:key outputs #:allow-other-keys)
634 #$(cond
635 ((%current-target-system)
636 #~(display "Cannot validate native-comp on cross builds.\n"))
637 ((member (%current-system) '("armhf-linux" "i686-linux" "i586-gnu"))
638 #~(display "Integrity test is broken on 32bit systems.\n"))
639 (else
640 #~(invoke
641 (string-append (assoc-ref outputs "out") "/bin/emacs")
642 "--batch"
643 "--load"
644 #$(local-file
645 (search-auxiliary-file "emacs/comp-integrity.el"))
646 "-f" "ert-run-tests-batch-and-exit")))))))))
647 (inputs
648 (let ((inputs
649 (modify-inputs inputs
650 (prepend gnutls
651 ;; For native compilation
652 libgccjit
653 ;; Avoid Emacs's limited movemail substitute that retrieves POP3
654 ;; email only via insecure channels.
655 ;; This is not needed for (modern) IMAP.
656 mailutils
657
658 acl
659 ghostscript
660 jansson
661 lcms
662 libice
663 libsm
664 libxml2
665 m17n-lib
666 sqlite
667 tree-sitter
668 zlib))))
669 (if (target-hurd?)
670 inputs
671 (modify-inputs inputs
672 (prepend
673 alsa-lib
674 elogind
675 gpm
676 libselinux)))))))
677
678(define-public emacs
679 (package/inherit emacs-no-x
680 (name "emacs")
681 (synopsis "The extensible, customizable, self-documenting text editor")
682 (build-system glib-or-gtk-build-system)
683 (arguments
684 (substitute-keyword-arguments arguments
685 ((#:modules _) (%emacs-modules build-system))
686 ((#:configure-flags flags #~'())
687 #~(cons* "--with-cairo" #$flags))
688 ((#:phases phases)
689 #~(modify-phases #$phases
690 ;; Note: due to the changed #:modules, %standard-phases in #$phases
691 ;; refers to glib-or-gtk:%standard-phases, so we don't need to add
692 ;; them ourselves.
693 (add-after 'glib-or-gtk-wrap 'restore-emacs-pdmp
694 ;; Restore the dump file that Emacs installs somewhere in
695 ;; libexec/ to its original state.
696 (lambda* (#:key outputs target #:allow-other-keys)
697 (let* ((libexec (string-append (assoc-ref outputs "out")
698 "/libexec"))
699 ;; each of these ought to only match a single file,
700 ;; but even if not (find-files) sorts by string<,
701 ;; so the Nth element in one maps to the Nth element of
702 ;; the other
703 (pdmp (find-files libexec "\\.pdmp$"))
704 (pdmp-real (find-files libexec "\\.pdmp-real$")))
705 (for-each rename-file pdmp-real pdmp))))))))
706 (inputs (modify-inputs inputs
707 (prepend
708 cairo
709 dbus
710 gtk+
711 giflib
712 harfbuzz
713 libjpeg-turbo
714 libotf
715 libpng
716 (librsvg-for-system)
717 libtiff
718 libx11
719 libxft
720 libxpm
721 libxrender
722 libxt
723 libwebp
724 pango
725 poppler)))))
726
727(define-public emacs-pgtk
728 (package/inherit emacs
729 (name "emacs-pgtk")
730 (arguments
731 (substitute-keyword-arguments arguments
732 ((#:configure-flags flags #~'())
733 #~(cons* "--with-pgtk" #$flags))))
734 (synopsis "Emacs text editor with @code{pgtk} frames")
735 (description "This Emacs build implements graphical UI purely in terms
736of GTK.")))
737
738(define-public emacs-lucid
739 (package/inherit emacs-no-x
740 (name "emacs-lucid")
741 (synopsis
742 "The extensible, customizable, self-documenting text editor (with Lucid toolkit)")
743 (inputs (modify-inputs (package-inputs emacs)
744 (delete "gtk+")
745 (prepend libxaw)))
746 (arguments
747 (substitute-keyword-arguments
748 (package-arguments emacs-no-x)
749 ((#:configure-flags flags #~'())
750 #~(cons "--with-x-toolkit=lucid"
751 #$flags))))))
752
753(define-public emacs-motif
754 (package/inherit emacs-no-x
755 (name "emacs-motif")
756 (synopsis
757 "The extensible, customizable, self-documenting text editor (with Motif
758toolkit)")
759 ;; Using emacs' inputs as base, since it has all the graphical stuff
760 (inputs (modify-inputs (package-inputs emacs)
761 (delete "gtk+")
762 (prepend inotify-tools motif)))
763 (arguments
764 (substitute-keyword-arguments
765 (package-arguments emacs-no-x)
766 ((#:configure-flags flags #~'())
767 #~(cons "--with-x-toolkit=motif"
768 #$flags))))))
769
770(define-public emacs-no-x-toolkit
771 (package/inherit emacs-no-x
772 (name "emacs-no-x-toolkit")
773 (synopsis "The extensible, customizable, self-documenting text
774editor (without X toolkit)" )
775 ;; Using emacs' inputs as base, since it has all the graphical stuff
776 (inputs (modify-inputs (package-inputs emacs)
777 (delete "gtk+")
778 (prepend inotify-tools)))
779 (arguments
780 (substitute-keyword-arguments arguments
781 ((#:configure-flags flags #~'())
782 #~(cons "--with-x-toolkit=no" #$flags))))))
783
784(define-public emacs-wide-int
785 (package/inherit emacs
786 (name "emacs-wide-int")
787 (synopsis "The extensible, customizable, self-documenting text
788editor (with wide ints)" )
789 (arguments
790 (substitute-keyword-arguments arguments
791 ((#:configure-flags flags)
792 #~(cons "--with-wide-int" #$flags))))))
793
794(define-public emacs-next-minimal
795 (let ((commit "2b026419537955b331e5229bb23ee47b18ac3c91")
796 (revision "1"))
797 (package
798 (inherit emacs-minimal)
799 (name "emacs-next-minimal")
800 (version (git-version "32.0.50" revision commit))
801 (source
802 (origin
803 (inherit (package-source emacs-minimal))
804 (method git-fetch)
805 (uri (git-reference
806 (url "https://git.savannah.gnu.org/git/emacs.git")
807 (commit commit)))
808 (file-name (git-file-name name version))
809 (sha256
810 (base32 "1200rsvwdp86zw3mxcplp73hpfwkapkiik69hcjk835n8kim1dny"))
811 (patches
812 (search-patches "emacs-disable-jit-compilation.patch"
813 "emacs-fix-scheme-indent-function.patch"
814 "emacs-native-comp-driver-options.patch"
815 "emacs-native-comp-fix-filenames.patch"
816 "emacs-native-comp-pin-packages.patch"))))
817 (arguments
818 (substitute-keyword-arguments arguments
819 ((#:make-flags flags #~'())
820 #~(append #$flags (list (string-append "SELECTOR=" #$%emacs-next-selector)))))))))
821
822(define* (emacs->emacs-next emacs #:optional name
823 #:key (version (package-version emacs-next-minimal))
824 (source (package-source emacs-next-minimal)))
825 (package
826 (inherit emacs)
827 (name (or name
828 (and (string-prefix? "emacs" (package-name emacs))
829 (string-append "emacs-next"
830 (string-drop (package-name emacs)
831 (string-length "emacs"))))))
832 (version version)
833 (source source)
834 (arguments
835 (substitute-keyword-arguments arguments
836 ((#:make-flags flags #~'())
837 #~(append #$flags (list (string-append "SELECTOR=" #$%emacs-next-selector))))))))
838
839(define-public emacs-next (emacs->emacs-next emacs))
840(define-public emacs-next-pgtk (emacs->emacs-next emacs-pgtk))
841(define-public emacs-next-lucid (emacs->emacs-next emacs-lucid))
842
843(define-public guile-emacs
844 (let ((upstream-version "31.0.50")
845 (commit "f2d0459d6a4cda8b7c38b6fb12a55f1330ba50fa")
846 (revision "2"))
847 (package
848 (inherit emacs)
849 (name "guile-emacs")
850 (version (git-version upstream-version revision commit))
851 (source (origin
852 (method git-fetch)
853 (uri (git-reference
854 (url "https://codeberg.org/lyrra/guilemacs")
855 (commit commit)))
856 (file-name (git-file-name name version))
857 (sha256
858 (base32
859 "0ry0dn9xrndpz54hs92dnnsw4xa4qn4lz898ldlh2rs47ah1f4wl"))))
860 (native-inputs
861 (modify-inputs native-inputs
862 (prepend autoconf automake guile-for-guile-emacs)))
863 (inputs
864 (modify-inputs inputs
865 (prepend imagemagick)))
866 (home-page "https://guile-emacs.org")
867 (synopsis "Emacs text editor powered by Guile('s elisp implementation)")
868 (description
869 "Guile-Emacs brings Emacs and Guile together by providing a new Elisp
870implementation based on Guile's compiler technology, serving as the basis for
871a more expressive and extensible version of Elisp.
872
873Started in 2014 as a GSOC project, Guile-Emacs was resurrected in 2024.")
874 (arguments
875 (substitute-keyword-arguments `(#:strip-binaries? #f
876 ,@(package-arguments emacs))
877 ((#:configure-flags flags ''())
878 #~`(#$(string-append "CFLAGS=-Og -ggdb3"
879 " -Wno-error=implicit-function-declaration"
880 " -Wno-error=implicit-int"
881 " -Wno-error=incompatible-pointer-types"
882 " -Wno-error=int-conversion"
883 " -Wno-error=shift-count-negative")
884 "--with-native-compilation=no"
885 "--without-modules"
886 "--without-threads"
887 "--with-jpeg=no"
888 "--without-cairo"
889 "--without-tree-sitter"
890 "--with-imagemagick"
891 ,@(fold delete #$flags
892 '("CFLAGS=-g -O2 -Wno-error=incompatible-pointer-types"
893 "--with-cairo"
894 "--with-modules"
895 "--with-native-compilation=aot"))))
896 ((#:make-flags flags #~'())
897 #~(list "V=1"))
898 ((#:phases phases)
899 #~(modify-phases #$phases
900 (add-after 'unpack 'autogen
901 (lambda _
902 (invoke "sh" "autogen.sh")))
903 (delete 'patch-compilation-driver)
904 (delete 'set-libgccjit-path)
905 (delete 'validate-comp-integrity)
906 (delete 'restore-emacs-pdmp)
907 (delete 'build-trampolines)
908 (delete 'install-site-start)
909 (replace 'wrap-emacs-paths
910 ;; Restrict EMACSLOADPATH to builtin packages.
911 (lambda _
912 (let ((lisp-dirs (list (string-append
913 #$output "/share/emacs/"
914 #$upstream-version "/lisp")))
915 (inputs '#$(map (match-lambda
916 ((name directory)
917 #~(#$name . #$directory)))
918 (package-inputs this-package))))
919 (for-each
920 (lambda (prog)
921 (wrap-program prog
922 ;; Some variants rely on uname being in PATH for Tramp.
923 ;; Tramp paths can't be hardcoded, because they need to
924 ;; be portable.
925 `("PATH" suffix
926 ,(map dirname
927 (list (search-input-file inputs "/bin/gzip")
928 ;; for coreutils
929 (search-input-file inputs "/bin/yes"))))
930 ;; We use "=" because loading non-builtin packages is
931 ;; currently not supported and prevents guile-emacs
932 ;; from running.
933 `("EMACSLOADPATH" = ,lisp-dirs)))
934 (find-files
935 (string-append #$output "/bin")
936 ;; Matches versioned and unversioned emacs binaries.
937 ;; We don't patch emacsclient, because it takes its
938 ;; environment variables from emacs.
939 ;; Likewise, we don't need to patch helper binaries
940 ;; like etags, ctags or ebrowse.
941 "^emacs(-[0-9]+(\\.[0-9]+)*)?$")))))
942 (add-after 'configure 'touch-lisp/finder-inf.el
943 (lambda _
944 (call-with-output-file "lisp/finder-inf.el"
945 (lambda (port) (display port))))))))))))