Add new macro `with-existing-directory'

* doc/lispref/files.texi (Testing Accessibility): Document it.
* lisp/subr.el (with-existing-directory): New macro (bug#32004).
This commit is contained in:
Lars Ingebrigtsen 2021-09-01 12:13:19 +02:00
parent a15f549a57
commit 6a6de68daf
4 changed files with 36 additions and 0 deletions

View file

@ -936,6 +936,16 @@ file in @file{/foo/} will give an error:
@end example
@end defun
@defmac with-existing-directory body@dots{}
This macro ensures that @code{default-directory} is bound to an
existing directory before executing @var{body}. If
@code{default-directory} already exists, that's preferred, and
otherwise some other directory is used. This macro can be useful, for
instance, when calling an external command that requires that it's
running in a directory that exists. The chosen directory is not
guaranteed to be writable.
@end defmac
@defun access-file filename string
If you can read @var{filename} this function returns @code{nil};
otherwise it signals an error

View file

@ -3422,6 +3422,11 @@ The former is now declared obsolete.
* Lisp Changes in Emacs 28.1
+++
*** New macro 'with-existing-directory'.
This macro binds 'default-directory' to some other existing directory
if 'default-directory' doesn't exist, and then executes the body forms.
+++
*** New function 'file-name-concat'.
This appends file name components to a directory name and returns the

View file

@ -4593,6 +4593,19 @@ MODES is as for `set-default-file-modes'."
,@body)
(set-default-file-modes ,umask)))))
(defmacro with-existing-directory (&rest body)
"Execute BODY with `default-directory' bound to an existing directory.
If `default-directory' is already an existing directory, it's not changed."
(declare (indent 0) (debug t))
`(let ((default-directory (seq-find (lambda (dir)
(and dir
(file-exists-p dir)))
(list default-directory
(expand-file-name "~/")
(getenv "TMPDIR")
"/tmp/")
"/")))
,@body))
;;; Matching and match data.

View file

@ -740,5 +740,13 @@ See https://debbugs.gnu.org/cgi/bugreport.cgi?bug=19350."
1))
(should (equal (buffer-string) "new bar zot foobar"))))
(ert-deftest test-with-existing-directory ()
(let ((dir (make-temp-name "/tmp/not-exist-")))
(let ((default-directory dir))
(should-not (file-exists-p default-directory)))
(with-existing-directory
(should-not (equal dir default-directory))
(should (file-exists-p default-directory)))))
(provide 'subr-tests)
;;; subr-tests.el ends here