radian-software / prescient.el

☄️ Simple but effective sorting and filtering for Emacs.
MIT License
603 stars 25 forks source link

prescient.el: simple but effective sorting and filtering for Emacs.

Summary

prescient.el is a library which sorts and filters lists of candidates, such as appear when you use a package like Ivy or Company. Extension packages such as ivy-prescient.el and company-prescient.el adapt the library for usage with various frameworks.

prescient.el also provides a completion style (prescient) for filtering candidates via Emacs's generic completion, such as in Icomplete, Vertico, and Corfu. These last two have extension packages to correctly set up filtering and sorting.

As compared to other packages which accomplish similar tasks, including IDO, Ivy, Helm, Smex, Flx, Historian, and Company-Statistics, prescient.el aims to be simpler, more predictable, and faster.

Installation

prescient.el is available on MELPA as six separate packages (one for the library, and the rest for integrating with other frameworks):

The easiest way to install these packages is using straight.el:

(straight-use-package 'prescient)
(straight-use-package 'corfu-prescient)
(straight-use-package 'company-prescient)
(straight-use-package 'ivy-prescient)
(straight-use-package 'selectrum-prescient)
(straight-use-package 'vertico-prescient)

However, you may install using any other package manager if you prefer.

Usage

prescient.el and the extension packages provide modes that configure filtering and/or sorting in their respective framework. These modes can have their own settings, such as ways to set up filtering but not sorting, which are described in a following section.

Please note that you must load Counsel before ivy-prescient.el. This is because loading Counsel results in a number of changes being made to the user options of Ivy, which ivy-prescient.el must then undo.

Algorithm

prescient.el takes as input a list of candidates, and a query that you type.

When filtering, the query is first split on spaces into subqueries (two consecutive spaces match a literal space). Each subquery filters the candidates according to the filter methods listed in prescient-filter-method. By default, a subquery must match as either a substring of the candidate, a regexp, or an initialism (e.g. ffap matches find-file-at-point, and so does fa). A candidate must match all subqueries to pass the filter and subqueries can be matched in any order.

When sorting, the last few candidates you selected are displayed first, followed by the most frequently selected ones, and then the remaining candidates are sorted by length.

If you would like prescient.el to forget about a candidate, use the command prescient-forget.

Configuration and other features

Faces

prescient.el defines two faces: prescient-primary-highlight and prescient-secondary-highlight. The primary highlight is used to highlight matches in candidates. The secondary highlight is used for important sections within each matched region. For example, the initialism filter method highlights the entire match with prescient-primary-highlight and each initial in the initialism with prescient-secondary-highlight.

These faces are used by the prescient completion style (and so completion frameworks using that style, such as Corfu and Vertico) and Selectrum. ivy-prescient.el uses Ivy's faces.

The following example shows customizing these faces. I use the Zerodark color theme, which includes colors for Ivy, but not for Selectrum. I inspected the theme source code to see what colors were being used for Ivy, and copied them to be used for Selectrum as well:

(require 'zerodark-theme)

(let ((class '((class color) (min-colors 89))))
  (custom-theme-set-faces
   'zerodark
   `(selectrum-current-candidate
     ((,class (:background "#48384c"
                           :weight bold
                           :foreground "#c678dd"))))
   `(prescient-primary-highlight
     ((,class (:foreground "#da8548"))))
   `(prescient-secondary-highlight
     ((,class (:foreground "#98be65"))))))

(enable-theme 'zerodark)

For the completion style

The following user options are specific to using the prescient completion style:

For Corfu

corfu-prescient.el configures filtering locally in buffers in which corfu-mode is active. To do this, it modifies the values of completion-styles, completion-category-overrides, and completion-category-defaults. Sorting is configured globally.

The following user options are specific to using prescient.el with Corfu:

For Company

The following user options are specific to using prescient.el sorting with Company:

For Ivy

The following user options are specific to using prescient.el with Ivy:

For Selectrum

The following user options are specific to using prescient.el with Selectrum:

For Vertico

vertico-prescient.el configures filtering locally in the Vertico buffer. To do this, it modifies the values of completion-styles, completion-category-overrides, and completion-category-defaults. Sorting is configured globally.

The following user options are specific to using prescient.el with Vertico:

Contributor guide

Please see the contributor guide for my projects.