03 February 2011

completing-read wishlist

Completing-read wishlist

Two features I'd like to see in emacs' completing-read:

  • A way to make it return the value or the whole object instead of the string.
  • A way to make it possibly loop using a new collection generated from the selection. That is useful for:
    • Showing the user the likely options first, but allowing him to get the full list of options by choosing something like "\*More\*"
    • Presenting a set of options that mostly behave alike, plus a few exceptional ones. Like "pick one of {A,B,C,etc} or \*Create a new entry\* and use it", or "Pick a function name or \*Rescan\* or pick from \*Variables\* instead". My `hbmk' does this, and so does `imenu'. Some packages such as filesets.el would probably have used this if it were available and would be more convenient.
    • Chaining, where one selection leads to a new set of options that elaborates the choice. Sometimes your code wants to immediately do work on the first selection in which case this isn't useful. But more often your code doesn't commit to action until the user has committed to a choice, and sometimes there's nothing to do between successive selections.

Wrote them, but that didn't suffice

I actually have written both of these. #1 I wrote back in the stone age; I believe I called it tehom-4.el. #2 I more-or-less wrote when I rewrote pcomplete to support pcmpl-elisp; it's not a separate thing and only does what pcomplete wanted, but it could be factored out and added to. Other people have had a hand at this too.

But being written doesn't make them available! If I write code that uses tehom-4, that gives it an additional dependency that's not bundled with emacs. AFAICT, nobody uses tehom-4 for another project, they just roll their own. And if I were to factor the #2 code out of pcomplete, it would just be the same story again.

That's an aspect of a problem I've bumped into a lot lately with emacs: Too little re-use of code. You can't really require non-bundled libraries unless you make them part of your package.

How

I implemented (2) something like this: after completing-read finished, if the value was a list it would check the car of it. If it was:

`complete-further'
completing-read would run again, using the cdr of the value as a collection. (I used the symbol `further')
nil
Done, treat the cdr as the value.

Other possibilities

  • Call the cdr as a function and use its return value as a collection.
  • Show something (Help message, context, anything) but not be finished.

Minor wishlist items:

  • A slightly more refined sense of the "require-match" param, including:
    nil
    Do not require match at all
    always-interact
    Require match. Always interact, even if there are zero completions
    yn
    Require match.
    • Abort if there are no completions.
    • If there's only one completion, interact to give user a chance to abort.
    t
    Require match.
    • Abort if there are no completions.
    • If there's only one completion, just use it.

No comments:

Post a Comment