abo-abo / swiper

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

Question about argument passed to :action for dynamic collection #2677

Open thanhvg opened 4 years ago

thanhvg commented 4 years ago

Hi, this could be a newbie question but I cannot find a workaround for my use case so far.

For a collection that is a alist when I use ivy-read without a :dynamic-collection option I got the whole (cons . cell) of the alist element in the :action callback. But when I add :dynamic-collection the :action callback will only get the cons of the alist element.

For example

(defun counsel-foo ()
  (interactive)
  (ivy-read "Foo: "
            (counsel-foo-fn "x")
            :action (lambda (x) (message "I got %s" x))))

(defun counsel-foo-dynamic ()
  (interactive)
  (ivy-read "Foo dyn: "
            #'counsel-foo-fn
            :dynamic-collection t
            :action (lambda (x) (message "I got %s" x))))

(defun counsel-foo-fn (&rest args)
  '(("1" . "one") ("2" . "two")))

When I run counsel-foo and choose 1, the echo area will show: I got (1 . one) which is expected.

But when I run counsel-foo-dynamic and choose 1, the echo area will show: I got 1, which is just the car of the element (1 . one).

I am very confused by this behavior. Why can't dynamic action get the whole alist element? Thanks

dsdshcym commented 3 years ago

I ran into a similar issue today, is it possible to get alist working with dynamic-collection?

thanhvg commented 3 years ago

@dsdshcym I found a solution from lsp project. Basically ivy can take a list of hashtable objects and you will have to define a transform function. I made small package for tide-mode using this approach:

https://github.com/thanhvg/counsel-tide-nav/blob/master/counsel-tide-nav.el

It's not clean and it's not documented anywhere afaik. On this matter I would say ivy's dynamic api is not intuitive as helm.

basil-conto commented 3 years ago

FWIW, you can always look the key up in the alist to retrieve the value.