Skip to content

Commit

Permalink
Remove prescient-completion-enable-sort to avoid confusion. (#130)
Browse files Browse the repository at this point in the history
It is better to make the various completion UIs use
`prescient-completion-sort` directly, as this allows the sorting of
candidates filtered by other completion styles and avoids Company
Prescient re-sorting candidates from `company-capf`.

To keep things simple, the option of modifying completion-table
metadata is removed.

See #129 and conversations in minad/vertico#237.
  • Loading branch information
okamsn authored Oct 1, 2022
1 parent 928cc72 commit a86b714
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 107 deletions.
24 changes: 7 additions & 17 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,23 +24,13 @@ The format is based on [Keep a Changelog].
works with UIs like Emacs's built-in minibuffer completion,
Icomplete, and Vertico. See various discussions in [#125], [#120],
[#112], [#89], [#58], and [#54].
* In Emacs 27+, this completion style can optionally modify
unsorted completion tables to use `prescient.el` sorting instead.
This behavior can be enabled by setting the new user option
`prescient-completion-enable-sort` to `t`. Note that this might
lead to sorting candidates twice, such as when
`company-prescient-mode` is enabled and a Company backend filters
using the `prescient` completion style.
* The modification sets the sorting function to the new function
`prescient-completion-sort`, which combines `prescient-sort` with
the new function `prescient-sort-full-matches-first`. This
function is meant to be used after filtering.

Some completion UIs allow explicitly setting the sorting function.
Setting such an option to `prescient-completion-sort` is
recommended to use prescient.el's sorting with other completion
styles and backends. Note that sorting fully matched candidates
before others only works for candidates filtered by `prescient`.
* Add new function `prescient-completion-sort`, which combines
`prescient-sort` with the new function
`prescient-sort-full-matches-first`. See [#125]. This function is
meant to be used after filtering and as the sorting function of your
preferred completion UI. Note that sorting fully matched candidates
before partially matched candidates only works for candidates
filtered by the `prescient` completion style.
* Added user option `prescient-completion-highlight-matches`, which
determines whether the completion style highlights the matching
parts of candidates with the above new faces ([#125]).
Expand Down
27 changes: 1 addition & 26 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,7 @@ prefer.
2. Configure your completion UI to call `prescient-remember` on the
chosen candidate so that candidates are sorted correctly.
3. Configure your completion UI to sort filtered candidates via
`prescient-completion-sort` or a custom sorting function as
needed. Optionally, on Emacs 27+, you can instead set
`prescient-completion-enable-sort` (see below) to `t` to allow
the `prescient` completion style to set sorting directly. This
option is off by default to better work with various UIs.
`prescient-completion-sort`.

Please note that **you must load Counsel before `ivy-prescient.el`**.
This is because loading Counsel results in a number of changes being
Expand Down Expand Up @@ -153,27 +149,6 @@ completion style:
* `prescient-completion-highlight-matches`: Whether the completion
style should highlight matches in the filtered candidates.

* `prescient-completion-enable-sort`: Whether, in Emacs 27+, the
completion style should automatically modify unsorted candidates to
instead use the function `prescient-completion-sort`. This is
disabled by default to be more generic and to avoid users
accidentally sorting candidates more than once, such as when
`company-prescient-mode` is enabled and the `prescient` completion
style is used to filter candidates in the Company backend.

This user option only controls sorting done by the `prescient`
completion style. It does not affect sorting for the other styles in
the `completion-style` user option.

Some completion UIs, such as [Vertico][vertico] and [Corfu][corfu],
allow you to explicitly set a default sorting function for unsorted
candidates. In that case, you could set such an option to
`prescient-completion-sort`, which wraps the functions
`prescient-sort` and `prescient-sort-full-matches-first`. This would
also allow you to use prescient.el's sorting (excluding
`prescient-sort-full-matches-first`) with other completion styles
and completion backends.

### For Company
The following user options are specific to using `prescient.el`
sorting with Company:
Expand Down
72 changes: 8 additions & 64 deletions prescient.el
Original file line number Diff line number Diff line change
Expand Up @@ -226,24 +226,6 @@ contains no upper-case letters."
This affects the completion style, not other methods."
:type 'boolean)

(defcustom prescient-completion-enable-sort nil
"Whether the `prescient' completion style can set sorting.
If non-nil and in Emacs 27+, then completion tables that don't
specify a sorting function will use `prescient-completion-sort'.
Tables that do specify a sorting function are unaffected. This
will affect anything that uses the `prescient' completion style
for filtering, including possibly `completion-at-point'
functions.
Some completion UIs provide their own user options for sorting
functions. That might provide more control than indiscriminately
sorting candidates filtered by `prescient'. It also allows for
sorting candidates that were not filtered by `prescient'.
See also the user option `prescient-sort-length-enable'."
:type 'boolean)

(define-obsolete-face-alias 'selectrum-primary-highlight
'prescient-primary-highlight t)
(define-obsolete-face-alias 'selectrum-prescient-primary-highlight
Expand Down Expand Up @@ -917,31 +899,16 @@ REGEXPS."
(cl-defun prescient-completion-sort (candidates)
"Sort the filtered CANDIDATES.
This function is a wrapper around `prescient-sort' and the
function `prescient-sort-full-matches-first'. It is designed for
use with the `prescient' completion style, though it might also
be useful in other cases.
In Emacs 27 and later, when filtering via the `prescient'
completion style, if `prescient-completion-enable-sort' is
non-nil, then completion tables that do not specify a sorting
function are modified to use this function. This does not effect
the sorting done by other completion styles or by completion UIs
when those styles are filtering.
Therefore, if you want prescient.el sorting to be used with other
completion styles, consider setting your UI of choice to use this
function when no other function is given. If you explicitly set
the sorting function to this function or `prescient-sort', then
be sure that `prescient-completion-enable-sort' is nil (the
default) to avoid mistakenly sorting the candidates twice.
This function will always sort candidates using the function
`prescient-sort'. When CANDIDATES has been filtered using the
`prescient' completion style, it can optionally also sort them
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
the `prescient' style). These properties are set during
`prescient-filter', and are used for implementing the user option
`prescient-sort-full-matches-first'."
`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
Expand All @@ -958,23 +925,6 @@ the `prescient' style). These properties are set during
;; transformer.
sorted)))

(defun prescient--completion-modify-sort (metadata)
"Modify METADATA to use prescient.el for sorting if no order given."
;; Based on `completion--flex-adjust-metadata'.
;; Unlike `completion--flex-adjust-metadata', we want to modify
;; sorting even when there is no input.
(if (or (null prescient-completion-enable-sort)
;; If there is any existing sorting information, we assume
;; that it is meaningful and that we shouldn't even move the
;; fully matched candidates.
(completion-metadata-get metadata 'display-sort-function)
(completion-metadata-get metadata 'cycle-sort-function))
metadata
`(metadata
(display-sort-function . prescient-completion-sort)
(cycle-sort-function . prescient-completion-sort)
,@(cdr metadata))))

;;;;; Filtering functions

;;;###autoload
Expand Down Expand Up @@ -1029,14 +979,8 @@ actually just the input, in which case nothing happens."
(add-to-list
'completion-styles-alist
'( prescient prescient-try-completion prescient-all-completions
"Filtering (and optionally sorting) using prescient.el.
To enable sorting done by the completion style itself, see
`prescient-completion-enable-sort', which requires Emacs 27 or
later. Otherwise, see the function `prescient-completion-sort'."))

;;;###autoload
(put 'prescient
'completion--adjust-metadata 'prescient--completion-modify-sort)
"Filtering using prescient.el.
For sorting, see the function `prescient-completion-sort'."))

;;;; Closing remarks
(provide 'prescient)
Expand Down

0 comments on commit a86b714

Please sign in to comment.