Skip to content

Commit

Permalink
Support completion-lazy-hilit and completion-lazy-hilit-fn for Em…
Browse files Browse the repository at this point in the history
…acs 30.

This feature allows highlighting to occur later instead of being
performed by the completion style immediately.

- Move logic for highlighting a single candidate from
  `prescient--highlight-matches` to `prescient--highlight-candidate`.

- Rename `prescient--highlight-matches` to
  `prescient--highlight-candidates`, which now applies the new
  function to a list of candidates.
  - Keep this function to support
    `prescient-completion-highlight-matches`, which is now obsolete.

See:
- Prescient issue #152
  (#152)

- Emacs bug #47711
  (https://debbugs.gnu.org/cgi/bugreport.cgi?bug=47711)

- Emacs commit dfffb91a70532ac0021648ba692336331cbe0499
  (https://git.savannah.gnu.org/cgit/emacs.git/commit/?id=dfffb91a70532ac0021648ba692336331cbe0499),

- Vertico commit b11040e1e9c1a4e5178800a0d0925aeeb72dd027
  (minad/vertico@b11040e)

- This Prescient PR #153
  (#153).
  • Loading branch information
okamsn committed Nov 12, 2023
1 parent 37d356e commit 7e97215
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 32 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog].

## Unreleased
### Breaking Changes
* `prescient-completion-highlight-matches` is now obsolete ([#152],
[#153]). This user option is replaced by `completion-lazy-hilit`,
which is new in Emacs 30 and already supported by some third-party
completion UIs.

### Features
* New user option `prescient-tiebreaker` which can be used to change
how matches with no recency information are sorted, instead of by
Expand Down Expand Up @@ -37,6 +43,8 @@ The format is based on [Keep a Changelog].
[#128]: https://github.com/radian-software/prescient.el/pull/128
[#148]: https://github.com/radian-software/prescient.el/pull/148
[#149]: https://github.com/radian-software/prescient.el/pull/149
[#152]: https://github.com/radian-software/prescient.el/issues/152
[#153]: https://github.com/radian-software/prescient.el/pull/153

## 6.1 (released 2022-12-16)
### New features
Expand Down
84 changes: 54 additions & 30 deletions prescient.el
Original file line number Diff line number Diff line change
Expand Up @@ -234,9 +234,14 @@ contains no upper-case letters."
(const :tag "Never" nil)
(const :tag "Unless using upper-case letters" smart)))

(make-obsolete-variable 'prescient-completion-highlight-matches
nil nil 'set)
(defcustom prescient-completion-highlight-matches t
"Whether the `prescient' completion style should highlight matches.
This user option is obsolete. Completion UIs should instead be
using `completion-lazy-hilit'.
See also the faces `prescient-primary-highlight' and
`prescient-secondary-highlight'."
:type 'boolean)
Expand Down Expand Up @@ -522,37 +527,43 @@ filtered for use by the function `prescient-sort-full-matches-first'."
;; just return all properties here.
finally return props))

(defun prescient--highlight-matches (input candidates)
(defun prescient--highlight-candidate (regexps case-fold candidate)
"Highlight sections in CANDIDATE matching REGEXPS according to CASE-FOLD.
Returns a propertized CANDIDATE."
(setq candidate (copy-sequence candidate))
(prog1 candidate
(let ((case-fold-search case-fold))
(save-match-data
(dolist (regexp regexps)
(when (string-match regexp candidate)
(font-lock-prepend-text-property
(match-beginning 0) (match-end 0)
'face 'prescient-primary-highlight
candidate)
(cl-loop
for (start end)
on (cddr (match-data))
by #'cddr
do (when (and start end)
(font-lock-prepend-text-property
start end
'face 'prescient-secondary-highlight
candidate)))))))))

(defun prescient--highlight-candidates (input candidates)
"According to INPUT, highlight the matched sections in CANDIDATES.
INPUT is the string that was used to generate a list of regexps
for filtering. CANDIDATES is the list of filtered candidates,
which should be a list of strings.
Return a list of propertized CANDIDATES."
(let ((regexps (prescient-filter-regexps input 'with-group))
(case-fold-search (prescient-ignore-case-p input)))
(save-match-data
(mapcar
(lambda (candidate)
(setq candidate (copy-sequence candidate))
(prog1 candidate
(dolist (regexp regexps)
(when (string-match regexp candidate)
(font-lock-prepend-text-property
(match-beginning 0) (match-end 0)
'face 'prescient-primary-highlight
candidate)
(cl-loop
for (start end)
on (cddr (match-data))
by #'cddr
do (when (and start end)
(font-lock-prepend-text-property
start end
'face 'prescient-secondary-highlight
candidate)))))))
candidates))))
(cl-loop with regexps = (prescient-filter-regexps input 'with-group)
and case-fold-search = (prescient-ignore-case-p input)
for cand in candidates
collect (prescient--highlight-candidate regexps case-fold-search
cand)))

;;;; Regexp Builders

Expand Down Expand Up @@ -982,6 +993,9 @@ REGEXPS."
;; completion style. This feature is based on Orderless.el.
;; See: https://github.com/oantolin/orderless

(defvar completion-lazy-hilit)
(defvar completion-lazy-hilit-fn)

;;;;; Sorting functions

;;;###autoload
Expand Down Expand Up @@ -1034,12 +1048,22 @@ the length of the prefix string used for completion (which might
be all or just part of STRING)."
;; `point' is a required argument, but unneeded here.
(when-let ((completions (prescient-filter string table pred)))
(pcase-let ((`(,prefix . ,pattern)
(prescient--prefix-and-pattern string table pred)))
(nconc (if prescient-completion-highlight-matches
(prescient--highlight-matches pattern completions)
completions)
(length prefix)))))
(pcase-let* ((`(,prefix . ,pattern)
(prescient--prefix-and-pattern string table pred))
(maybe-highlighted
(cond
((bound-and-true-p completion-lazy-hilit)
(setq completion-lazy-hilit-fn
(apply-partially
#'prescient--highlight-candidate
(prescient-filter-regexps pattern 'with-group)
(prescient-ignore-case-p pattern)))
completions)
(prescient-completion-highlight-matches
(prescient--highlight-candidates pattern completions))
(t
completions))))
(nconc maybe-highlighted (length prefix)))))

;;;###autoload
(defun prescient-try-completion (string table &optional pred point)
Expand Down
4 changes: 2 additions & 2 deletions selectrum-prescient.el
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ For use on `selectrum-candidate-selected-hook'."
(setq selectrum-refine-candidates-function
#'selectrum-prescient--refine)
(setq selectrum-highlight-candidates-function
#'prescient--highlight-matches)
#'prescient--highlight-candidates)
(define-key selectrum-minibuffer-map
(kbd "M-s") prescient-toggle-map)
(add-hook 'prescient--toggle-refresh-functions
Expand All @@ -147,7 +147,7 @@ For use on `selectrum-candidate-selected-hook'."
(setq selectrum-refine-candidates-function
selectrum-prescient--old-refine-function))
(when (eq selectrum-highlight-candidates-function
#'prescient--highlight-matches)
#'prescient--highlight-candidates)
(setq selectrum-highlight-candidates-function
selectrum-prescient--old-highlight-function))
(when (equal (lookup-key selectrum-minibuffer-map (kbd "M-s"))
Expand Down

0 comments on commit 7e97215

Please sign in to comment.