aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLars Ingebrigtsen2019-07-26 17:03:42 +0200
committerLars Ingebrigtsen2019-07-27 12:16:51 +0200
commit0779b1c31d27c348f6f2a94c5aa1a64de855a39d (patch)
treef4d3a1ef72a03c3afa56e3f076a3a4216c7538d6
parent2cc5bb67ffde05384dfb4b7c24ea3e4255205390 (diff)
downloademacs-0779b1c31d27c348f6f2a94c5aa1a64de855a39d.tar.gz
emacs-0779b1c31d27c348f6f2a94c5aa1a64de855a39d.zip
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.
-rw-r--r--doc/lispref/files.texi5
-rw-r--r--etc/NEWS4
-rw-r--r--lisp/files.el23
3 files changed, 22 insertions, 10 deletions
diff --git a/doc/lispref/files.texi b/doc/lispref/files.texi
index 0ea8a4f0a19..6be5a528372 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
2919that can be read. 2919that can be read.
2920@end defun 2920@end defun
2921 2921
2922@defun directory-files-recursively directory regexp &optional include-directories predicate 2922@defun directory-files-recursively directory regexp &optional include-directories predicate follow-symlinks
2923Return all files under @var{directory} whose names match @var{regexp}. 2923Return all files under @var{directory} whose names match @var{regexp}.
2924This function searches the specified @var{directory} and its 2924This function searches the specified @var{directory} and its
2925sub-directories, recursively, for files whose basenames (i.e., without 2925sub-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
2940neither @code{nil} nor @code{t}, it should be a function that takes 2940neither @code{nil} nor @code{t}, it should be a function that takes
2941one parameter (the subdirectory name) and should return non-@code{nil} 2941one parameter (the subdirectory name) and should return non-@code{nil}
2942if the directory is to be descended into. 2942if the directory is to be descended into.
2943
2944Symbolic links to subdirectories are not followed by default, but if
2945@var{follow-symlinks} is non-@code{nil}, they are followed.
2943@end defun 2946@end defun
2944 2947
2945@defun directory-files-and-attributes directory &optional full-name match-regexp nosort id-format 2948@defun directory-files-and-attributes directory &optional full-name match-regexp nosort id-format
diff --git a/etc/NEWS b/etc/NEWS
index 348b2124e66..021e84c9a43 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -2407,7 +2407,9 @@ the Emacs Lisp manual.
2407 2407
2408+++ 2408+++
2409** `directory-files-recursively' can now take an optional PREDICATE 2409** `directory-files-recursively' can now take an optional PREDICATE
2410parameter to control descending into subdirectories. 2410parameter to control descending into subdirectories, and a
2411FOLLOW-SYMLINK parameter to say that symbolic links that point to
2412other directories should be followed.
2411 2413
2412 2414
2413* Changes in Emacs 27.1 on Non-Free Operating Systems 2415* Changes in Emacs 27.1 on Non-Free Operating Systems
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."
813 (error "No such directory found via CDPATH environment variable")))) 813 (error "No such directory found via CDPATH environment variable"))))
814 814
815(defun directory-files-recursively (dir regexp 815(defun directory-files-recursively (dir regexp
816 &optional include-directories predicate) 816 &optional include-directories predicate
817 follow-symlinks)
817 "Return list of all files under DIR that have file names matching REGEXP. 818 "Return list of all files under DIR that have file names matching REGEXP.
818This function works recursively. Files are returned in \"depth 819This function works recursively. Files are returned in \"depth
819first\" order, and files from each directory are sorted in 820first\" order, and files from each directory are sorted in
@@ -827,7 +828,10 @@ PREDICATE can be either nil (which means that all subdirectories
827are descended into), t (which means that subdirectories that 828are descended into), t (which means that subdirectories that
828can't be read are ignored), or a function (which is called with 829can't be read are ignored), or a function (which is called with
829name name of the subdirectory and should return non-nil if the 830name name of the subdirectory and should return non-nil if the
830subdirectory is to be descended into)." 831subdirectory is to be descended into).
832
833If FOLLOW-SYMLINKS, symbolic links that point to directories are
834followed. Note that this can lead to infinite recursion."
831 (let* ((result nil) 835 (let* ((result nil)
832 (files nil) 836 (files nil)
833 (dir (directory-file-name dir)) 837 (dir (directory-file-name dir))
@@ -841,19 +845,22 @@ subdirectory is to be descended into)."
841 (let* ((leaf (substring file 0 (1- (length file)))) 845 (let* ((leaf (substring file 0 (1- (length file))))
842 (full-file (concat dir "/" leaf))) 846 (full-file (concat dir "/" leaf)))
843 ;; Don't follow symlinks to other directories. 847 ;; Don't follow symlinks to other directories.
844 (when (and (not (file-symlink-p full-file)) 848 (when (and (or (not (file-symlink-p full-file))
849 (and (file-symlink-p full-file)
850 follow-symlinks))
845 ;; Allow filtering subdirectories. 851 ;; Allow filtering subdirectories.
846 (or (eq predicate nil) 852 (or (eq predicate nil)
847 (eq predicate t) 853 (eq predicate t)
848 (funcall predicate full-file))) 854 (funcall predicate full-file)))
849 (let ((sub-files 855 (let ((sub-files
850 (if (eq predicate t) 856 (if (eq predicate t)
851 (condition-case _ 857 (ignore-error file-error
852 (directory-files-recursively 858 (directory-files-recursively
853 full-file regexp include-directories) 859 full-file regexp include-directories
854 (file-error nil)) 860 predicate follow-symlinks))
855 (directory-files-recursively 861 (directory-files-recursively
856 full-file regexp include-directories)))) 862 full-file regexp include-directories
863 predicate follow-symlinks))))
857 (setq result (nconc result sub-files)))) 864 (setq result (nconc result sub-files))))
858 (when (and include-directories 865 (when (and include-directories
859 (string-match regexp leaf)) 866 (string-match regexp leaf))