From a7563c9d08ae23abc05f8a184911ff803e52a54b Mon Sep 17 00:00:00 2001 From: Axel Forsman Date: Wed, 8 Nov 2023 10:59:36 +0100 Subject: [PATCH] Use completion-lazy-hilit Closes #17 --- README.md | 20 ++++++++++---------- hotfuzz.el | 46 +++++++--------------------------------------- test/tests.el | 16 ---------------- 3 files changed, 17 insertions(+), 65 deletions(-) diff --git a/README.md b/README.md index 619bdfe..aba81c4 100644 --- a/README.md +++ b/README.md @@ -19,20 +19,19 @@ Or, if using [Fido], add hotfuzz to the `completion-styles` list this way: (lambda () (setq-local completion-styles '(hotfuzz)))) ``` -**Note:** Highlighting of the matched characters is only applied to +**Note:** Unless the completion UI supports the +`completion-lazy-hilit` variable, as i.a. [Vertico] and [Corfu] do, +then highlighting of the matched characters will only be applied to the first `hotfuzz-max-highlighted-completions` completions, out of -performance concerns. The default value is large enough so that -generally you will need to scroll the list of completions beyond the -second page to first see non-highlighted completions. If you are -annoyed by this you can make it highlight all completions instead -using +performance concerns. The default value is large enough that generally +the list of completions will need to be scrolled beyond the second +page to reach non-highlighted completions. If you are annoyed by this +you can make it highlight all completions instead using ```elisp (setq hotfuzz-max-highlighted-completions most-positive-fixnum) ``` provided you are completing small enough lists and/or do not encounter performance problems. -This is a non-issue when using `hotfuzz-vertico-mode` since -Vertico supports lazy highlighting. ## Customization @@ -98,11 +97,12 @@ to match according to any other completion style. It is very customizable, but does no sorting and allows the individual sub-patterns to overlap (`"foo foo"` filters no additional items compared to `"foo"`). -Hotfuzz on the other hand tries to be more *clever* about sorting, +Hotfuzz on the other hand tries to be more clever about sorting, and so users who dislike that may prefer orderless. [Vertico]: https://github.com/minad/vertico +[Corfu]: https://github.com/minad/corfu +[Ido]: https://www.gnu.org/software/emacs/manual/html_node/ido/index.html [Fido]: https://www.gnu.org/software/emacs/manual/html_node/emacs/Icomplete.html [flx]: https://github.com/lewang/flx -[Ido]: https://www.gnu.org/software/emacs/manual/html_node/ido/index.html [orderless]: https://github.com/oantolin/orderless diff --git a/hotfuzz.el b/hotfuzz.el index 6628c77..bce35da 100644 --- a/hotfuzz.el +++ b/hotfuzz.el @@ -124,8 +124,6 @@ HAYSTACK has to be a match according to `hotfuzz-all-completions'." (add-face-text-property i (1+ i) 'completions-common-part nil haystack)))) haystack) -;;; Completion style implementation - ;;;###autoload (defun hotfuzz-all-completions (string table &optional pred point) "Get hotfuzz-completions of STRING in TABLE. @@ -162,13 +160,12 @@ list before passing it to `display-sort-function' or finally (setq all (mapcar #'cdr (sort all #'car-less-than-car)))))) (when all (unless (string= needle "") - ;; Without deferred highlighting (bug#47711) only highlight - ;; the top completions. - (cl-loop repeat hotfuzz-max-highlighted-completions and for x in-ref all - do (setf x (hotfuzz-highlight needle (copy-sequence x)))) - (when (zerop hotfuzz-max-highlighted-completions) - (setcar all (copy-sequence (car all)))) - (put-text-property 0 1 'completion-sorted t (car all))) + (defvar completion-lazy-hilit-fn) ; Introduced in Emacs 30 (bug#47711) + (if (bound-and-true-p completion-lazy-hilit) + (setq completion-lazy-hilit-fn (apply-partially #'hotfuzz-highlight needle)) + (cl-loop repeat hotfuzz-max-highlighted-completions and for x in-ref all + do (setf x (hotfuzz-highlight needle (copy-sequence x))))) + (setcar all (propertize (car all) 'completion-sorted t))) (if (string= prefix "") all (nconc all (length prefix)))))) (defun hotfuzz--adjust-metadata (metadata) @@ -194,37 +191,8 @@ list before passing it to `display-sort-function' or '(hotfuzz completion-flex-try-completion hotfuzz-all-completions "Fuzzy completion."))) -;;; Vertico integration - -(declare-function vertico--all-completions "ext:vertico") -(declare-function corfu--all-completions "ext:corfu") - -(defun hotfuzz--vertico--all-completions-advice (fun &rest args) - "Advice for FUN `vertico--all-completions' to defer hotfuzz highlighting." - (cl-letf* ((hl nil) - ((symbol-function #'hotfuzz-highlight) - (lambda (pattern cand) - (setq hl (apply-partially - #'mapcar - (lambda (x) (hotfuzz-highlight pattern (copy-sequence x))))) - cand)) - (hotfuzz-max-highlighted-completions 1) - (result (apply fun args))) - (when hl (setcdr result hl)) - result)) - ;;;###autoload -(define-minor-mode hotfuzz-vertico-mode - "Toggle hotfuzz compatibility code for the Vertico&Corfu completion systems. -Contrary to what the name might suggest, this mode does not enable -hotfuzz. You still have to customize e.g. `completion-styles'." - :global t - (if hotfuzz-vertico-mode - (progn - (advice-add #'vertico--all-completions :around #'hotfuzz--vertico--all-completions-advice) - (advice-add #'corfu--all-completions :around #'hotfuzz--vertico--all-completions-advice)) - (advice-remove #'vertico--all-completions #'hotfuzz--vertico--all-completions-advice) - (advice-remove #'corfu--all-completions #'hotfuzz--vertico--all-completions-advice))) +(define-obsolete-function-alias 'hotfuzz-vertico-mode #'ignore "0.1") (provide 'hotfuzz) ;;; hotfuzz.el ends here diff --git a/test/tests.el b/test/tests.el index 62fb3bf..5f5322e 100644 --- a/test/tests.el +++ b/test/tests.el @@ -96,19 +96,3 @@ nil 6) ; Point as in "/usr/s|/man" '("share/" . 5))))) - -;;; Vertico integration - -(ert-deftest vertico--all-completions-advice-test () - (cl-flet ((f (apply-partially - #'hotfuzz--vertico--all-completions-advice - (lambda (&rest args) (cons (apply #'completion-all-completions args) nil))))) - ;; If hotfuzz was not tried or produced no matches: Do not set highlighting fn - (let ((completion-styles '(basic hotfuzz))) - (should (equal (f "x" '("x") nil 1) '(("x" . 0) . nil)))) - (let ((completion-styles '(hotfuzz))) - (should (equal (f "y" '("x") nil 1) '(nil . nil))) - (cl-destructuring-bind (xs . hl) (f "x" '("x") nil 1) - ;; Highlighting should not yet have been applied - (should (equal-including-properties xs '(#("x" 0 1 (completion-sorted t))))) - (should (functionp hl))))))