1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2026-04-07 06:41:00 -07:00
emacs/lisp
João Távora afb422bb98 Rewrite flex completion scoring with Gotoh algorithm
The greedy regexp matching, broken scoring and broken highlight were
sources of frequent complaints about the 'flex' matching style.  This
commit fixes that.

It was inspired by the 'hotfuzz' style available at
https://github.com/axelf4/hotfuzz which is a modified version of Gotoh's
1982 dynamic programming algorithm (see: GOTOH, Osamu. An improved
algorithm for matching biological sequences. Journal of molecular
biology, 1982, 162.3: 705-708.).  That style is slightly more
sophisticated than 'flex' (has special rules for matching things at word
boundaries, a C module with multithreading support).  It's almost (but not
entirely) void of hacks so it'd make a good candidate to replace 'flex'
entirely, but no progress has been made in getting it into Emacs's core
in over 2 years, so I thought I'd try my hand at it.

The new 'flex' implementation also uses Gotoh algorithm (apparently
a common choice for these kinds of task) and happens mostly in a new C
function.  It is strictly more correct than the "old" flex.  For
example, when matching the pattern 'goto' to, say, 'eglot--goto' and
'eglot--bol', no longer is the latter returned first, which was a
substantial annoyance.  And of course the highlighting is also correctly
placed on the 'goto' not scattered across the candidate.

Regarding performance, it is faster than the naive 'flex', but that's
mainly because this commit also includes changes to the Elisp code which
make faster regexp's for the filtering step.  It is slower than
'hotfuzz' when that style's C-module extension is leveraged.  'hotfuzz'
does the filtering and sorting steps together in C code and has
multithreaded workers there.  The matching and scoring algorithm itself
is not the bottleneck.

Test code were refactored and more tests were added.

* src/minibuf.c (completion--flex-score-gotoh): New function.

* lisp/minibuffer.el (completion--flex-score): Rewrite.
(completion--flex-propertize): New function.
(completion-flex--pattern-str): New variable.
(flex-score-match-tightness): Make obsolete.
(completion-pcm--all-completions): Add optional override-re parameter.
(completion-pcm--hilit-commonality): No more re-based highlighting.
(completion-substring--all-completions): Add optional simple-re parameters.
(completion--flex-adjust-metadata): Tweak to new scoring API.
(completion-flex-try-completion, completion-flex-all-completions):
Pass simple-re parameter to completion-substring--all-completions.
(completion--hilit-from-re, completion--flex-score-1)
(completion--flex-score-last-md, completion-pcm--regexp): Delete.

* test/lisp/minibuffer-tests.el (completion--sorted-flex-completions):
New helper function.
(completion-flex-test-non-ascii): New test.
(completion--pcm-score): Delete.
(completion-pcm-test-3, completion-pcm-test-4)
(completion-substring-test-1, completion-substring-test-2)
(completion-flex-test-2, completion-flex-test-3): Remove old scoring
expectations.
2026-02-05 15:17:42 +00:00
..
calc
calendar
cedet Fix [More] buttons in tutorial and other buttons in Semantic 2026-02-03 05:14:59 +02:00
emacs-lisp shortdoc: Don't burp on missing docstrings 2026-02-04 10:59:23 -05:00
emulation
erc
eshell
gnus
image
international
language
leim/quail
mail
mh-e
net
nxml
obsolete
org
play
progmodes
term
textmodes (yaml-ts-mode-yamllint-options): Use a list of strings 2026-02-04 11:03:57 -05:00
url
use-package
vc diff-mode-shared-map: Bind '@' to diff-revert-and-kill-hunk 2026-02-02 12:57:12 +00:00
abbrev.el
align.el
allout-widgets.el
allout.el
ansi-color.el
ansi-osc.el
apropos.el
arc-mode.el
array.el
auth-source-pass.el
auth-source.el
autoinsert.el
autorevert.el
avoid.el
battery.el
bind-key.el
bindings.el
bookmark.el
bs.el
buff-menu.el
button.el
calculator.el
case-table.el
ChangeLog.1
ChangeLog.2
ChangeLog.3
ChangeLog.4
ChangeLog.5
ChangeLog.6
ChangeLog.7
ChangeLog.8
ChangeLog.9
ChangeLog.10
ChangeLog.11
ChangeLog.12
ChangeLog.13
ChangeLog.14
ChangeLog.15
ChangeLog.16
ChangeLog.17
char-fold.el
chistory.el
cmuscheme.el
color.el
comint.el * lisp/comint.el (comint-redirect-hook): Defvar (bug#80313) 2026-02-04 11:14:10 -05:00
completion-preview.el
completion.el
composite.el
COPYING
cus-dep.el
cus-edit.el
cus-face.el
cus-start.el
cus-theme.el
custom.el
dabbrev.el
delim-col.el
delsel.el
descr-text.el
desktop.el
dframe.el
dired-aux.el
dired-x.el
dired.el
dirtrack.el
disp-table.el
display-fill-column-indicator.el
display-line-numbers.el
dnd.el
doc-view.el
dom.el
dos-fns.el
dos-vars.el
dos-w32.el
double.el
dynamic-setting.el
ebuff-menu.el
ecomplete.el
editorconfig-conf-mode.el
editorconfig-core-handle.el
editorconfig-core.el
editorconfig-fnmatch.el
editorconfig-tools.el
editorconfig.el
edmacro.el
ehelp.el
elec-pair.el
electric.el
elide-head.el
emacs-lock.el
env.el
epa-dired.el
epa-file.el
epa-hook.el
epa-ks.el
epa-mail.el
epa.el
epg-config.el
epg.el
expand.el
external-completion.el
ezimage.el
face-remap.el
facemenu.el
faces.el
ffap.el
filecache.el
fileloop.el
filenotify.el
files-x.el
files.el
filesets.el
find-cmd.el
find-dired.el
find-file.el
find-lisp.el
finder.el
flow-ctrl.el
foldout.el
follow.el
font-core.el
font-lock.el
format-spec.el
format.el
forms.el
frame.el
frameset.el
fringe.el
generic-x.el
help-at-pt.el
help-fns.el
help-macro.el
help-mode.el Fix [More] buttons in tutorial and other buttons in Semantic 2026-02-03 05:14:59 +02:00
help.el
hex-util.el
hexl.el
hfy-cmap.el
hi-lock.el
hilit-chg.el
hippie-exp.el
hl-line.el
htmlfontify.el
ibuf-ext.el
ibuf-macs.el
ibuffer.el
icomplete.el
ido.el
ielm.el
iimage.el
image-file.el
image-mode.el
image.el
imenu.el
indent-aux.el
indent.el
info-look.el
info-xref.el
info.el
informat.el
isearch.el isearch.el: Remove autoloads hacks 2026-02-02 17:42:40 -05:00
isearchb.el
jit-lock.el
jka-cmpr-hook.el
jka-compr.el
json.el
jsonrpc.el
keymap.el
kmacro.el
ldefs-boot.el
loadhist.el
loadup.el
locate.el
lpr.el
ls-lisp.el
macros.el
Makefile.in
man.el
master.el
mb-depth.el
md4.el
menu-bar.el
midnight.el
minibuf-eldef.el
minibuffer.el Rewrite flex completion scoring with Gotoh algorithm 2026-02-05 15:17:42 +00:00
misc.el
misearch.el
mouse-copy.el
mouse-drag.el
mouse.el
mpc.el
msb.el
mwheel.el
newcomment.el
notifications.el
novice.el
obarray.el
outline.el
paren.el
password-cache.el
pcmpl-cvs.el
pcmpl-git.el
pcmpl-gnu.el
pcmpl-linux.el
pcmpl-rpm.el
pcmpl-unix.el
pcmpl-x.el
pcomplete.el
pgtk-dnd.el
pixel-scroll.el
plstore.el
printing.el
proced.el
profiler.el
ps-bdf.el
ps-mule.el
ps-print.el
ps-samp.el
pulse.el
README
recentf.el
rect.el
register.el
registry.el
repeat.el
replace.el
reposition.el
reveal.el
rfn-eshadow.el
ring-bell-fns.el
rot13.el
rtree.el
ruler-mode.el
savehist.el
saveplace.el
scroll-all.el
scroll-bar.el
scroll-lock.el
select.el
send-to.el
server.el
ses.el
shadowfile.el
shell.el
simple.el
skeleton.el
so-long.el
sort.el
soundex.el
speedbar.el
sqlite-mode.el
sqlite.el
startup.el
strokes.el
subr.el
svg.el
system-taskbar.el
t-mouse.el
tab-bar.el
tab-line.el
tabify.el
talk.el
tar-mode.el
tempo.el
term.el
thingatpt.el
thread.el
time-stamp.el
time.el
timezone.el
tmm.el
tool-bar.el
tooltip.el
touch-screen.el
transient.el
tree-widget.el
treesit-x.el
treesit.el
tty-tip.el
tutorial.el Fix [More] buttons in tutorial and other buttons in Semantic 2026-02-03 05:14:59 +02:00
type-break.el
uniquify.el
userlock.el
vcursor.el
version.el
view.el
visual-wrap.el
w32-fns.el
w32-vars.el
wdired.el
which-key.el
whitespace.el
wid-browse.el
wid-edit.el
widget.el
windmove.el
window-tool-bar.el
window-x.el
window.el
winner.el
woman.el
x-dnd.el
xdg.el
xml.el
xt-mouse.el
xwidget.el
yank-media.el

This directory contains source code for the parts of Emacs that are
written in Emacs Lisp.  *.el files are Emacs Lisp source, and the
corresponding *.elc files are byte-compiled versions.  Byte-compiled
files are architecture-independent.

The term subdirectory contains Lisp files that customize Emacs for
certain terminal types.  When Emacs starts, it checks the TERM
environment variable to get the terminal type and loads
'term/${TERM}.el' if it exists.

The other subdirectories hold Lisp packages grouped by their general
purpose.