abo-abo / swiper

Ivy - a generic completion frontend for Emacs, Swiper - isearch with an overview, and more. Oh, man!
https://oremacs.com/swiper/
2.29k stars 338 forks source link

Group candidates with separators #2892

Open jkitchin opened 3 years ago

jkitchin commented 3 years ago

Is it possible to make a selection buffer that looks like this in ivy? I am familiar with using a transformer for annotations, I was wondering more about the separators.

image

basil-conto commented 3 years ago

Is it possible to make a selection buffer that looks like this in ivy?

In theory, of course - perhaps even today, by making some clever (read: kludge) usage of display properties or similar. But it's not a currently supported UI AFAIK.

I guess the correct way to go about this would be to support the group-function completion metadata property that's new in Emacs 28. @minad (author of group-function and the better integrated and more modular completion packages Vertico, Marginalia, etc.) will know more about this than I.

For some other similar UI discussions see also #2780 and #2847.

bdarcus commented 3 years ago

I guess the correct way to go about this would be to support the group-function completion metadata property that's new in Emacs 28.

Yes, this is definitely the right path.

I thought Ivy might already have support for group-function, but if not, definitely would be great to have.

FWIW, that UI is using the group-function with completing-read (here Vertico). Would be awesome if it "just works" in Ivy at some point.

The WIP PR:

https://github.com/bdarcus/bibtex-actions/pull/182

... and the group-function definition:

https://github.com/bdarcus/bibtex-actions/pull/182/files#diff-0c5bf39d0ba9ffa1e60ab4e4ccc706f13a708558105935f70075f8824e7d90d7R184

I'll paste it here just in case I rebase and the link breaks :-)

(defun bibtex-actions-org-cite--styles-group-fn (style transform)
  "Return group title of STYLE or TRANSFORM the candidate.
This is a group-function that groups org-cite style/variant
strings by style."
    (let ((short-style
           (if (string-match "^/[bcf]*" style) "default"
             (car (split-string style "/")))))
    (if transform
        ;; Use the candidate string as is.
        (concat "  " (truncate-string-to-width style 20 nil 32))
      ;; Transform for grouping and group title display.
      (cond
       ((string= short-style "default") "Default")
       ((string= short-style "author") "Author-Only")
       ((string= short-style "locators") "Locators-Only")
       ((string= short-style "text") "Textual/Narrative")
       ((string= short-style "nocite") "No Cite")
       ((string= short-style "noauthor") "Suppress Author")))))