/ivy-rich

More friendly interface for ivy

Primary LanguageEmacs Lisp

README

1 More friendly interface for ivy

The package current comes with support for ivy-switch-buffer, counsel-M-x, counsel-describe-function and counsel-describe-variable, but it should be easy enough to define your own transformers. Screenshots are available here.

1.1 Installation

package-install RET ivy-rich RET

1.2 Basic Usages

(require 'ivy-rich)
(ivy-rich-mode 1)

It is recommended to set also

(setcdr (assq t ivy-format-functions-alist) #'ivy-format-function-line)

1.3 Customization

The transformer format for each ivy command is defined in plist ivy-rich--display-transformers-list, which has a default value

'(ivy-switch-buffer
  (:columns
   ((ivy-rich-candidate (:width 30))  ; return the candidate itself
    (ivy-rich-switch-buffer-size (:width 7))  ; return the buffer size
    (ivy-rich-switch-buffer-indicators (:width 4 :face error :align right)); return the buffer indicators
    (ivy-rich-switch-buffer-major-mode (:width 12 :face warning))          ; return the major mode info
    (ivy-rich-switch-buffer-project (:width 15 :face success))             ; return project name using `projectile'
    (ivy-rich-switch-buffer-path (:width (lambda (x) (ivy-rich-switch-buffer-shorten-path x (ivy-rich-minibuffer-width 0.3))))))  ; return file path relative to project root or `default-directory' if project is nil
   :predicate
   (lambda (cand) (get-buffer cand)))
  counsel-M-x
  (:columns
   ((counsel-M-x-transformer (:width 40))  ; thr original transformer
    (ivy-rich-counsel-function-docstring (:face font-lock-doc-face))))  ; return the docstring of the command
  counsel-describe-function
  (:columns
   ((counsel-describe-function-transformer (:width 40))  ; the original transformer
    (ivy-rich-counsel-function-docstring (:face font-lock-doc-face))))  ; return the docstring of the function
  counsel-describe-variable
  (:columns
   ((counsel-describe-variable-transformer (:width 40))  ; the original transformer
    (ivy-rich-counsel-variable-docstring (:face font-lock-doc-face))))  ; return the docstring of the variable
  counsel-recentf
  (:columns
   ((ivy-rich-candidate (:width 0.8)) ; return the candidate itself
    (ivy-rich-file-last-modified-time (:face font-lock-comment-face))))) ; return the last modified time of the file

Each plist key is a ivy command and plist value is its transformer format definitions. The transformer definition is combined with several columns (also in plist format) indicated by :columns and a filter function predicate function indicated by :predicate.

A transformer is just a string processing function with some format properties. Thus it should be easy to add or remove the columns you want. The first element of each element in the value of :columns is a transform function which takes an ivy candidate (string) and should return a transformed string. The second element is also a plist which defines the properties of current transformer. Currently supported keywords are :width, :face and :align. Refer to the documentation of ivy-rich--display-transformers-list for details. Notice that besides using a common face for each column, you can still return propertied string in the transform function.

If the predicate function is given, only candidate with t predicate will be transformed.

1.3.1 Example

1.3.1.1 counsel-M-x

For example, the transformer for counsel-M-x

counsel-M-x
(:columns
 ((counsel-M-x-transformer (:width 40))
  (ivy-rich-counsel-function-docstring (:face font-lock-doc-face))))

it defines two columns. The first one is the original built-in transformer with max width of 40 chars and the second one transforms the string candidate into a docstring with face font-lock-doc-face.

1.3.1.2 Add icons for ivy-switch-buffer

The package all-the-icons.el provides functionality to use icon fonts easily in emacs. For example, you can define a transformer

   (defun ivy-rich-switch-buffer-icon (candidate)
     (with-current-buffer
   	  (get-buffer candidate)
	(let ((icon (all-the-icons-icon-for-mode major-mode)))
	  (if (symbolp icon)
	      (all-the-icons-icon-for-mode 'fundamental-mode)
	    icon))))

and add it to the ivy-rich--display-transformers-List

(setq ivy-rich--display-transformers-list
      '(ivy-switch-buffer
        (:columns
         ((ivy-rich-switch-buffer-icon :width 2)
          (ivy-rich-candidate (:width 30))
          (ivy-rich-switch-buffer-size (:width 7))
          (ivy-rich-switch-buffer-indicators (:width 4 :face error :align right))
          (ivy-rich-switch-buffer-major-mode (:width 12 :face warning))
          (ivy-rich-switch-buffer-project (:width 15 :face success))
          (ivy-rich-switch-buffer-path (:width (lambda (x) (ivy-rich-switch-buffer-shorten-path x (ivy-rich-minibuffer-width 0.3))))))
         :predicate
         (lambda (cand) (get-buffer cand)))))

You will get

screenshots/all-the-icons.png

1.4 Notes

  1. If you modify ivy-rich--display-transformers-list, you may need to disable and re-enable ivy-rich-mode again to make the changes take effect.
  2. If you define transformers for commands comes from neither ivy nor counsel, e.g. counsel-projectile-*, it currently may not take effect since if you enable ivy-rich-mode before loading counsel-projectile, the transformer setting is overwritten by loading the package. I am considering to add a :package keyword in the transformer definition to deal with this.
  3. Disabling the minor mode ivy-rich-mode will restore the transformers to what they were before, but not necessarily to the ‘built-in default’ one. For example, the default transformer for ivy-switch-buffer is ivy-switch-buffer-transformer from the ivy package. But if you set the transformer to some-function before enabling ivy-rich-mode, disabling the minor mode will restore it to some-function other than ivy-switch-buffer-transformer.

2 Screenshots and details

2.1 ivy-switch-buffer

screenshots/buffer.png

To abbreviate paths using abbreviate-file-name (e.g. replace “/home/username” with “~”)

(setq ivy-rich-path-style 'abbrev)

Note that this may not affect remote files. To always show absolute path, set it to =’full= or =’absolute=. Any other value will show the file path relative to the project root or default-Directory.

There are two variables ivy-rich-parse-remote-buffer and ivy-rich-parse-remote-file-path controls how remote buffers are processed, please refer to the docstring of them for more details if you have trouble using this function under tramp.

2.2 counsel-M-x

screenshots/counsel-m-x.png

2.3 counsel-describe-variable

screenshots/counsel-describe-variable.png

2.4 counsel-recentf

screenshots/counsel-recentf.png

2.5 counsel-bookmark

screenshots/counsel-bookmark.png

2.6 package-install

screenshots/package-install.png

3 Important Changes

Since the version 0.1.0 of ivy-rich, the transformer format can be customized. Variables from older version like ivy-rich-switch-buffer-mode-max-length or ivy-rich-switch-buffer-project-max-length has been deprecated since they are now packed into ivy-rich--display-transformers-list as stated in the customization section.

Supports for virtual buffers and shorten file paths in ivy-switch-buffer are temporarily Removed.

4 FAQ

  • Can I search buffers by major-mode, project in ivy-switch-buffer?

    No, as far as I know, you can not right now. ivy-rich provides just transformers to display the original ivy candidates in a different way. It does not modify the original candidates. At least for now I have no idea how to add feature to search in the transformer columns. It probably requires some change in ivy.

So you can not search the description of counsel-describe-function neither.

5 Related Packages