Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/minad/affe
:monkey: affe.el - Asynchronous Fuzzy Finder for Emacs
https://github.com/minad/affe
Last synced: about 1 month ago
JSON representation
:monkey: affe.el - Asynchronous Fuzzy Finder for Emacs
- Host: GitHub
- URL: https://github.com/minad/affe
- Owner: minad
- License: gpl-3.0
- Created: 2021-01-28T01:46:54.000Z (almost 4 years ago)
- Default Branch: main
- Last Pushed: 2024-02-24T15:16:19.000Z (9 months ago)
- Last Synced: 2024-05-02T00:30:13.244Z (7 months ago)
- Language: Emacs Lisp
- Homepage:
- Size: 160 KB
- Stars: 205
- Watchers: 6
- Forks: 8
- Open Issues: 0
-
Metadata Files:
- Readme: README.org
- License: LICENSE
Awesome Lists containing this project
README
#+title: affe.el - Asynchronous Fuzzy Finder for Emacs
#+author: Daniel Mendler
#+language: en
#+export_file_name: affe.texi
#+texinfo_dir_category: Emacs misc features
#+texinfo_dir_title: Affe: (affe).
#+texinfo_dir_desc: Asynchronous Fuzzy Finder for Emacs.#+html:
This package provides an asynchronous fuzzy finder similar to the [[https://github.com/junegunn/fzf][fzf
command-line fuzzy finder]], written in pure Elisp. A producer process is
started in the background, e.g., ~find~ or ~grep~. The output produced by this
process is filtered by an external asynchronous Emacs process. The Emacs UI
always stays responsive since the work is off-loaded to other processes. The
results are presented in the minibuffer using [[https://github.com/minad/consult][Consult]], which allows to quickly
select from the available items. Note that Affe is an experimental package and a
demonstrator of asynchronous processing outside of Emacs in a separate process.
Generally I recommend to use =consult-grep= or =consult-ripgrep=, since these
commands will perform better for large projects. The Consult package itself is
more mature.#+toc: headlines 8
* Installation and Configuration
The package is available on MELPA and can be installed using the Emacs package
manager. If files should not be automatically previewed, a manual preview key
should be set for ~affe-grep~.#+begin_src emacs-lisp
(use-package affe
:config
;; Manual preview key for `affe-grep'
(consult-customize affe-grep :preview-key "M-."))
#+end_srcThe default regular expression transformation of Consult is limited. It is
recommended to configure [[https://github.com/oantolin/orderless][Orderless]] as =affe-regexp-compiler= in Consult.#+begin_src emacs-lisp
(defun affe-orderless-regexp-compiler (input _type _ignorecase)
(setq input (cdr (orderless-compile input)))
(cons input (apply-partially #'orderless--highlight input t)))
(setq affe-regexp-compiler #'affe-orderless-regexp-compiler)
#+end_srcAffe requires the ~rg~ ("ripgrep") command line program to be available. The
producer processes can be customized by adjusting the variables
~affe-find-command~ and ~affe-grep-command~.* Available commands
- ~affe-grep~: Filters the content of all text files in the current directory, similar to ~consult-grep~.
- ~affe-find~: Filters the file paths of all files in the current directory, similar to ~consult-find~.* Related packages
Affe depends on Consult and works best with the Vertico and the Mct completion
UIs.- [[https://github.com/minad/consult][Consult]]: Useful search and navigation commands (Dependency of Affe).
- [[https://github.com/minad/marginalia][Marginalia]]: File annotations in the minibuffer.
- [[https://github.com/oantolin/embark][Embark]]: Minibuffer actions on files.
- [[https://github.com/oantolin/orderless][Orderless]]: Advanced completion style, can be plugged together with Affe.
- [[https://github.com/minad/vertico][Vertico]] or [[https://git.sr.ht/~protesilaos/mct][Mct]]: Vertical completion systems* Details
The Affe frontend transforms the input string to a list of regular expressions
by calling the ~affe-regexp-function~. The regular expressions are passed to the
Affe backend via the ~emacsclient~ protocol. The backend controls a producer
process, which generates lines of text. The lines are filtered using the regular
expressions submitted by the frontend. For performance reasons,
~all-completions~ is used for the filtering. The backend returns only a limited
amount of matching candidates, hopefully the most plausible ones. The frontend
calls the ~affe-highlight-function~ on the returned matches, to highlight the
input pattern.Affe uses a more primitive matching technique than ~fzf~, which uses the
[[https://en.wikipedia.org/wiki/Smith%E2%80%93Waterman_algorithm][Smith-Waterman algorithm]]. Affe does not perform any ranking or sorting; it
matches the lines in the order returned by the producer process against a list
of regular expressions. On the upside, this allows plugging Affe together with
the [[https://github.com/oantolin/orderless][Orderless]] completion style, which can give a consistent fuzzy filtering
experience across all Emacs commands, including synchronous and asynchronous
commands.As possible enhancement of Affe, one could implement alphabetical and sorting by
length in the backend. By using a bucket sorting technique the sorting
complexity will stay sufficiently linear such that the performance impact should
be acceptable. However implementing a scoring-based sorting is probably not
feasible since this requires heavier computations in Elisp. But maybe nativecomp
Emacs is a game changer here?* Alternatives
- [[https://github.com/minad/consult][consult-grep/consult-find]]: Perform the filtering in the frontend.
- [[https://github.com/abo-abo/swiper][counsel-fzf]]: Ivy-specific, restarts find+fzf when updating the input pattern.
- [[https://github.com/bling/fzf.el][fzf.el]]: Runs the fzf command line program in an Emacs terminal
- [[https://github.com/10sr/fuzzy-finder-el][fuzzy-finder.el]]: Similar to fzf.el