Skip to content

Commit

Permalink
Only add properties for prescient-sort-full-matches-first to the fi…
Browse files Browse the repository at this point in the history
…rst candidate.

Only add properties to the first candidate, and search for the
properties in the candidates list. This should be better than what we
do now, which is to propertize every candidate and later get the
properties from the first candidate in the list.

For N candidates, the old way is always

    (propertize N) + (search 1) + (sort N)

and the new way is

    (propertize 1) + (search (N - x)) + (sort N)

where x is greater than or equal to 0. Assuming that
`get-text-property` is no worse than `propertize` (which seems true in
testing), the new way is never worse than the old way, and should
usually be better.
  • Loading branch information
okamsn committed Jul 4, 2023
1 parent a86b714 commit 016edcf
Showing 1 changed file with 29 additions and 23 deletions.
52 changes: 29 additions & 23 deletions prescient.el
Original file line number Diff line number Diff line change
Expand Up @@ -453,7 +453,7 @@ INPUT contains uppercase letters."
prescient-use-case-folding))

(defun prescient--add-sort-info (candidates regexps ignore-case)
"Propertize all candidates in CANDIDATES to save data.
"Propertize the first candidate in CANDIDATES to save data.
REGEXPS are the regexps used by filtering. IGNORE-CASE is whether
case was ignored. These are stored as the text property
Expand All @@ -463,16 +463,15 @@ This information is used by the function
`prescient-sort-full-matches-first'."
(if (null candidates)
nil
;; We need to propertize all of the candidates, since some UIs
;; might rearrange candidates before we can sort them. For
;; example, Company will sort CAPF candidates that don't have a
;; specified sorting function, which moves them around before
;; Some UIs might rearrange candidates before we can sort them.
;; For example, Company will sort CAPF candidates that don't have
;; a specified sorting function, which moves them around before
;; passing them to the Company Prescient transformer that applies
;; our own sorting.
(cl-loop for cand in candidates
collect (propertize cand
'prescient-regexps regexps
'prescient-ignore-case ignore-case))))
(cons (propertize (car candidates)
'prescient-regexps regexps
'prescient-ignore-case ignore-case)
(cdr candidates))))

(defun prescient--highlight-matches (input candidates)
"According to INPUT, highlight the matched sections in CANDIDATES.
Expand Down Expand Up @@ -905,25 +904,32 @@ This function will always sort candidates using the function
using the function `prescient-sort-full-matches-first'.
This function checks for the properties `prescient-regexps' and
`prescient-ignore-case' on the first candidate in
CANDIDATES (though they are stored on all candidates filtered by
`prescient-ignore-case' on any candidate in CANDIDATES (though
they are stored on the first candidate returned by
`prescient-filter'). These properties are used for implementing
the user option `prescient-sort-full-matches-first'."
(if (null candidates)
nil
(let ((regexps (get-text-property 0 'prescient-regexps
(car candidates)))
(ignore-case (get-text-property 0 'prescient-ignore-case
(car candidates)))
(sorted (prescient-sort candidates)))
;; `prescient-filter' adds the properties needed for
;; `prescient-sort-full-matches-first' to the first candidate in
;; the list it returns. If we're receiving the filtered candidates
;; directly (so, not in `company-prescient-transformer') then we
;; should be checking for them before running `prescient-sort',
;; which destructively modifies CANDIDATES.
(let ((regexps)
(ignore-case))
(when prescient-sort-full-matches-first
(setq sorted (prescient-sort-full-matches-first
sorted regexps ignore-case)))
;; Since we propertize all candidates during `prescient-filter',
;; we don't need to worry about re-arranging candidates here
;; for whatever comes after, such as the Company Prescient
;; transformer.
sorted)))
(cl-loop
for cand in candidates
do (setq regexps (get-text-property 0 'prescient-regexps cand))
until regexps
finally do
(setq ignore-case (get-text-property 0 'prescient-ignore-case cand))))
(thread-first
candidates
(prescient-sort)
;; If `regexps' is nil, this just returns the input.
(prescient-sort-full-matches-first regexps ignore-case)))))

;;;;; Filtering functions

Expand Down

0 comments on commit 016edcf

Please sign in to comment.