emacs-diffs
[Top][All Lists]
Advanced

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

[Emacs-diffs] master 0779b1c: Allow directory-files-recursively to follo


From: Lars Ingebrigtsen
Subject: [Emacs-diffs] master 0779b1c: Allow directory-files-recursively to follow symlinks
Date: Sat, 27 Jul 2019 06:17:12 -0400 (EDT)

branch: master
commit 0779b1c31d27c348f6f2a94c5aa1a64de855a39d
Author: Lars Ingebrigtsen <address@hidden>
Commit: Lars Ingebrigtsen <address@hidden>

    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.
---
 doc/lispref/files.texi |  5 ++++-
 etc/NEWS               |  4 +++-
 lisp/files.el          | 23 +++++++++++++++--------
 3 files changed, 22 insertions(+), 10 deletions(-)

diff --git a/doc/lispref/files.texi b/doc/lispref/files.texi
index 0ea8a4f..6be5a52 100644
--- a/doc/lispref/files.texi
+++ b/doc/lispref/files.texi
@@ -2919,7 +2919,7 @@ An error is signaled if @var{directory} is not the name 
of a directory
 that can be read.
 @end defun
 
-@defun directory-files-recursively directory regexp &optional 
include-directories predicate
+@defun directory-files-recursively directory regexp &optional 
include-directories predicate follow-symlinks
 Return all files under @var{directory} whose names match @var{regexp}.
 This function searches the specified @var{directory} and its
 sub-directories, recursively, for files whose basenames (i.e., without
@@ -2940,6 +2940,9 @@ instance, if it's not readable by this user) are ignored. 
 If it's
 neither @code{nil} nor @code{t}, it should be a function that takes
 one parameter (the subdirectory name) and should return non-@code{nil}
 if the directory is to be descended into.
+
+Symbolic links to subdirectories are not followed by default, but if
+@var{follow-symlinks} is non-@code{nil}, they are followed.
 @end defun
 
 @defun directory-files-and-attributes directory &optional full-name 
match-regexp nosort id-format
diff --git a/etc/NEWS b/etc/NEWS
index 348b212..021e84c 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -2407,7 +2407,9 @@ the Emacs Lisp manual.
 
 +++
 ** `directory-files-recursively' can now take an optional PREDICATE
-parameter to control descending into subdirectories.
+parameter to control descending into subdirectories, and a
+FOLLOW-SYMLINK parameter to say that symbolic links that point to
+other directories should be followed.
 
 
 * Changes in Emacs 27.1 on Non-Free Operating Systems
diff --git a/lisp/files.el b/lisp/files.el
index 81ca948..184421f 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))



reply via email to

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