bug-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

bug#27158: 25.2; Eliminating old usage of completing-read from built-in


From: Ryan Thompson
Subject: bug#27158: 25.2; Eliminating old usage of completing-read from built-in files
Date: Wed, 31 May 2017 11:45:33 +0000

The default arg has been available since the beginning, AFAIK.
The behavior you describe is no more legacy than is providing a
default-value arg.  Nothing to do with backward compatibility,
I think.

I suppose I inferred that it was a backward-compatibility issue from the fact that the feature is used intentionally in very few places (all fairly old code) and is triggered unintentionally in more places, i.e. more recently-written functions that set REQUIRE-MATCH to t and then assume that completing-read will always return an element from the collection. The latter kind will typically produce an error or do something nonsensical for the empty string.

And it returns the default, even if REQUIRE-MATCH is non-nil
and the default is not in the collection.  Do you dislike
that behavior too?

"" is just the default default, if you like (or not).

Thanks, that's actually a good way to think about it.
 
Would you make a default arg be mandatory instead of optional?
Is that it?  If not, what default default would you propose?
What should be returned if no explicit default is provided and
the user hits RET with no input?

Thinking some more about it, I guess one solution would be to give REQUIRE-MATCH could gain a special 3rd value, such as `force', which would mandate that the returned value is a valid completion. (Not sure what should happen in this case if DEF is provided and is not a valid completion.)

"" seems like a great choice for the default default, to me.
It's pretty much guaranteed never to coincide with any usable
completion candidate (which is not the case for a non-empty
default value).  For one thing, that lets you easily check
whether the user chose one of the candidates, even in the
case where the collection is complex (e.g. a function).

> This quirk

Why is it a quirk?

IN any case, nothing stops someone from defining their own
`my-completing-read', which does not have this feature, er,
quirk.  I don't see the problem.

The problem comes when implementing a completion system that returns the first available completion when pressiong RET (e.g. ido and ivy). In the case of an empty input, RET causes these completion systems to return the first element of COLLECTION if no default was specified. Sometimes this is correct, but sometimes this is wrong, as in the following usage pattern:
(defun pick-a-fruit ()
  (interactive)
  (let* ((default "banana")
         (prompt (format "Pick a fruit (default %s): " default))
         (collection '("apple" "banana" "cherry"))
         (selection (completing-read prompt collection nil t)))
    (when (string= selection "")
      (setq selection default))
    (message "You selected %s" selection)))
This pattern is used in e.g. Info-follow-reference. The problem is that there's no way for the completion function to know whether it's being used in this way or not, so if the user presses RET on an empty input and the default wasn't provied to completing-read, it doesn't know whether it should return the empty string or the first match. For an example where returning the first match seems like the more correct behavior, see read-char-by-name, which throws an error on the empty string. This ambiguity makes it difficult to reconcile the desired convenience feature of "return the first match on RET" with the documented completing-read behavior of "return the empty string on empty input + RET" without breaking some functions. And it's not even possible to implement an automatic fallback to completing-read-default, because there's no way for the completion function to know whether the caller is expecting that behavior (Info-follow-reference) or is expecting it not to happen (read-char-by-name). Ultimately, that's the issue: if completing-read is called with a DEF being nil, the calling code may or may not be expecting it to return the empty string, and while not expecting the empty string might represent a bug in the caller, the existence of such functions makes it difficult to implement ido-style completion that does the right thing in all cases.

Going back to your statement that "empty string is just the default default", it's possible that one might get reasonable behavior for ido and ivy by taking this statement literally and prepending "" to the list of completions when DEF is nil. By "reasonable" I mean correct behavior in all of the cases that completing-read-default is correct, and bug-for-bug compatibility in functions that don't expect completing-read to return "". I'll try that out and see how it works.

Thanks for the insights. I guess you can close this.

reply via email to

[Prev in Thread] Current Thread [Next in Thread]