From 1ea7f99778d78adb4224c2a96335129987f7ba48 Mon Sep 17 00:00:00 2001 From: Gerard Vermeulen Date: Thu, 22 Dec 2022 14:12:35 +0100 Subject: [PATCH] Handle two Hyperbole quirks better --- README.org | 64 +++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 54 insertions(+), 10 deletions(-) diff --git a/README.org b/README.org index 0dbfa6e..fb8bc82 100644 --- a/README.org +++ b/README.org @@ -5027,22 +5027,66 @@ Listing [[lst:configure-browse-url]] configures =browse-url=. :CUSTOM_ID: sec:ensure-hyperbole-installation :END: +Listing [[lst:ensure-hyperbole-installation][ensure Hyperbole installation]] works around two [[https://www.gnu.org/software/hyperbole/][GNU Hyperbole]] quirks: +1. The [[https://elpa.gnu.org/elpa/hyperbole.html][GNU ELPA Hyperbole]] and [[https://elpa.gnu.org/devel/hyperbole.html][GNU ELPA Hyperbole developer]] packages ship their + own =hyperbole-autoloads= and =kotl-autoloads= files which are incompatible + with Emacs Lisp packages from "package archives". Consequently, Emacs can + neither autoload nor load the =hyperbole-autoloads= and =kotl-autoloads= + files. Therefore, the predicate loading the =kotl-autoloads= file in the + first =unless= form of listing [[lst:ensure-hyperbole-installation][ensure Hyperbole installation]] will fail and + the body of this form will overwrite the =hyperbole-autoloads= file to fix + =load-path= *and* load the =hyperbole-autoloads= and =kotl-autoloads= files. + A next time, Emacs will be able to autoload the new =hyperbole-autoloads= + file but not the =kotl-autoloads= file. However, Emacs will now be able to + load the =kotl-autoloads= file which the predicate in the first =unless= form + of listing [[lst:ensure-hyperbole-installation][ensure Hyperbole installation]] does. +2. [[https://www.gnu.org/software/hyperbole/][GNU Hyperbole]] and [[info:vertico#Top][Vertico (info)]] do not play well together, since the + =vertico-mode= preselection of the first candidate out of the full candidate + completion list interferes with =hyperbole-mode= expectations where it must + handle a full candidate list. Therefore, the function call + src_emacs-lisp{(either-hyperbole-or-vertico-mode)} handles this conflict by + toggling between =hyperbole-mode= and =vertico-mode=. + #+caption[Ensure Hyperbole installation]: -#+caption: Ensure Hyperbole installation. +#+caption: Ensure Hyperbole installation and address two Hyperbole quirks. #+name: lst:ensure-hyperbole-installation #+begin_src emacs-lisp (when (ensure-package-installation 'hyperbole) - ;; Hyperbole's autoloads files break package.el's autoloading. - (dolist (name '("hyperbole-autoloads" "kotl-autoloads")) - (when-let (result (directory-files-recursively - (expand-file-name package-user-dir) - (concat name ".el\\'"))) - (cl-pushnew (file-name-directory (car result)) - load-path :test #'string=) - (load name))) + (unless (load "kotl-autoloads.el" 'noerror nil nil 'must-suffix) + ;; See `package-generate-autoloads' for `loaddefs-generate' usage. + (unless (bound-and-true-p package-archive-contents) + (package-read-all-archive-contents)) + (let* ((pkg-desc (cadr (assq 'hyperbole package-archive-contents))) + (pkg-dir (expand-file-name + (package-desc-full-name pkg-desc) package-user-dir)) + (hpbl-alf (expand-file-name "hyperbole-autoloads.el" pkg-dir)) + (kotl-alf (expand-file-name + (file-name-concat "kotl" "kotl-autoloads.el") pkg-dir)) + (extra-data + (concat + (prin1-to-string + '(add-to-list + 'load-path + (or (and load-file-name (file-name-directory load-file-name)) + (car load-path)))) + "\n" + (prin1-to-string + '(add-to-list + 'load-path + (expand-file-name + "kotl" + (or (and load-file-name (file-name-directory load-file-name)) + (car load-path))))))) + (autoload-timestamps nil) + (version-control 'never)) + (loaddefs-generate pkg-dir hpbl-alf nil extra-data nil 'generate-full) + (dolist (alf (list hpbl-alf kotl-alf)) + (let ((buf (find-buffer-visiting hpbl-alf))) + (when buf (kill-buffer buf))) + (load alf nil nil nil 'must-suffix)))) (defun either-hyperbole-or-vertico-mode () - "Toggle between either hyperbole-mode or vertical mode." + "Toggle between either `hyperbole-mode' or `vertico-mode'." (interactive) (when (and (boundp hyperbole-mode) (boundp vertico-mode)) (if hyperbole-mode