diff options
| author | João Távora | 2019-10-25 23:57:44 +0100 |
|---|---|---|
| committer | João Távora | 2019-10-26 13:09:52 +0100 |
| commit | 7fc0292f5c49d11fc39853f8bc25586d54221e6a (patch) | |
| tree | 807713e2e4c8585553f357a0acd9057a749c1171 | |
| parent | e3cebbb839fc94f314659bf667c6790edebf4297 (diff) | |
| download | emacs-7fc0292f5c49d11fc39853f8bc25586d54221e6a.tar.gz emacs-7fc0292f5c49d11fc39853f8bc25586d54221e6a.zip | |
Allow completion styles to adjust completion metadata
The new facility, realized in the completion-adjust-metadata-for-style
generic, allows completion styles to have a say in metadata properties
such as cycle-sort-function and display-sort-function. This is
especially useful for completion styles such as 'flex', which
generally produce many matches, including some potentially "obscure"
ones. The default sorting strategy would often bubble the latter
to the top of the list.
The sorting function for 'flex' considers pre-computed matching scores
and is thus much better than the default for this particular style.
Additionally, it overrides the completion table's cycle-sort-function
or display-sort-function properties if they exist, although it still
uses them to pre-sort the result, so that they are still relevant for
resolving ties.
* lisp/minibuffer.el (completion--nth-completion): Call
completion-adjust-metadata-for-style.
(completion-adjust-metadata-for-style): New generic.
(completion-adjust-metadata-for-style 'flex): New method.
| -rw-r--r-- | lisp/minibuffer.el | 46 |
1 files changed, 37 insertions, 9 deletions
diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el index 7227e83f878..35de3fbb969 100644 --- a/lisp/minibuffer.el +++ b/lisp/minibuffer.el | |||
| @@ -907,6 +907,31 @@ This overrides the defaults specified in `completion-category-defaults'." | |||
| 907 | (delete-dups (append (cdr over) (copy-sequence completion-styles))) | 907 | (delete-dups (append (cdr over) (copy-sequence completion-styles))) |
| 908 | completion-styles))) | 908 | completion-styles))) |
| 909 | 909 | ||
| 910 | (cl-defgeneric completion-adjust-metadata-for-style (style metadata) | ||
| 911 | "Adjust METADATA of current completion according to STYLE." | ||
| 912 | (:method (_style _metadata) nil) ; nop by default | ||
| 913 | (:method | ||
| 914 | ((_style (eql flex)) metadata) | ||
| 915 | (cl-flet ((compose-flex-sort-fn | ||
| 916 | (existing-sort-fn) ; wish `cl-flet' had proper indentation... | ||
| 917 | (lambda (completions) | ||
| 918 | (let ((res | ||
| 919 | (if existing-sort-fn | ||
| 920 | (funcall existing-sort-fn completions) | ||
| 921 | completions))) | ||
| 922 | (sort | ||
| 923 | res | ||
| 924 | (lambda (c1 c2) | ||
| 925 | (or (equal c1 minibuffer-default) | ||
| 926 | (> (get-text-property 0 'completion-score c1) | ||
| 927 | (get-text-property 0 'completion-score c2))))))))) | ||
| 928 | (let ((alist (cdr metadata))) | ||
| 929 | (setf (alist-get 'display-sort-function alist) | ||
| 930 | (compose-flex-sort-fn (alist-get 'display-sort-function alist))) | ||
| 931 | (setf (alist-get 'cycle-sort-function alist) | ||
| 932 | (compose-flex-sort-fn (alist-get 'cycle-sort-function alist))) | ||
| 933 | metadata)))) | ||
| 934 | |||
| 910 | (defun completion--nth-completion (n string table pred point metadata) | 935 | (defun completion--nth-completion (n string table pred point metadata) |
| 911 | "Call the Nth method of completion styles." | 936 | "Call the Nth method of completion styles." |
| 912 | (unless metadata | 937 | (unless metadata |
| @@ -936,17 +961,20 @@ This overrides the defaults specified in `completion-category-defaults'." | |||
| 936 | (setq string (pop new)) | 961 | (setq string (pop new)) |
| 937 | (setq table (pop new)) | 962 | (setq table (pop new)) |
| 938 | (setq point (pop new)) | 963 | (setq point (pop new)) |
| 939 | (cl-assert (<= point (length string))) | 964 | (cl-assert (<= point (length string))) |
| 940 | (pop new)))) | 965 | (pop new)))) |
| 941 | (result | 966 | (result-and-style |
| 942 | (completion--some (lambda (style) | 967 | (completion--some |
| 943 | (funcall (nth n (assq style | 968 | (lambda (style) |
| 944 | completion-styles-alist)) | 969 | (let ((probe (funcall (nth n (assq style |
| 945 | string table pred point)) | 970 | completion-styles-alist)) |
| 946 | (completion--styles metadata)))) | 971 | string table pred point))) |
| 972 | (and probe (cons probe style)))) | ||
| 973 | (completion--styles metadata)))) | ||
| 974 | (completion-adjust-metadata-for-style (cdr result-and-style) metadata) | ||
| 947 | (if requote | 975 | (if requote |
| 948 | (funcall requote result n) | 976 | (funcall requote (car result-and-style) n) |
| 949 | result))) | 977 | (car result-and-style)))) |
| 950 | 978 | ||
| 951 | (defun completion-try-completion (string table pred point &optional metadata) | 979 | (defun completion-try-completion (string table pred point &optional metadata) |
| 952 | "Try to complete STRING using completion table TABLE. | 980 | "Try to complete STRING using completion table TABLE. |