]> git.eshelyaron.com Git - emacs.git/commitdiff
Add new macro `with-existing-directory'
authorLars Ingebrigtsen <larsi@gnus.org>
Wed, 1 Sep 2021 10:13:19 +0000 (12:13 +0200)
committerLars Ingebrigtsen <larsi@gnus.org>
Wed, 1 Sep 2021 13:56:04 +0000 (15:56 +0200)
* doc/lispref/files.texi (Testing Accessibility): Document it.
* lisp/subr.el (with-existing-directory): New macro (bug#32004).

doc/lispref/files.texi
etc/NEWS
lisp/subr.el
test/lisp/subr-tests.el

index 266501d46d0f3c9c6b4203622593609e0841677a..d1045704527e3636b2d4af74630bd0a063530674 100644 (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
index 0e1edd648d0a4175040ec475661787421a5ac56b..6f6b8e108fee3e20aec75dbce93bfa91fc67d2a6 100644 (file)
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -3422,6 +3422,11 @@ The former is now declared obsolete.
 \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
index 0a31ef2b29f6846f808ed2f17c8474d669196b26..7426dcce50f48b9c75718cca9166ffca9cf0e066 100644 (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))
 \f
 ;;; Matching and match data.
 
index 21b8a27858e009a649bcf38588411e8faf7f1172..c1f8225ec8a80f306042c5a9174d17bb106e60e4 100644 (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