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

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

bug#66187: read-file-name unexpected behavior when MUSTMATCH is a functi


From: Michael Heerdegen
Subject: bug#66187: read-file-name unexpected behavior when MUSTMATCH is a function
Date: Mon, 25 Sep 2023 23:33:06 +0200
User-agent: Gnus/5.13 (Gnus v5.13)

Joseph Turner <joseph@breatheoutbreathe.in> writes:

> (mkdir "/tmp/foo" t)
> (with-temp-buffer
>   (write-file "/tmp/foo/bar"))
> (setq default-directory "/tmp/foo/")
> (read-file-name "Clone into new or empty directory: " nil nil
>                 (lambda (filename)
>                   (or (not (file-exists-p filename))
>                       (directory-empty-p filename)))
>                 nil
>                 (lambda (filename)
>                   (file-directory-p filename)))
>
> The default prompt is "/tmp/foo/". In my Emacs (29.0.92), when I
> immediately press RET, read-file-name (erroneously?) returns "/tmp/foo/"
> (which exists and is not empty) instead of saying "[Match required]".
>
> Are you able to reproduce this on your machine?

Yes, I see the same.  But I think it's expected.  AFAIU the algorithm
works like this: first it's checked whether a completion is allowed (by
checking whether it's the name of an existing file and consulting
PREDICATE when specified).  Only when it is not allowed we check whether
MUSTMATCH declares it acceptable.

This is not really explained in the docstring, however.

In your example, the default-directory is the name of an existing file,
so the MUSTMATCH argument is irrelevant, the specified PREDICATE is
fulfilled, so it's accepted as input.

If I guess correctly I think you want something like this:

#+begin_src emacs-lisp
(let ((acceptable-p (lambda (filename)
                      (and (file-directory-p filename)
                           (directory-empty-p filename)))))
  (read-file-name "Clone into new or empty directory: " nil nil
                  (lambda (filename)
                    (if (file-exists-p filename)
                        (funcall acceptable-p filename)
                      t))
                  nil
                  acceptable-p))
#+end_src

Does that come close?


Michael.





reply via email to

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