gnu: emacs: Adapt the autoloads auxiliary code to use EMACSLOADPATH.
authorMaxim Cournoyer <maxim.cournoyer@gmail.com>
Wed, 30 Oct 2019 02:07:55 +0000 (22:07 -0400)
committerMaxim Cournoyer <maxim.cournoyer@gmail.com>
Mon, 18 Nov 2019 05:34:41 +0000 (14:34 +0900)
The Elisp directories to scan for autoloads are now taken from EMACSLOADPATH
instead of from the user profile, environment profile or system profile.
Manually adding the Elisp directories to the `load-path' is no longer
necessary, as this is covered by Emacs when they are in EMACSLOADPATH.  The
caching logic is also removed, as this code is not typically run often and the
gain is marginal (loading autoloads files is cheap).

* gnu/packages/aux-files/emacs/guix-emacs.el (guix-emacs-directory)
(guix-emacs-subdirs, guix-emacs-directories): Remove procedures.
(guix-emacs-find-autoloads): Filter the directory entries by passing the
regexp to `directory-files' directly, which is ten times faster.  Remove
deduplication.
(guix-emacs-autoloads-regexp): Remove the group, which used to filter out the
file extension; it no longer works this way due to passing the regexp to the
`directory-files' procedure directly, which doesn't care about groups.
(guix-emacs-autoload-packages): Update doc.  Search package directories from
EMACSLOADPATH.  Do not populate the load-path.  Remove cache.

gnu/packages/aux-files/emacs/guix-emacs.el

dissimilarity index 71%
index 9a49e88..46ee557 100644 (file)
-;;; guix-emacs.el --- Emacs packages installed with Guix
-
-;; Copyright © 2014, 2015, 2016, 2017 Alex Kost <alezost@gmail.com>
-;; Copyright © 2017 Kyle Meyer <kyle@kyleam.com>
-
-;; This file is part of GNU Guix.
-
-;; GNU Guix is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Guix is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; This file provides auxiliary code to autoload Emacs packages
-;; installed with Guix.
-
-;;; Code:
-
-(require 'cl-lib)
-
-(defvar guix-user-profile (expand-file-name "~/.guix-profile"))
-
-(defvar guix-emacs-autoloads nil
-  "List of the last loaded Emacs autoloads.")
-
-(defvar guix-emacs-autoloads-regexp
-  (rx (group (* any) "-autoloads")
-      ".el" (zero-or-one "c") string-end)
-  "Regexp to match Emacs 'autoloads' file.")
-
-(defun guix-emacs-directory (&optional profile)
-  "Return directory with Emacs packages installed in PROFILE.
-If PROFILE is nil, use `guix-user-profile'."
-  (expand-file-name "share/emacs/site-lisp"
-                    (or profile guix-user-profile)))
-
-(defun guix-emacs-find-autoloads (directory)
-  "Return a list of Emacs 'autoloads' files in DIRECTORY.
-The files in the list do not have extensions (.el, .elc)."
-  (cl-remove-duplicates
-   (delq nil
-        (mapcar (lambda (file)
-                  (when (string-match guix-emacs-autoloads-regexp file)
-                    (match-string 1 file)))
-                (directory-files directory 'full-name nil 'no-sort)))
-   :test #'string=))
-
-(defun guix-emacs-subdirs (directory)
-  "Return list of DIRECTORY subdirectories."
-  (cl-remove-if (lambda (file)
-                  (or (string-match-p (rx "/." string-end) file)
-                      (string-match-p (rx "/.." string-end) file)
-                      (not (file-directory-p file))))
-                (directory-files directory 'full-name nil 'no-sort)))
-
-(defun guix-emacs-directories (&optional profile)
-  "Return the list of directories under PROFILE that contain Emacs packages.
-This includes both `share/emacs/site-lisp/guix.d/PACKAGE'
-sub-directories and `share/emacs/site-lisp' itself.
-
-If PROFILE is nil, use `guix-user-profile'.
-Return nil, if Emacs packages are not installed in PROFILE."
-  (let ((root-dir (guix-emacs-directory (or profile guix-user-profile))))
-    (when (file-directory-p root-dir)
-      (let* ((pkgs-dir  (expand-file-name "guix.d" root-dir))
-             (pkgs-dirs (when (file-directory-p pkgs-dir)
-                          (guix-emacs-subdirs pkgs-dir))))
-        (cons root-dir pkgs-dirs)))))
-
-;;;###autoload
-(defun guix-emacs-autoload-packages (&rest profiles)
-  "Autoload Emacs packages installed in PROFILES.
-If PROFILES are not specified, use a default user and system
-profiles.
-
-'Autoload' means add directories with Emacs packages to
-`load-path' and load 'autoloads' files matching
-`guix-emacs-autoloads-regexp'."
-  (interactive (list (if (fboundp 'guix-read-package-profile)
-                         (funcall 'guix-read-package-profile)
-                       guix-user-profile)))
-  (let* ((env      (getenv "GUIX_ENVIRONMENT"))
-         (profiles (or profiles
-                       (append (list "/run/current-system/profile"
-                                     guix-user-profile)
-                               (and env (list env))))))
-    (dolist (profile profiles)
-      (let ((dirs (guix-emacs-directories profile)))
-        (when dirs
-          (let* ((autoloads     (cl-mapcan #'guix-emacs-find-autoloads
-                                           dirs))
-                 (new-autoloads (cl-nset-difference autoloads
-                                                    guix-emacs-autoloads
-                                                    :test #'string=)))
-            (dolist (dir dirs)
-              (cl-pushnew (directory-file-name dir)
-                          load-path
-                          :test #'string=))
-            (dolist (file new-autoloads)
-              (load file 'noerror))
-            (setq guix-emacs-autoloads
-                  (append new-autoloads guix-emacs-autoloads))))))))
-
-(provide 'guix-emacs)
-
-;;; guix-emacs.el ends here
+;;; guix-emacs.el --- Emacs packages installed with Guix
+
+;; Copyright © 2014, 2015, 2016, 2017 Alex Kost <alezost@gmail.com>
+;; Copyright © 2017 Kyle Meyer <kyle@kyleam.com>
+;; Copyright © 2019 Maxim Cournoyer <maxim.cournoyer@gmail.com>
+
+;; This file is part of GNU Guix.
+
+;; GNU Guix is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Guix is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This file provides auxiliary code to autoload Emacs packages
+;; installed with Guix.
+
+;;; Code:
+(require 'seq)
+
+(defvar guix-emacs-autoloads-regexp
+  (rx (* any) "-autoloads.el" (zero-or-one "c") string-end)
+  "Regexp to match Emacs 'autoloads' file.")
+
+(defun guix-emacs-find-autoloads (directory)
+  "Return a list of Emacs 'autoloads' files in DIRECTORY.
+The files in the list do not have extensions (.el, .elc)."
+  ;; `directory-files' doesn't honor group in regexp.
+  (mapcar #'file-name-sans-extension
+          (directory-files directory 'full-name guix-emacs-autoloads-regexp)))
+
+;;;###autoload
+(defun guix-emacs-autoload-packages ()
+  "Autoload Emacs packages found in EMACSLOADPATH.
+
+'Autoload' means to load the 'autoloads' files matching
+`guix-emacs-autoloads-regexp'."
+  ;; FIXME: The autoloads generated by the emacs-build-system are not byte
+  ;; compiled.
+  (interactive)
+  (let* ((emacs-load-path (getenv "EMACSLOADPATH"))
+         (emacs-non-core-load-path-directories
+          ;; Filter out core Elisp directories, which are already autoloaded
+          ;; by Emacs.
+          (seq-filter (lambda (dir)
+                        (string-match-p "/share/emacs/site-lisp" dir))
+                      (split-string emacs-load-path ":")))
+          (autoloads (mapcan #'guix-emacs-find-autoloads
+                             emacs-non-core-load-path-directories)))
+    (mapc (lambda (f)
+            (load f 'noerror))
+          autoloads)))
+
+(provide 'guix-emacs)
+
+;;; guix-emacs.el ends here