* doc/lispref/files.texi (Testing Accessibility): Document it.
* lisp/subr.el (with-existing-directory): New macro (bug#32004).
@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
\f
* 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
,@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))
\f
;;; Matching and match data.
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