branch: externals/consult
commit 977794acd3baa601e5bfa40e344dd9656455814e
Author: Daniel Mendler <[email protected]>
Commit: Daniel Mendler <[email protected]>

    Add consult--annotate-align to compute annotation alignment (Fix #740)
---
 consult.el | 97 ++++++++++++++++++++++++++++++++++----------------------------
 1 file changed, 54 insertions(+), 43 deletions(-)

diff --git a/consult.el b/consult.el
index dbfd4c0b5a..5dbcf54b65 100644
--- a/consult.el
+++ b/consult.el
@@ -501,6 +501,12 @@ as the public API.")
 This function can be called by custom completion systems from
 outside the minibuffer.")
 
+(defvar consult--annotate-align-step 10
+  "Round candidate width.")
+
+(defvar consult--annotate-align-width 0
+  "Maximum candidate width used for annotation alignment.")
+
 (defconst consult--tofu-char #x200000
   "Special character used to encode line prefixes for disambiguation.
 We use invalid characters outside the Unicode range.")
@@ -2347,6 +2353,18 @@ Note that `consult-narrow-key' and `consult-widen-key' 
are bound dynamically."
 
 ;;;; Internal API: consult--read
 
+(defun consult--annotate-align (cand ann)
+  "Align annotation ANN by computing the maximum CAND width."
+  (setq consult--annotate-align-width
+        (max consult--annotate-align-width
+             (* (ceiling (consult--display-width cand)
+                         consult--annotate-align-step)
+                consult--annotate-align-step)))
+  (when ann
+    (concat
+     #("   " 0 1 (display (space :align-to (+ left 
consult--annotate-align-width))))
+     ann)))
+
 (defun consult--add-history (async items)
   "Add ITEMS to the minibuffer future history.
 ASYNC must be non-nil for async completion functions."
@@ -2457,6 +2475,7 @@ PREVIEW-KEY are the preview keys."
                                 . ,(apply-partially #'consult--read-annotate 
annotate))))
                          ,@(unless sort '((cycle-sort-function . identity)
                                           (display-sort-function . 
identity)))))
+             (consult--annotate-align-width 0)
              (result
               (consult--with-preview
                   preview-key state
@@ -2607,14 +2626,14 @@ KEYMAP is a command-specific keymap."
     (delq nil)
     (delete-dups)))
 
-(defun consult--multi-annotate (sources align cand)
-  "Annotate candidate CAND with `consult--multi' type, given SOURCES and 
ALIGN."
-  (let* ((src (consult--multi-source sources cand))
-         (annotate (plist-get src :annotate))
-         (ann (if annotate
-                  (funcall annotate (cdr (get-text-property 0 'multi-category 
cand)))
-                (plist-get src :name))))
-    (and ann (concat align ann))))
+(defun consult--multi-annotate (sources cand)
+  "Annotate candidate CAND from multi SOURCES."
+  (consult--annotate-align
+   cand
+   (let ((src (consult--multi-source sources cand)))
+     (if-let ((fun (plist-get src :annotate)))
+         (funcall fun (cdr (get-text-property 0 'multi-category cand)))
+       (plist-get src :name)))))
 
 (defun consult--multi-group (sources cand transform)
   "Return title of candidate CAND or TRANSFORM the candidate given SOURCES."
@@ -2664,25 +2683,23 @@ KEYMAP is a command-specific keymap."
 
 (defun consult--multi-candidates (sources)
   "Return `consult--multi' candidates from SOURCES."
-  (let ((idx 0) (max-width 0) (candidates))
+  (let ((idx 0) candidates)
     (seq-doseq (src sources)
       (let* ((face (and (plist-member src :face) `(face ,(plist-get src 
:face))))
              (cat (plist-get src :category))
              (items (plist-get src :items))
              (items (if (functionp items) (funcall items) items)))
         (dolist (item items)
-          (let ((cand (consult--tofu-append item idx))
-                (width (consult--display-width item)))
+          (let ((cand (consult--tofu-append item idx)))
             ;; Preserve existing `multi-category' datum of the candidate.
             (if (get-text-property 0 'multi-category cand)
                 (when face (add-text-properties 0 (length item) face cand))
               ;; Attach `multi-category' datum and face.
               (add-text-properties 0 (length item)
                                    `(multi-category (,cat . ,item) ,@face) 
cand))
-            (when (> width max-width) (setq max-width width))
             (push cand candidates))))
       (cl-incf idx))
-    (cons (+ 3 max-width) (nreverse candidates))))
+    (nreverse candidates)))
 
 (defun consult--multi-enabled-sources (sources)
   "Return vector of enabled SOURCES."
@@ -2773,18 +2790,15 @@ Optional source fields:
   (let* ((sources (consult--multi-enabled-sources sources))
          (candidates (consult--with-increased-gc
                       (consult--multi-candidates sources)))
-         (align (propertize
-                 " " 'display
-                 `(space :align-to (+ left ,(car candidates)))))
          (selected
           (apply #'consult--read
-                 (cdr candidates)
+                 candidates
                  (append
                   options
                   (list
                    :category    'multi-category
                    :predicate   (apply-partially #'consult--multi-predicate 
sources)
-                   :annotate    (apply-partially #'consult--multi-annotate 
sources align)
+                   :annotate    (apply-partially #'consult--multi-annotate 
sources)
                    :group       (apply-partially #'consult--multi-group 
sources)
                    :lookup      (apply-partially #'consult--multi-lookup 
sources)
                    :preview-key (consult--multi-preview-key sources)
@@ -4066,27 +4080,23 @@ of the prompt.  See also `cape-history' from the Cape 
package."
   (let ((history (if (eq t search-default-mode)
                      (append regexp-search-ring search-ring)
                    (append search-ring regexp-search-ring))))
-    (cons
-     (delete-dups
-      (mapcar
-       (lambda (cand)
-         ;; The search type can be distinguished via text properties.
-         (let* ((props (plist-member (text-properties-at 0 cand)
-                                     'isearch-regexp-function))
-                (type (pcase (cadr props)
-                        ((and 'nil (guard (not props))) ?r)
-                        ('nil                           ?l)
-                        ('word-search-regexp            ?w)
-                        ('isearch-symbol-regexp         ?s)
-                        ('char-fold-to-regexp           ?c)
-                        (_                              ?u))))
-           ;; Disambiguate history items.  The same string could
-           ;; occur with different search types.
-           (consult--tofu-append cand type)))
-       history))
-     (if history
-         (+ 4 (apply #'max (mapcar #'length history)))
-       0))))
+    (delete-dups
+     (mapcar
+      (lambda (cand)
+        ;; The search type can be distinguished via text properties.
+        (let* ((props (plist-member (text-properties-at 0 cand)
+                                    'isearch-regexp-function))
+               (type (pcase (cadr props)
+                       ((and 'nil (guard (not props))) ?r)
+                       ('nil                           ?l)
+                       ('word-search-regexp            ?w)
+                       ('isearch-symbol-regexp         ?s)
+                       ('char-fold-to-regexp           ?c)
+                       (_                              ?u))))
+          ;; Disambiguate history items.  The same string could
+          ;; occur with different search types.
+          (consult--tofu-append cand type)))
+      history))))
 
 (defconst consult--isearch-history-narrow
   '((?c . "Char")
@@ -4106,13 +4116,12 @@ starts a new Isearch session otherwise."
   (consult--forbid-minibuffer)
   (let* ((isearch-message-function 'ignore) ;; Avoid flicker in echo area
          (inhibit-redisplay t)              ;; Avoid flicker in mode line
-         (candidates (consult--isearch-history-candidates))
-         (align (propertize " " 'display `(space :align-to (+ left ,(cdr 
candidates))))))
+         (candidates (consult--isearch-history-candidates)))
     (unless isearch-mode (isearch-mode t))
     (with-isearch-suspended
      (setq isearch-new-string
            (consult--read
-            (car candidates)
+            candidates
             :prompt "I-search: "
             :category 'consult-isearch
             :history t ;; disable history
@@ -4121,7 +4130,9 @@ starts a new Isearch session otherwise."
             :keymap consult-isearch-history-map
             :annotate
             (lambda (cand)
-              (concat align (alist-get (consult--tofu-get cand) 
consult--isearch-history-narrow)))
+              (consult--annotate-align
+               cand
+               (alist-get (consult--tofu-get cand) 
consult--isearch-history-narrow)))
             :group
             (lambda (cand transform)
               (if transform

Reply via email to