emacs-diffs
[Top][All Lists]
Advanced

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

master 6a6de68 1/3: Add new macro `with-existing-directory'


From: Lars Ingebrigtsen
Subject: master 6a6de68 1/3: Add new macro `with-existing-directory'
Date: Wed, 1 Sep 2021 10:27:16 -0400 (EDT)

branch: master
commit 6a6de68dafd27238577e92a7a79e97f3f1a6e381
Author: Lars Ingebrigtsen <larsi@gnus.org>
Commit: Lars Ingebrigtsen <larsi@gnus.org>

    Add new macro `with-existing-directory'
    
    * doc/lispref/files.texi (Testing Accessibility): Document it.
    * lisp/subr.el (with-existing-directory): New macro (bug#32004).
---
 doc/lispref/files.texi  | 10 ++++++++++
 etc/NEWS                |  5 +++++
 lisp/subr.el            | 13 +++++++++++++
 test/lisp/subr-tests.el |  8 ++++++++
 4 files changed, 36 insertions(+)

diff --git a/doc/lispref/files.texi b/doc/lispref/files.texi
index 266501d..d104570 100644
--- a/doc/lispref/files.texi
+++ b/doc/lispref/files.texi
@@ -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
diff --git a/etc/NEWS b/etc/NEWS
index 0e1edd6..6f6b8e1 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -3423,6 +3423,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
 result.
diff --git a/lisp/subr.el b/lisp/subr.el
index 0a31ef2..7426dcc 100644
--- a/lisp/subr.el
+++ b/lisp/subr.el
@@ -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.
 
diff --git a/test/lisp/subr-tests.el b/test/lisp/subr-tests.el
index 21b8a27..c1f8225 100644
--- a/test/lisp/subr-tests.el
+++ b/test/lisp/subr-tests.el
@@ -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



reply via email to

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