Package: emacs;
Reported by: Heime <heimeborgia <at> protonmail.com>
Date: Thu, 17 Aug 2023 00:48:01 UTC
Severity: normal
Tags: notabug
Done: Eli Zaretskii <eliz <at> gnu.org>
Bug is archived. No further changes may be made.
View this message in rfc822 format
From: Drew Adams <drew.adams <at> oracle.com> To: Juri Linkov <juri <at> linkov.net> Cc: Eli Zaretskii <eliz <at> gnu.org>, "heimeborgia <at> protonmail.com" <heimeborgia <at> protonmail.com>, "65348 <at> debbugs.gnu.org" <65348 <at> debbugs.gnu.org> Subject: bug#65348: INITIAL-INPUT in completing-read repeats same entry twice consecutively Date: Mon, 21 Aug 2023 00:23:08 +0000
> > In case you're thinking, for your "obvious" use > > cases, of a case where you have few completion > > candidates, such as just "alpha", "beta", "gamma", > > then let's not forget that you can already cycle > > among those now, as completion candidates, without > > having them added to the future history. That's > > available since Stefan added candidate cycling, > > AFAIK. > > Your answers are too short. Please elaborate > what do you mean by "candidate cycling" and > what keys do you press to cycle candidates? Sorry. First, I'm no expert on the cycling provided by vanilla Emacs. I believe Stefan introduced it. He can probably tell you more, and better. There are two different completion metadata entries, `display-sort-function' and `cycle-sort-function'. See (elisp) `Programmed Completion': https://www.gnu.org/software/emacs/manual/html_node/elisp/Programmed-Completion.html (I don't see why anyone would ever want those two to have different values, but I don't think my ignorance about that is very relevant here.) Dunno whether there is some key that, by _default_, invokes one or the other of those functions. I use them in a two of my libraries, `sortie.el' and `keysee.el', to use vanilla Emacs cycling for cycling and display, together. With sortie.el, when you hit a key (`C-,' by default) the candidates in *Completions* are re-sorted, and so are the candidates you cycle through (same sort order). So when you cycle to a candidate, that's also the current candidate in *Completions*. To turn on cycling you need to give `completion-cycle-threshold' a non-nil value. Then you can cycle among candidates using `TAB'. keysee.el uses key descriptions as candidates. sortie.el uses sort orders (functions) as candidates. keysee.el uses sortie.el to let you change how its candidate key descriptions are sorted. In the Commentary of sortie there's a simple example of using the features it provides. Here's most of that example: (defun my-completion-with-sort-cycling () "Read and echo choice using completion with sort-order cycling." (interactive) (minibuffer-with-setup-hook #'sorti-bind-cycle-key (let ((sorti-current-order 'order1) (sorti-sort-function-chooser 'my-sort-fn-chooser) (sorti-sort-orders-alist '((order1 . "alphabetical") (order2 . "by length"))) (sorti-sort-orders-ring (let ((rng (make-ring 4))) (ring-insert rng 'order1) (ring-insert rng 'order2) rng))) (message "RESULT: %S" (completing-read "fff: " (my-collection-fn '("aa" "bb" "ab" "aaff" "c"))))))) (defun my-collection-fn (candidates) "Collection function that provides metadata for sorting. Sorting is per the current value of `my-sort-fn-chooser'." (lambda (string pred action) (if (eq action 'metadata) (let ((order (my-sort-fn-chooser))) `(metadata ,@(and order `((display-sort-function . ,order) (cycle-sort-function . ,order))))) (complete-with-action action candidates string pred)))) (defun my-sort-fn-chooser () "Return sort function for current value of `sorti-current-order'." (if (eq 'order2 sorti-current-order) 'my-sort-by-length 'my-sort-alphabetically)) So for example, with both sortie.el and keysee.el loaded, if you turn on mode `kc-mode' then * `S-TAB' shows currently available key bindings. * `C-,' re-sorts them in a few different ways (for both *Completions* display and cycling). You cycle among the available sort orders, to choose one, with `completing-read'. * `TAB' cycles among the key bindings, to choose one, with `completing-read'. ___ As I say, I don't know how others make use of the vanilla cycling feature. Maybe Emacs provides a key for such cycling by default, but I doubt it. I think you have to define the cycling yourself, by defining a function (such as `my-collection-fn' above) that dynamically sorts the candidates to produce a COLLECTION that's sorted as desired. But is it really needed - by default, i.e., in general - to be able to cycle among all candidates in COLLECTION? Certainly some libraries, such as Icicles, offer that, but it's not as if it's so essential that vanilla Emacs should provide it by default, I think. It makes sense to give coders ways to provide candidate cycling when they want it for `completing-read'. My main point was that IF any such cycling of COLLECTION entries is provided, it need not, and should NOT, be part of the history (future or not). Leave the history cycling to minibuffer input HISTORY and to DEFAULTS. If you want cycling of all candidates in COLLECTION then provide that as a different kind of cycling (different key). > Then maybe this cycling could be used instead of 'M-n'. No, not in my opinion; not at all. `M-n' should be only for cycling forward in the history, just as `M-p' should be for cycling backward. Users should know that that's what's being cycled, and that those things are NOT, in general, candidates from COLLECTION. (Think lax completion.) The "feature" of unequivocally adding COLLECTION to the history mixes things that don't belong together. It doesn't help users, IMO; and it can confuse them, by mixing carrots with car parts. My call is to first-and-foremost give control to (1) users interactively and (2) coders who call `completing-read'. We already have a way for any coder to add all of COLLECTION to the "future history": use it as, or include it in, the value of argument DEFAULTS. _End of story._ That gives coders 100% control over such addition. It's not blindly imposed on them. And it's easy to obtain when/if they want it. Easy peasy. They already have COLLECTION - just pass it also as arg DEFAULTS (or part of DEFAULTS). Arg DEFAULTS should, _alone_, determine/define the "future history". You can do anything you want with it, including get the current behavior that gets imposed unilaterally. But you need not live with that imposition. Do I want to argue this in emacs-devel? Not really. I really don't have time for such things these days. But do I wish something were done to remove this imposition and give control back to coders & users? Absolutely. If this makes sense to you, go for it. And I think it's simple to do: (1) Stop filling future history with COLLECTION, or at least provide a simple means to stop that. (2) Point out to users that IF they want to for some reason (the "many" use cases Eli hinted at), they can simply include all of COLLECTION as, or in, the future history, by just passing it as (or as part of) the list arg DEFAULTS. What's more, they can sort it first, any way they like. And they can filter it, if they don't want to include _all_ of COLLECTION. The current "feature" is brutal - it's a one-size-fits-none, IMO. It was never needed (DEFAULT suffices), and it can't be turned off. #2 is maybe not obvious, even though it has been available since Day One. If it were really so useful in "many" situations then I think we would have seen "many" users pass COLLECTION also as DEFAULTS (e.g. before Emacs 23). I seriously doubt we'v seen many - maybe not even any. Yet someone thought it was a great idea to impose that behavior always, on everyone - every call to `completing-read' that uses an explicit COLLECTION. Dunno who did that, and as Eli says, apparently it was done in Emacs 23. I guess many of us just never noticed it. BTW, what about a COLLECTION that's not explicit, that's realized bit by bit with a function? That doesn't work anyway for this "feature", I guess. You need to manifest an explicit COLLECTION, in order to add it to any history (history needs to be manifest for the call to `completing-read'). (I guess if you know the candidate domain you can use `all-completions' with a function COLLECTION to get an explicit version, if you really need to add it to the future history.) HTH. And BTW, thanks, Juri, for enhancing DEFAULT to be able to be a list (long ago). ___ https://www.emacswiki.org/emacs/download/sortie.el https://www.emacswiki.org/emacs/download/keysee.el
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.