aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoão Távora2019-02-14 23:33:49 +0000
committerJoão Távora2019-02-14 23:33:49 +0000
commit0d19e08da647c42562428dd608e5284cf414415e (patch)
tree090e74e45424caa7632fce426d4f9626b65d5d88
parenta4c7de35decaace94eba678161b0d4c8266647d2 (diff)
downloademacs-0d19e08da647c42562428dd608e5284cf414415e.tar.gz
emacs-0d19e08da647c42562428dd608e5284cf414415e.zip
Change scoring strategy for 'flex' completion style
The previous strategy had problems comparing scores of matches to strings of different lengths. This one seems slightly more sensible, and uses a new constant `flex-score-match-tightness' instead of the more abstract `flex-score-falloff'. It's not completely without problems, and I think it shouldn't count "holes" at the front and at the back, but that needs a different "pattern-to-regexp" conversion in completion-pcm--hilit-commonality. (defun test () (mapcar (lambda (a) (cons (substring-no-properties a) (get-text-property 0 'completion-score a))) (sort (completion-pcm--hilit-commonality '(prefix "f" star "o" star "o" point) '("foo" "barfoobaz" "foobarbaz" "barbazfoo" "fabrobazo" "foot" "foto" "fotttttttttttttttttttttttto")) (lambda (a b) (> (get-text-property 0 'completion-score a) (get-text-property 0 'completion-score b)))))) (let ((flex-score-match-tightness 100)) (test)) => (("foo" . 1.0) ("foot" . 0.375) ("foto" . 0.375) ("foobarbaz" . 0.16260162601626016) ;; one hole ("barbazfoo" . 0.16260162601626016) ;; one hole ("barfoobaz" . 0.10964912280701755) ;; two holes ("fabrobazo" . 0.10964912280701755) ;; two holes ("fotttttttttttttttttttttttto" . 0.04982561036372696)) (let ((flex-score-match-tightness 0.1)) (test)) => (("foo" . 1.0) ("foot" . 0.375) ("foto" . 0.375) ("barfoobaz" . 0.007751937984496124) ;; two holes ("fabrobazo" . 0.007751937984496124) ;; two holes ("foobarbaz" . 0.00641025641025641) ;; one hole ("barbazfoo" . 0.00641025641025641) ;; one hole ("fotttttttttttttttttttttttto" . 0.0004789272030651341)) * lisp/minibuffer.el (flex-score-falloff): Rename to flex-score-match-tightness. (completion-pcm--hilit-commonality): Update function.
-rw-r--r--lisp/minibuffer.el46
1 files changed, 23 insertions, 23 deletions
diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el
index cdbd4b3b545..7413be42ebd 100644
--- a/lisp/minibuffer.el
+++ b/lisp/minibuffer.el
@@ -3042,21 +3042,16 @@ PATTERN is as returned by `completion-pcm--string->pattern'."
3042 (when (string-match-p regex c) (push c poss))) 3042 (when (string-match-p regex c) (push c poss)))
3043 (nreverse poss)))))) 3043 (nreverse poss))))))
3044 3044
3045(defvar flex-score-falloff -1.5 3045(defvar flex-score-match-tightness 100
3046 "Controls how the `flex' completion style scores its matches. 3046 "Controls how the `flex' completion style scores its matches.
3047 3047
3048Value is a number whose sign and amplitude have subtly different 3048Value is a positive number. Values smaller than one make the
3049effects. Positive values make the scoring formula value matches 3049scoring formula value matches scattered along the string, while
3050scattered along the string, while negative values make the 3050values greater than one make the formula value tighter matches.
3051formula value tighter matches. I.e \"foo\" matches both strings 3051I.e \"foo\" matches both strings \"barbazfoo\" and \"fabrobazo\",
3052\"barfoobaz\" and \"fabrobazo\", which are of equal length, but 3052which are of equal length, but only a value greater than one will
3053only a negative value will score the former higher than the 3053score the former (which has one \"hole\") higher than the
3054second. 3054latter (which has two).")
3055
3056The absolute value of this variable controls the relative order
3057of different-length strings matched by the same pattern . Its
3058effect is not completely understood yet, so feel free to play
3059around with it.")
3060 3055
3061(defun completion-pcm--hilit-commonality (pattern completions) 3056(defun completion-pcm--hilit-commonality (pattern completions)
3062 (when completions 3057 (when completions
@@ -3092,10 +3087,10 @@ around with it.")
3092 ;; score 1. The formula takes the form of a quotient. 3087 ;; score 1. The formula takes the form of a quotient.
3093 ;; For the numerator, we use the number of +, i.e. the 3088 ;; For the numerator, we use the number of +, i.e. the
3094 ;; length of the pattern. For the denominator, it 3089 ;; length of the pattern. For the denominator, it
3095 ;; counts the number of - in each such group, 3090 ;; sums (1+ (/ (grouplen - 1)
3096 ;; exponentiates that number to `flex-score-falloff', 3091 ;; flex-score-match-tightness)) across all groups of
3097 ;; adds it to the total, adds one to the final sum, 3092 ;; -, sums one to that total, and then multiples by
3098 ;; and then multiples by the length of the string. 3093 ;; the length of the string.
3099 (score-numerator 0) 3094 (score-numerator 0)
3100 (score-denominator 0) 3095 (score-denominator 0)
3101 (last-b 0) 3096 (last-b 0)
@@ -3103,22 +3098,27 @@ around with it.")
3103 (lambda (a b) 3098 (lambda (a b)
3104 "Update score variables given match range (A B)." 3099 "Update score variables given match range (A B)."
3105 (setq 3100 (setq
3106 score-numerator (+ score-numerator (- b a)) 3101 score-numerator (+ score-numerator (- b a)))
3107 score-denominator (+ score-denominator 3102 (unless (= a last-b)
3108 (expt (- a last-b) 3103 (setq
3109 flex-score-falloff)) 3104 score-denominator (+ score-denominator
3105 1
3106 (/ (- a last-b 1)
3107 flex-score-match-tightness
3108 1.0))))
3109 (setq
3110 last-b b)))) 3110 last-b b))))
3111 (funcall update-score 0 start) 3111 (funcall update-score start start)
3112 (while md 3112 (while md
3113 (funcall update-score start (car md)) 3113 (funcall update-score start (car md))
3114 (put-text-property start (pop md) 3114 (put-text-property start (pop md)
3115 'font-lock-face 'completions-common-part 3115 'font-lock-face 'completions-common-part
3116 str) 3116 str)
3117 (setq start (pop md))) 3117 (setq start (pop md)))
3118 (funcall update-score len len)
3118 (put-text-property start end 3119 (put-text-property start end
3119 'font-lock-face 'completions-common-part 3120 'font-lock-face 'completions-common-part
3120 str) 3121 str)
3121 (funcall update-score start end)
3122 (if (> (length str) pos) 3122 (if (> (length str) pos)
3123 (put-text-property pos (1+ pos) 3123 (put-text-property pos (1+ pos)
3124 'font-lock-face 'completions-first-difference 3124 'font-lock-face 'completions-first-difference