Yevgnen/ivy-rich

Simple way to customize transformer column property

jeffvalk opened this issue · 4 comments

Please correct me if I am missing something. Currently, there doesn't seem to be a simple way to customize a column property without rewriting the entire transformer definition.

For example, to customize the :width property of the "major-mode" column of the 'ivy-switch-buffer transformer, one must do something like the following:

;; Set transformers -> ivy-switch-buffer -> major-mode column -> width to 20
(let* ((transformer (plist-get ivy-rich-display-transformers-list 'ivy-switch-buffer))
       (columns     (plist-get transformer :columns))
       (properties  (cadr (assoc 'ivy-rich-switch-buffer-major-mode columns))))
  (plist-put properties :width 20)))

This is quite a bit of code, and requires knowledge of implementation detail...just to set a column width.

Is there a better way to make a simple tweak to a transformer?

Yes, that's cumbersome...and people seems tend to redefine the transformer whole set. Do you have any API suggestion? Will simple wrapper like theses help?

(defun ivy-rich-set-display-transformer (cmd transformer-props)
  (plist-put ivy-rich-display-transformers-list cmd transformer-props))

(defun ivy-rich-set-display-transformer-property (cmd transformer column-prop column-value)
  (plist-put (cadr (assoc 'ivy-rich-switch-buffer-project
                          (plist-get (plist-get ivy-rich-display-transformers-list
                                                cmd) :columns)))
             column-prop column-value))

(ivy-rich-set-display-transformer
 'ivy-switch-buffer
 '(:columns
   ((ivy-switch-buffer-transformer (:width 0.35))
    (ivy-rich-switch-buffer-project (:width 0.18 :face success)))
   :predicate
   (lambda (cand) (get-buffer cand))))

(ivy-rich-set-display-transformer-property
 'ivy-switch-buffer
 'ivy-rich-switch-buffer-project
 :width 20)

Yes, those wrapper functions would be a big improvement.

I'd suggest two things to help API expressiveness:

  1. Allow the column property setting function to accept any number of key-value pairs; and
  2. Consider a shorter function name. 🙂

Perhaps something like the following:

(defun ivy-rich-adapt-column (cmd column &rest key-value-pairs)
  (if (evenp (length key-value-pairs))
      (let* ((trans (plist-get ivy-rich-display-transformers-list cmd))
             (props (cadr (assoc column (plist-get trans :columns)))))
        (while key-value-pairs
          (plist-put props
                     (pop key-value-pairs)
                     (pop key-value-pairs))))
    (error "An even number of key-value arguments is required")))


(ivy-rich-adapt-column 'ivy-switch-buffer
                       'ivy-rich-switch-buffer-major-mode
                       :width 20
                       :face :warning)

That's great suggestion! Do you mind opening a PR for this?

Sure. I will do that shortly.