Skip to content

Commit

Permalink
Use completion-lazy-hilit
Browse files Browse the repository at this point in the history
Closes #17
  • Loading branch information
axelf4 committed Nov 8, 2023
1 parent 822c936 commit a7563c9
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 65 deletions.
20 changes: 10 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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
46 changes: 7 additions & 39 deletions hotfuzz.el
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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)
Expand All @@ -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
16 changes: 0 additions & 16 deletions test/tests.el
Original file line number Diff line number Diff line change
Expand Up @@ -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))))))

0 comments on commit a7563c9

Please sign in to comment.