radian-software / selectrum

🔔 Better solution for incremental narrowing in Emacs.
MIT License
739 stars 33 forks source link

Question about ivy not being centered around the completing-read API #573

Open memeplex opened 3 years ago

memeplex commented 3 years ago

Hi,

the README states:

Selectrum focuses on the standard completion API offered by Emacs and tries to provide the best possible UI for this API. In contrast, Ivy deviates from this API and invents its own API with extra features, sacrificing reuse and composability down the road.

The packages centered around the completing-read API are more composable, interchangable and modular. Since Selectrum does not offer a public completion API, the decoupling of the components is enforced.

Maybe I don't understand the issue in due detail, but the characterization seems slightly inaccurate to me. AFAIU ivy works out of the box with everything completing-read, what is built on a piecemeal basis on top of standard functions is counsel (and swiper). At least in this regard, ivy seemingly compares to selectrum, the main difference being instead between the counsel approach and perhaps consult or embark (I'm not that familiarized with the new "completing ecosystem" yet). It is there, apparently, where reuse and composability are sacrificed.

A few years ago ivy's author posted about this issue, it's a very interesting read, there he said:

Initially, I hoped that ivy-mode could do most of the work, via the Emacs' completing-read-function interface. How it works: most built-in packages will call completing-read when they require completion. That function will forward the completion to completing-read-function if it's set. This is the way how things like icomplete-mode or ivy-mode or helm-mode work.

Unfortunately, the interface rather limits what you can do in completing-read-function. Essentially, you're given a list of strings and you have to return a string. You have no idea which function called you, so you can't do any fancy stuff depending on the caller, short of examining this-command which isn't very reliable. You have no idea what will be done with the one string that you return, so you can't do something fancy like select two or three strings and perform that action for each of them.

The result is that sometimes I have to replace the built-in functions, instead of re-using them. So instead of re-using find-file, I wrote my own counsel-find-file [...]

Would you mind explaining:

  1. How ivy (not counsel nor swiper) deviates from the completing-read API?
  2. How the new framework is able to overcome the limitations of that API that ivy's author faced at the time?

Thank you in advance.

memeplex commented 3 years ago

So instead of re-using find-file, I wrote my own counsel-find-file

BTW, this point was expressed in an extreme way, since counsel-find-file is more of a wrapper than a reimplementation, as most (all?) counsel functions are.

bdarcus commented 3 years ago

I'm not really sure, but suspect it has to do with the fact that ivy includes actions support (mentioned in the excerpt you quoted), and selectrum etc don't.

If that's right, then the question is really how embark implements actions with completing-read?