summaryrefslogtreecommitdiff
path: root/lisp/files.el
diff options
context:
space:
mode:
authorLars Ingebrigtsen <larsi@gnus.org>2019-07-26 17:03:42 +0200
committerLars Ingebrigtsen <larsi@gnus.org>2019-07-27 12:16:51 +0200
commit0779b1c31d27c348f6f2a94c5aa1a64de855a39d (patch)
treef4d3a1ef72a03c3afa56e3f076a3a4216c7538d6 /lisp/files.el
parent2cc5bb67ffde05384dfb4b7c24ea3e4255205390 (diff)
downloademacs-0779b1c31d27c348f6f2a94c5aa1a64de855a39d.tar.gz
Allow directory-files-recursively to follow symlinks
* doc/lispref/files.texi (Contents of Directories): Document it. * lisp/files.el (directory-files-recursively): Allow following symlinks.
Diffstat (limited to 'lisp/files.el')
-rw-r--r--lisp/files.el23
1 files changed, 15 insertions, 8 deletions
diff --git a/lisp/files.el b/lisp/files.el
index 81ca948bd2d..184421f54f2 100644
--- a/lisp/files.el
+++ b/lisp/files.el
@@ -813,7 +813,8 @@ The path separator is colon in GNU and GNU-like systems."
(error "No such directory found via CDPATH environment variable"))))
(defun directory-files-recursively (dir regexp
- &optional include-directories predicate)
+ &optional include-directories predicate
+ follow-symlinks)
"Return list of all files under DIR that have file names matching REGEXP.
This function works recursively. Files are returned in \"depth
first\" order, and files from each directory are sorted in
@@ -827,7 +828,10 @@ PREDICATE can be either nil (which means that all subdirectories
are descended into), t (which means that subdirectories that
can't be read are ignored), or a function (which is called with
name name of the subdirectory and should return non-nil if the
-subdirectory is to be descended into)."
+subdirectory is to be descended into).
+
+If FOLLOW-SYMLINKS, symbolic links that point to directories are
+followed. Note that this can lead to infinite recursion."
(let* ((result nil)
(files nil)
(dir (directory-file-name dir))
@@ -841,19 +845,22 @@ subdirectory is to be descended into)."
(let* ((leaf (substring file 0 (1- (length file))))
(full-file (concat dir "/" leaf)))
;; Don't follow symlinks to other directories.
- (when (and (not (file-symlink-p full-file))
+ (when (and (or (not (file-symlink-p full-file))
+ (and (file-symlink-p full-file)
+ follow-symlinks))
;; Allow filtering subdirectories.
(or (eq predicate nil)
(eq predicate t)
(funcall predicate full-file)))
(let ((sub-files
(if (eq predicate t)
- (condition-case _
- (directory-files-recursively
- full-file regexp include-directories)
- (file-error nil))
+ (ignore-error file-error
+ (directory-files-recursively
+ full-file regexp include-directories
+ predicate follow-symlinks))
(directory-files-recursively
- full-file regexp include-directories))))
+ full-file regexp include-directories
+ predicate follow-symlinks))))
(setq result (nconc result sub-files))))
(when (and include-directories
(string-match regexp leaf))