From df3fe4e275205adbf57833552f6899d4810450fe Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jo=C3=A3o=20T=C3=A1vora?= Date: Sun, 22 Dec 2019 22:51:08 +0100 Subject: [PATCH] Fix bug in flex completion style's sorting and simplify This previous commit targetting this function introduced a bug whereby the completion table's sorting function wouldn't be called. That is fixed by this commit, which also simplifies the function further: it now skips re-sorting the completions completely if there is no minibuffer input at all (in other words, when flex isn't doing anything useful). * lisp/minibuffer.el (completion--flex-adjust-metadata): Simplify. --- lisp/minibuffer.el | 62 ++++++++++++++++++++++++---------------------- 1 file changed, 32 insertions(+), 30 deletions(-) diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el index c0df383e288..2dba26818e1 100644 --- a/lisp/minibuffer.el +++ b/lisp/minibuffer.el @@ -3583,36 +3583,38 @@ that is non-nil." (put 'flex 'completion--adjust-metadata 'completion--flex-adjust-metadata) (defun completion--flex-adjust-metadata (metadata) - (cl-flet ((compose-flex-sort-fn - (existing-sort-fn) ; wish `cl-flet' had proper indentation... - (lambda (completions) - (let* ((by-score - (sort - (if existing-sort-fn - (funcall existing-sort-fn completions) - completions) - (lambda (c1 c2) - (let ((s1 (get-text-property 0 'completion-score c1)) - (s2 (get-text-property 0 'completion-score c2))) - (> (or s1 0) (or s2 0)))))) - (promoted-default - (and minibuffer-default - (and (window-minibuffer-p) - (= (point-max) - (minibuffer-prompt-end))) - ;; If we have an empty pattern and a - ;; non-nil default we probably want to - ;; make sure that default is bubbled to - ;; the top even if it doesn't match the - ;; completion perfectly (like in M-x man - ;; case) - (cl-loop - for l on by-score - for comp = (cadr l) - when (string-prefix-p minibuffer-default comp) - do (setf (cdr l) (cddr l)) - and return (cons comp by-score))))) - (or promoted-default by-score))))) + (cl-flet + ((compose-flex-sort-fn + (existing-sort-fn) ; wish `cl-flet' had proper indentation... + (lambda (completions) + (let ((pre-sorted + (if existing-sort-fn + (funcall existing-sort-fn completions) + completions))) + (cond + ((or (not (window-minibuffer-p)) + (> (point-max) + (minibuffer-prompt-end))) + (sort + pre-sorted + (lambda (c1 c2) + (let ((s1 (get-text-property 0 'completion-score c1)) + (s2 (get-text-property 0 'completion-score c2))) + (> (or s1 0) (or s2 0)))))) + (minibuffer-default + ;; If we have an empty pattern and a non-nil default, we + ;; probably want to make sure that default is bubbled to + ;; the top so that a "force-completion" operation will + ;; select it. We want that to happen even if it doesn't + ;; match the completion perfectly. + (cl-loop + for l on pre-sorted + for comp = (cadr l) + when (string-prefix-p minibuffer-default comp) + do (setf (cdr l) (cddr l)) + and return (cons comp pre-sorted))) + (t + pre-sorted)))))) `(metadata (display-sort-function . ,(compose-flex-sort-fn -- 2.39.2