Last active
December 29, 2016 01:15
-
-
Save PythonNut/0538505e5aac87ea1d620dd32f9dcf12 to your computer and use it in GitHub Desktop.
Ivy smart flx sorting
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(defun nadvice/ivy--flx-sort (name cands) | |
"Sort according to closeness to string NAME the string list CANDS." | |
(condition-case nil | |
(let* (;; an optimized regex for fuzzy matching | |
;; "abc" → "\\`[^a]*a[^b]*b[^c]*c" | |
(fuzzy-regex (if (= (elt name 0) ?^) | |
(concat "^" | |
(regexp-quote (substring name 1 2)) | |
(mapconcat | |
(lambda (x) | |
(setq x (string x)) | |
(concat "[^" x "]*" (regexp-quote x))) | |
(substring name 2) | |
"")) | |
(concat "^" | |
(mapconcat | |
(lambda (x) | |
(setq x (string x)) | |
(concat "[^" x "]*" (regexp-quote x))) | |
name | |
"")))) | |
(flx-name (if (string-match "^\\^" name) | |
(substring name 1) | |
name)) | |
(cands-left) | |
(cands-to-sort)) | |
;; filter out non-matching candidates | |
(dolist (cand cands) | |
(when (string-match fuzzy-regex cand) | |
(push cand cands-left))) | |
;; pre-sort the candidates by length before partitioning | |
(setq cands-left (sort cands-left | |
(lambda (c1 c2) | |
(< (length c1) | |
(length c2))))) | |
;; partition the candidates into sorted and unsorted groups | |
(dotimes (_n (min (length cands-left) ivy-flx-limit)) | |
(push (pop cands-left) cands-to-sort)) | |
(append | |
;; compute all of the flx scores in one pass and sort | |
(mapcar #'car | |
(sort (mapcar | |
(lambda (cand) | |
(cons cand | |
(car (flx-score cand | |
flx-name | |
ivy--flx-cache)))) | |
cands-to-sort) | |
(lambda (c1 c2) | |
(if (/= (cdr c1) (cdr c2)) | |
(> (cdr c1) | |
(cdr c2)) | |
(< (length (car c1)) | |
(length (car c2))))))) | |
;; add the unsorted candidates | |
cands-left)) | |
(error | |
cands))) | |
(advice-add 'ivy--flx-sort :override #'nadvice/ivy--flx-sort) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment