branch: externals/hotfuzz
commit 5ccab77f7bfb1d4246aa01639e151ec9509c64bb
Author: Axel Forsman <[email protected]>
Commit: GitHub <[email protected]>

    Add compatibility mode for Vertico (#3)
---
 hotfuzz.el    | 73 +++++++++++++++++++++++++++++++++++++++++------------------
 test/tests.el | 16 +++++++++++++
 2 files changed, 67 insertions(+), 22 deletions(-)

diff --git a/hotfuzz.el b/hotfuzz.el
index 7445128958..720c2809a2 100644
--- a/hotfuzz.el
+++ b/hotfuzz.el
@@ -236,28 +236,57 @@ list before passing it to `display-sort-function' or
   "Previous values of the Selectrum sort/filter/highlight API endpoints.")
 
 ;;;###autoload
-(progn
-  (define-minor-mode hotfuzz-selectrum-mode
-    "Minor mode that enables hotfuzz in Selectrum menus."
-    :group 'hotfuzz
-    :global t
-    (if hotfuzz-selectrum-mode
-        (setq hotfuzz--prev-selectrum-functions
-              `(,(when (boundp 'selectrum-refine-candidates-function)
-                   selectrum-refine-candidates-function)
-                . ,(when (boundp 'selectrum-highlight-candidates-function)
-                     selectrum-highlight-candidates-function))
-              selectrum-refine-candidates-function #'hotfuzz-filter
-              selectrum-highlight-candidates-function #'hotfuzz--highlight-all)
-      (cl-flet ((restore
-                 (sym old our &aux (standard (car-safe (get sym 
'standard-value))))
-                 (cond ((not (eq (symbol-value sym) our)))
-                       (old (set sym old))
-                       (standard (set sym (eval standard t)))
-                       (t (makunbound sym)))))
-        (cl-destructuring-bind (old-rcf . old-hcf) 
hotfuzz--prev-selectrum-functions
-          (restore 'selectrum-refine-candidates-function old-rcf 
#'hotfuzz-filter)
-          (restore 'selectrum-highlight-candidates-function old-hcf 
#'hotfuzz--highlight-all))))))
+(define-minor-mode hotfuzz-selectrum-mode
+  "Minor mode that enables hotfuzz in Selectrum menus."
+  :group 'hotfuzz
+  :global t
+  (if hotfuzz-selectrum-mode
+      (setq hotfuzz--prev-selectrum-functions
+            `(,(when (boundp 'selectrum-refine-candidates-function)
+                 selectrum-refine-candidates-function)
+              . ,(when (boundp 'selectrum-highlight-candidates-function)
+                   selectrum-highlight-candidates-function))
+            selectrum-refine-candidates-function #'hotfuzz-filter
+            selectrum-highlight-candidates-function #'hotfuzz--highlight-all)
+    (cl-flet ((restore
+               (sym old our &aux (standard (car-safe (get sym 
'standard-value))))
+               (cond ((not (eq (symbol-value sym) our)))
+                     (old (set sym old))
+                     (standard (set sym (eval standard t)))
+                     (t (makunbound sym)))))
+      (cl-destructuring-bind (old-rcf . old-hcf) 
hotfuzz--prev-selectrum-functions
+        (restore 'selectrum-refine-candidates-function old-rcf 
#'hotfuzz-filter)
+        (restore 'selectrum-highlight-candidates-function old-hcf 
#'hotfuzz--highlight-all)))))
+
+;;; Vertico integration
+
+(declare-function vertico--all-completions "ext:vertico")
+
+(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 completion system.
+Contrary to what the name might suggest, this mode does not
+automatically enable Hotfuzz. You still have to choose when it gets
+used by customizing e.g. `completion-styles'."
+  :global t
+  :group 'hotfuzz
+  (if hotfuzz-vertico-mode
+      (advice-add #'vertico--all-completions :around 
#'hotfuzz--vertico--all-completions-advice)
+    (advice-remove #'vertico--all-completions 
#'hotfuzz--vertico--all-completions-advice)))
 
 (provide 'hotfuzz)
 ;;; hotfuzz.el ends here
diff --git a/test/tests.el b/test/tests.el
index e31b6c844f..def5817e15 100644
--- a/test/tests.el
+++ b/test/tests.el
@@ -89,3 +89,19 @@
        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-not (null hl))))))

Reply via email to