[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