'counsel-M-x
'(("d" counsel--find-symbol "definition")))
-(defun counsel--M-x-transformer (cand-pair)
- "Add a binding to CAND-PAIR cdr if the car is bound in the current window.
-CAND-PAIR is (command-name . extra-info)."
- (let* ((command-name (car cand-pair))
- (extra-info (cdr cand-pair))
- (binding (substitute-command-keys (format "\\[%s]" command-name))))
+(ivy-set-display-transformer
+ 'counsel-M-x
+ 'counsel-M-x-transformer)
+
+(defun counsel-M-x-transformer (cmd)
+ "Return CMD appended with the corresponding binding in the current window."
+ (let ((binding (substitute-command-keys (format "\\[%s]" cmd))))
(setq binding (replace-regexp-in-string "C-x 6" "<f2>" binding))
(if (string-match "^M-x" binding)
- cand-pair
- (cons command-name
- (if extra-info
- (format " %s (%s)" extra-info (propertize binding 'face 'font-lock-keyword-face))
- (format " (%s)" (propertize binding 'face 'font-lock-keyword-face)))))))
+ cmd
+ (format "%s (%s)"
+ cmd (propertize binding 'face 'font-lock-keyword-face)))))
(defvar smex-initialized-p)
(defvar smex-ido-cache)
(unless initial-input
(setq initial-input (cdr (assoc this-command
ivy-initial-inputs-alist))))
- (let* ((store ivy-format-function)
- (ivy-format-function
- (lambda (cand-pairs)
- (funcall
- store
- (with-ivy-window
- (mapcar #'counsel--M-x-transformer cand-pairs)))))
- (cands obarray)
+ (let* ((cands obarray)
(pred 'commandp)
(sort t))
(when (require 'smex nil 'noerror)
(when (featurep 'smex)
(smex-rank (intern cmd)))
(let ((prefix-arg current-prefix-arg)
- (ivy-format-function store)
(this-command (intern cmd)))
(command-execute (intern cmd) 'record)))
:sort sort
(setq ivy--actions-list
(plist-put ivy--actions-list cmd actions)))
+(defvar ivy--display-transformers-list nil
+ "A list of str->str transformers per command.")
+
+(defun ivy-set-display-transformer (cmd transformer)
+ "Set CMD a displayed candidate TRANSFORMER.
+
+It's a lambda that takes a string one of the candidates in the
+collection and returns a string for display, the same candidate
+plus some extra information.
+
+This lambda is called only on the `ivy-height' candidates that
+are about to be displayed, not on the whole collection."
+ (setq ivy--display-transformers-list
+ (plist-put ivy--display-transformers-list cmd transformer)))
+
(defvar ivy--sources-list nil
"A list of extra sources per command.")
matcher
;; When this is non-nil, call it for each input change to get new candidates
dynamic-collection
+ ;; A lambda that transforms candidates only for display
+ display-transformer-fn
caller)
(defvar ivy-last (make-ivy-state)
(list (car source) (funcall (car source)))
ivy--extra-candidates))))))
(setq ivy--extra-candidates '((original-source)))))
- (let ((recursive-ivy-last (and (active-minibuffer-window) ivy-last)))
+ (let ((recursive-ivy-last (and (active-minibuffer-window) ivy-last))
+ (transformer-fn (plist-get ivy--display-transformers-list caller)))
(setq ivy-last
(make-ivy-state
:prompt prompt
:re-builder re-builder
:matcher matcher
:dynamic-collection dynamic-collection
+ :display-transformer-fn transformer-fn
:caller caller))
(ivy--reset-state ivy-last)
(prog1
(end (min (+ start (1- ivy-height)) ivy--length))
(start (max 0 (min start (- end (1- ivy-height)))))
(cands (cl-subseq cands start end))
- (index (- ivy--index start)))
+ (index (- ivy--index start))
+ transformer-fn)
(cond (ivy--directory
(setq cands (mapcar (lambda (x)
(if (string-match-p "/\\'" x)
x)))
cands))))
(setq ivy--current (copy-sequence (nth index cands)))
+ (when (setq transformer-fn (ivy-state-display-transformer-fn ivy-last))
+ (with-ivy-window
+ (setq cands (mapcar transformer-fn cands))))
(let* ((ivy--index index)
- (cand-pairs (mapcar
- (lambda (cand)
- (cons (ivy--format-minibuffer-line cand) nil)) cands))
- (res (concat "\n" (funcall ivy-format-function cand-pairs))))
+ (cands (mapcar
+ (lambda (cand)
+ (cons (ivy--format-minibuffer-line cand) nil)) cands))
+ (res (concat "\n" (funcall ivy-format-function cands))))
(put-text-property 0 (length res) 'read-only nil res)
res))))