Subject: Re: bug#78926: 30.1; find-file-read-only require-match inconsistency

From: Thierry Volpiatto <[email-masked]>
Date: Thu, 03 Jul 2025 04:16:53 +0000

Eli Zaretskii <[email-masked]> writes:

> severity 78926 wishlist
> thanks
>
>> From: Thierry Volpiatto <[email-masked]>
>> Cc: Thierry Volpiatto <[email-masked]>,  [email-masked]
>> Date: Tue, 01 Jul 2025 17:32:55 +0000
>> 
>> Start emacs -Q, say you have a directory ~/tmp/ containing foo.txt and
>> bar.txt.
>> 
>> 1) C-x C-r ~/tmp/test.txt RET
>> => find-file--read-only: ~/tmp/foo.txt does not exist
>> 
>> 2) C-x C-r ~/tmp/*.txt RET
>> => Two buffer are opened foo.txt and bar.txt.
>> 
>> That's fine for 1) but I would prefer a [no match] preventing exiting the
>> minibuffer.
>
> find-file and friends are specially programmed not to do that, because
> otherwise creating new files, a very frequent operation, would be too
> annoying.

find-file and variants yes, but not find-file-read-only which is
programmed to not create new file, this is why I took this example.
Having the ability to use for one completing-read three options for
REQUIRE-MATCH instead of only two is what I would like to intoduce.  The
way find-file-read-only is implemented currently is because this feature
is missing.

> So I think this is a reasonable behavior.

>> For 2) I had expected a [confirm] before maybe blocking emacs by opening
>> too many buffers.
>
> We have find-file-wildcards to control this.  AFAIU, you would like to
> extend that variable to accept an integer value, which means visit
> only up to that number of files, otherwise ask for confirmation.

It is not what I want, but yes it is a good idea.

> Patches welcome.
>
>> Now (setq confirm-nonexistent-file-or-buffer 'confirm)
>> 
>> And repeat 1) and 2).
>> As you can see in both case we have a minibuffer-message [confirm].
>> 
>> In 1) I think it is confusing, I had expected instead a [no match].
>
> Not sure why.  "No match" comes from completion, whereas "confirm"
> comes from the coder that is controlled by the variable you
> customized.  Not sure why you prefer "no match", since it's much more
> general and therefore potentially confusing,

It is not confusing, it just prevent exiting with a not existing file
whereas the current code allows exiting and then send an error once done
which is confusing, but IIUC it has been implemented this way to provide
at the same time confirm-nonexistent-file-or-buffer and prevent creating
a new file, I am sure the author of this code would have used the
feature I propose if available.

> especially for non-native English speakers.
>
>> In 2) [confirm] is nice because it may prevent opening hundred of buffer
>> and blocking emacs.
>
> I'd argue that it might be a bug.  Why ask for confirmation in this
> case?

Because it is better than nothing (note that it is the intention of the
current code, why it uses confirm-nonexistent-file-or-buffer in first
place and error on second place), of course something like your
proposition of improving find-file-wildcards is better, also it is a
good example showing the need of the feature I propose which could be used
in more places:

    (defun completion--complete-and-exit (beg end
                                              exit-function completion-function)
      "Exit from `require-match' minibuffer.
    COMPLETION-FUNCTION is called if the current buffer's content does not
    appear to be a match."
      (cond
       ;; Allow user to specify null string
       ((= beg end) (funcall exit-function))
       ;; The REQUIRE-MATCH argument is a function.
       ((functionp minibuffer-completion-confirm)
        (pcase (funcall minibuffer-completion-confirm
                        (buffer-substring beg end))
          ((and confirm (or 'confirm 'confirm-after-completion))
           (setq minibuffer-completion-confirm confirm)
           (completion--complete-and-exit
            beg end exit-function completion-function))
          ((pred (eq nil))
           (unless completion-fail-discreetly
    	 (ding)
    	 (completion--message "No match")))
          (_ (funcall exit-function))))
          [...]

>> So what I think would be the best is having [no match] in 1) and
>> [confirm] in 2), however with the tools we have under hand you can't
>> implement this, this is why find-file-read-only allow to have [confirm]
>> in 2) but must use some code exiting with error in 1), you can't
>> implement both, it is one or the other.
>> 
>> By patching completion--complete-and-exit (see the two patches I sent)
>> you can allow the REQUIRE-MATCH arg of completing read using a function
>> that can exit with three option: nil, non-nil or confirm whereas with
>> the current code you can exit with nil or non-nil only.
>> 
>> And then you can make find-file-read-only prevent exiting with a non
>> existing file in 1), And confirm a wildcard in 2).
>> 
>> Is this more clear?
>
> Yes, thanks.
>
>> Note:
>> As you can see this is an enhancement there is no bug, the current
>> behavior is not so nice but it is ok, we can live with it.
>
> Agree.
>
>> Thanks for reading and sorry for beeing unclear, it is not easy to
>> explain non trivial things in english.
>
> No need to be sorry, and thanks.
>

-- 
Thierry