Yevgnen / ivy-rich

More friendly interface for ivy.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

How to add a column?

shankar2k opened this issue · comments

I tried to use ivy-rich-modify-columns to add a column for counsel-recentf, like so:

(use-package ivy-rich
  :after counsel
  :custom
  (ivy-virtual-abbreviate 'full)
  (ivy-rich-path-style 'abbrev)
  :config
  (ivy-rich-mode 1)
  (setcdr (assq t ivy-format-functions-alist) #'ivy-format-function-line)
  
  (ivy-rich-replace-columns
   'counsel-recentf
   '((file-name-nondirectory
      (:width 0.2))
     (ivy-rich-candidate
      (:width 0.6)))))

This only changed the width of the existing column ivy-rich-candidate to 0.6, but didn't add the new first column file-name-nondirectory. As a workaround, I made my own function ivy-rich-replace-columns that replaces the whole column list:

(use-package ivy-rich
  :after counsel
  :custom
  (ivy-virtual-abbreviate 'full)
  (ivy-rich-path-style 'abbrev)
  :config
  (ivy-rich-mode 1)
  (setcdr (assq t ivy-format-functions-alist) #'ivy-format-function-line)
  
  (ivy-rich-replace-columns
   'counsel-recentf
   '((file-name-nondirectory
      (:width 0.2))
     (ivy-rich-candidate
      (:width 0.6))
     (ivy-rich-file-last-modified-time
      (:face font-lock-comment-face)))))

(defun ivy-rich-replace-columns (cmd column-list)
    (let ((trans (plist-get ivy-rich-display-transformers-list cmd)))
      (plist-put trans :columns column-list)))

This worked, but as you can see, it required that I include the unmodified column ivy-rich-file-last-modified-time and its attributes. Is there a more straightforward way to do this?

Hi, thanks for the issue. Currently the *-modify-* functions does not support complete replace the columns.

At the same time, I found a related bug by inspecting into the code. I will work on it later.

Thanks for looking into this. My code above has a small typo. The first code block should use ivy-rich-modify-columns, not my custom function ivy-rich-replace-columns

Hi, can you try the this branch?

I've fixed a issue the ivy-rich-modify-column not updating the new transformer column and add a new function ivy-rich-set-columns to set/replace column definitions completely. You may refer to the docstring of these functions to see example usages. In your specific case, this may be

(ivy-rich-set-columns
 'counsel-recentf
 '((file-name-nondirectory
    (:width 0.2))
   (ivy-rich-candidate
    (:width 0.6))))

Please let me know if that helps.

This works, thanks for the prompt response! It appears that your new function ivy-rich-set-columns is a cleaned-up version of my ivy-rich-replace-columns. This overwrites the original transformer columns and doesn't include any that aren't explicitly specified in COLUMN-LIST. This means that the setting you specified above:

(ivy-rich-set-columns
 'counsel-recentf
 '((file-name-nondirectory
    (:width 0.2))
   (ivy-rich-candidate
    (:width 0.6))))

Doesn't do exactly what I want because it omits the column (ivy-rich-file-last-modified-time (:face font-lock-comment-face)) that was in the default set of transformer columns for counsel-recentf. So to get the behavior I want, I have to configure it like this:

  (ivy-rich-set-columns
   'counsel-recentf
   '((file-name-nondirectory (:width 0.2))
     (ivy-rich-shorten (:width 0.6))
     (ivy-rich-file-last-modified-time (:face font-lock-comment-face))))

This is fine if it is how you intended for this function to work. However, if it isn't too difficult, I think a cleaner solution would be to make ivy-rich-modify-columns modify columns that are already present in ivy-rich-display-transformers-list and add columns that aren't already present. This way, one wouldn't need ivy-rich-set-columns in most cases (e.g., only when you don't want to preserve columns from the existing configuration).

Yes, this is intended behavior. As mentioned in the docstring of ivy-rich-modify-column, the 'add' behavior for new column is unclear: Where shall the new ones be set? I'm not sure if appending is always the best behavior and sometimes it may confused new users. I personally don't have any better idea right now...

That's a good point. The order of the columns does matter, and its not clear where a new column should go. I can see situations where the new columns should be be prepended (like my case), appended, or even in between existing columns, and there doesn't seem to be an elegant way to specify this. Thanks again!

I'm going to merge the fix into master. Let me know if you have any idea about that!

Here's an idea. Currently in ivy-rich-set-columns, one must specify a list of transformer columns, where each transformer column is a list of the form:

(TRANSFORMER 
    (:param1 val1 :param2 val2 ...))

Instead of a plist of parameter-value pairs, how about if one specifies a symbol like 'existing, then ivy-rich-set-columns will use the plist for the transformer in the original ivy-rich-display-transformers-list. Would that be difficult to implement? It doesn't save as much typing as I would like, because you would still have to specify all the original transformer columns that you want to use, but in some cases (e.g., ivy-switch-buffer) the savings could still be considerable.