aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoão Távora2019-02-12 21:48:24 +0000
committerJoão Távora2019-02-13 21:21:51 +0000
commite4896fcb1189f6739f228d441b6c50118536e3d8 (patch)
tree798d5624b805063b354da57bd1fb3623294e0ad6
parent10527fca66e39d7067986904161fa33741abcd26 (diff)
downloademacs-e4896fcb1189f6739f228d441b6c50118536e3d8.tar.gz
emacs-e4896fcb1189f6739f228d441b6c50118536e3d8.zip
Add a new 'flex' completion style
* lisp/minibuffer.el (completion-styles-alist): Add flex. (completion-substring--all-completions): Accept transform-pattern-fn arg. (completion-flex-all-completions, completion-flex-try-completion) (completion-flex--make-flex-pattern): New functions.
-rw-r--r--lisp/minibuffer.el61
1 files changed, 60 insertions, 1 deletions
diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el
index b757eb8a5a6..c1e3fdc0781 100644
--- a/lisp/minibuffer.el
+++ b/lisp/minibuffer.el
@@ -788,6 +788,11 @@ Additionally the user can use the char \"*\" as a glob pattern.")
788I.e. when completing \"foo_bar\" (where _ is the position of point), 788I.e. when completing \"foo_bar\" (where _ is the position of point),
789it will consider all completions candidates matching the glob 789it will consider all completions candidates matching the glob
790pattern \"*foo*bar*\".") 790pattern \"*foo*bar*\".")
791 (flex
792 completion-flex-try-completion completion-flex-all-completions
793 "Completion of an in-order subset of characters.
794When completing \"foo\" the glob \"*f*o*o*\" is used, so that
795i.e. foo can complete to frodo.")
791 (initials 796 (initials
792 completion-initials-try-completion completion-initials-all-completions 797 completion-initials-try-completion completion-initials-all-completions
793 "Completion of acronyms and initialisms. 798 "Completion of acronyms and initialisms.
@@ -3345,7 +3350,12 @@ the same set of elements."
3345;;; Substring completion 3350;;; Substring completion
3346;; Mostly derived from the code of `basic' completion. 3351;; Mostly derived from the code of `basic' completion.
3347 3352
3348(defun completion-substring--all-completions (string table pred point) 3353(defun completion-substring--all-completions
3354 (string table pred point &optional transform-pattern-fn)
3355 "Match the presumed substring STRING to the entries in TABLE.
3356Respect PRED and POINT. The pattern used is a PCM-style
3357substring pattern, but it be massaged by TRANSFORM-PATTERN-FN, if
3358that is non-nil."
3349 (let* ((beforepoint (substring string 0 point)) 3359 (let* ((beforepoint (substring string 0 point))
3350 (afterpoint (substring string point)) 3360 (afterpoint (substring string point))
3351 (bounds (completion-boundaries beforepoint table pred afterpoint)) 3361 (bounds (completion-boundaries beforepoint table pred afterpoint))
@@ -3356,6 +3366,9 @@ the same set of elements."
3356 (pattern (if (not (stringp (car basic-pattern))) 3366 (pattern (if (not (stringp (car basic-pattern)))
3357 basic-pattern 3367 basic-pattern
3358 (cons 'prefix basic-pattern))) 3368 (cons 'prefix basic-pattern)))
3369 (pattern (if transform-pattern-fn
3370 (funcall transform-pattern-fn pattern)
3371 pattern))
3359 (all (completion-pcm--all-completions prefix pattern table pred))) 3372 (all (completion-pcm--all-completions prefix pattern table pred)))
3360 (list all pattern prefix suffix (car bounds)))) 3373 (list all pattern prefix suffix (car bounds))))
3361 3374
@@ -3375,6 +3388,52 @@ the same set of elements."
3375 (nconc (completion-pcm--hilit-commonality pattern all) 3388 (nconc (completion-pcm--hilit-commonality pattern all)
3376 (length prefix))))) 3389 (length prefix)))))
3377 3390
3391;;; "flex" completion, also known as flx/fuzzy/scatter completion
3392;; Completes "foo" to "frodo" and "farfromsober"
3393
3394(defun completion-flex--make-flex-pattern (pattern)
3395 "Convert PCM-style PATTERN into PCM-style flex pattern.
3396
3397This turns
3398 (prefix \"foo\" point)
3399into
3400 (prefix \"f\" any \"o\" any \"o\" any point)
3401which is at the core of flex logic. The extra
3402'any' is optimized away later on."
3403 (mapcan (lambda (elem)
3404 (if (stringp elem)
3405 (mapcan (lambda (char)
3406 (list (string char) 'any))
3407 elem)
3408 (list elem)))
3409 pattern))
3410
3411(defun completion-flex-try-completion (string table pred point)
3412 "Try to flex-complete STRING in TABLE given PRED and POINT."
3413 (pcase-let ((`(,all ,pattern ,prefix ,suffix ,_carbounds)
3414 (completion-substring--all-completions
3415 string table pred point
3416 #'completion-flex--make-flex-pattern)))
3417 (if minibuffer-completing-file-name
3418 (setq all (completion-pcm--filename-try-filter all)))
3419 ;; Try some "merging", meaning add as much as possible to the
3420 ;; user's pattern without losing any possible matches in `all'.
3421 ;; i.e this will augment "cfi" to "config" if all candidates
3422 ;; contain the substring "config". FIXME: this still won't
3423 ;; augment "foo" to "froo" when matching "frodo" and
3424 ;; "farfromsober".
3425 (completion-pcm--merge-try pattern all prefix suffix)))
3426
3427(defun completion-flex-all-completions (string table pred point)
3428 "Get flex-completions of STRING in TABLE, given PRED and POINT."
3429 (pcase-let ((`(,all ,pattern ,prefix ,_suffix ,_carbounds)
3430 (completion-substring--all-completions
3431 string table pred point
3432 #'completion-flex--make-flex-pattern)))
3433 (when all
3434 (nconc (completion-pcm--hilit-commonality pattern all)
3435 (length prefix)))))
3436
3378;; Initials completion 3437;; Initials completion
3379;; Complete /ums to /usr/monnier/src or lch to list-command-history. 3438;; Complete /ums to /usr/monnier/src or lch to list-command-history.
3380 3439