Subject: bug#34794: 26.1; doc of `read-buffer'

From: Drew Adams <[email-masked]>
Date: Sun, 10 Mar 2019 15:23:05 -0700 (PDT)

> I used some ideas from your suggestion.

Thanks.  Do you have a URL to the updated doc?

> > 4. There appears to be a fairly large bug in the
> > behavior, BTW.  The function is supposed to return a
> > buffer name, which is presumably a string.
> >
> > But try this, hitting `RET' with empty minibuffer input:
> >  (read-buffer "b: " (selected-window) t)
> > That returns a window!  And this returns a number, not
> > a numeric string: (read-buffer "b: " 42 t)
> > It apparently can return anything at all.
> 
> AFAICT, it just behaves according to documentation of DEF.
> 
> > This is in spite of the fact that the REQUIRE-MATCH
> > arg is `t', and according to the doc that should
> > mean that you cannot exit the minibuffer unless the
> > input corresponds to an existing buffer.
> 
> That's only valid for something the user types, AFAIU.

Yes, you're right about that.  "`t' means that the user
is not allowed to exit unless the input is (or completes
to) an element of COLLECTION __or is null__."  I forgot
about that last part.

> > Do you prefer a separate bug report for this bug, or
> > can you fix it based on this report?
> 
> I don't really see what is there to fix.

I guess not.  I would have thought that a DEF that
isn't a buffer name - or at least a string - might
helpfully raise an error.

Let me see what other `read-*' functions do...

`read-string', `read-passwd', and `read-regexps' act
the same way: the DEFAULT(S) arg can be anything
at all, and it is returned as is upon empty input.
`read-string' doesn'tt necessarily return a string,
and so on.

Not great, I'd say.  But at least `read-buffer' is
not alone in such behavior.

And I suppose there is some code somewhere that even
takes advantage of such a "feature" somehow...

I'm happy, however, to see that at least some `read-*'
commands do raise an error if the DEFAULT arg is not
a string or nil.

`read-command', for example, raises an error if DEF
is not a string (it doesn't require a command name,
but that test is better than nothing):

Hitting RET with no input here:
 (read-command "Command: " (selected-window))
raises
 wrong-type-argument stringp #<window 136 on *Help*>

Same thing for `read-number', though at least that
tests for the expected type:
 (read-number "Number: " (selected-window))
 wrong-type-argument numberp #<window 8 on *Help*>)

`read-face-name' raises an error even before trying
to read!  It doesn't wait for input:

 (read-face-name "Face: " (selected-window))
 wrong-type-argument listp #<window 136 on *Help*>

BTW, `read-from-minibuffer' with non-nil READ arg
and with DEFAULT-VALUE not a string or nil ends
with an `End of file during parsing error':

Hitting RET with no input here:
 (read-from-minibuffer "Input: " nil nil t nil
                       (selected-window))

DEFAULT-VALUE of course "should be a string", but
if it's not the error message is not as helpful
as it could be.  There's nothing to be done about
this one, however, I guess.  Perhaps it could spit
out the thing it was passed as DEFAULT-VALUE, to
let you know what `read' choked on.  

`read-input-method-name' seems a bit problematic
when passed a non-string, non-nil DEFAULT-VALUE arg.
It tries to insert it into the prompt's "%s", which
ends in an error such as 
 wrong-type-argument sequencep #<window 8 on *Help*>)

`read-language-name' raises a similar error:
wrong-type-argument sequencep #<window 8 on *Help*>)

There isn't much consistency in these `read-*'
functions wrt their handling of the DEFAULT arg.
IMO at least some of them might be made better by
testing whether that arg is of the proper type and
raising a (somewhat relevant) error if not.