diff options
| author | João Távora | 2019-02-14 23:33:49 +0000 |
|---|---|---|
| committer | João Távora | 2019-02-14 23:33:49 +0000 |
| commit | 0d19e08da647c42562428dd608e5284cf414415e (patch) | |
| tree | 090e74e45424caa7632fce426d4f9626b65d5d88 | |
| parent | a4c7de35decaace94eba678161b0d4c8266647d2 (diff) | |
| download | emacs-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.el | 46 |
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 | ||
| 3048 | Value is a number whose sign and amplitude have subtly different | 3048 | Value is a positive number. Values smaller than one make the |
| 3049 | effects. Positive values make the scoring formula value matches | 3049 | scoring formula value matches scattered along the string, while |
| 3050 | scattered along the string, while negative values make the | 3050 | values greater than one make the formula value tighter matches. |
| 3051 | formula value tighter matches. I.e \"foo\" matches both strings | 3051 | I.e \"foo\" matches both strings \"barbazfoo\" and \"fabrobazo\", |
| 3052 | \"barfoobaz\" and \"fabrobazo\", which are of equal length, but | 3052 | which are of equal length, but only a value greater than one will |
| 3053 | only a negative value will score the former higher than the | 3053 | score the former (which has one \"hole\") higher than the |
| 3054 | second. | 3054 | latter (which has two).") |
| 3055 | |||
| 3056 | The absolute value of this variable controls the relative order | ||
| 3057 | of different-length strings matched by the same pattern . Its | ||
| 3058 | effect is not completely understood yet, so feel free to play | ||
| 3059 | around 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 |