[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Emacs-diffs] master 4529057: Make directory-files-recursively take a PR
From: |
Lars Ingebrigtsen |
Subject: |
[Emacs-diffs] master 4529057: Make directory-files-recursively take a PREDICATE parameter |
Date: |
Mon, 15 Jul 2019 05:54:16 -0400 (EDT) |
branch: master
commit 4529057c97322893fb415512a2a51bc4616754f7
Author: Lars Ingebrigtsen <address@hidden>
Commit: Lars Ingebrigtsen <address@hidden>
Make directory-files-recursively take a PREDICATE parameter
* lisp/files.el (directory-files-recursively): Take an optional
PREDICATE parameter (bug#28567).
* doc/lispref/files.texi (Contents of Directories): Document it.
---
doc/lispref/files.texi | 9 ++++++++-
etc/NEWS | 4 ++++
lisp/files.el | 39 +++++++++++++++++++++++++++++----------
3 files changed, 41 insertions(+), 11 deletions(-)
diff --git a/doc/lispref/files.texi b/doc/lispref/files.texi
index 66678d3..0519f78 100644
--- a/doc/lispref/files.texi
+++ b/doc/lispref/files.texi
@@ -2911,7 +2911,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
+@defun directory-files-recursively directory regexp &optional
include-directories predicate
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
@@ -2925,6 +2925,13 @@ alphabetically by their basenames. By default,
directories whose
names match @var{regexp} are omitted from the list, but if the
optional argument @var{include-directories} is non-@code{nil}, they
are included.
+
+By default, all subdirectories are descended into. If @var{predicate}
+is @code{t}, errors when trying to descend into a subdirectory (for
+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.
@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 97143d2..edba159 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -2326,6 +2326,10 @@ zero-padding, upper- and lower-casing, and limiting the
length of the
interpolated strings. The function has now also been documented in
the Emacs Lisp manual.
++++
+** `directory-files-recursively' can now take an optional PREDICATE
+parameter to control descending into subdirectories.
+
* Changes in Emacs 27.1 on Non-Free Operating Systems
diff --git a/lisp/files.el b/lisp/files.el
index b2249bf..f76b08f 100644
--- a/lisp/files.el
+++ b/lisp/files.el
@@ -812,13 +812,22 @@ The path separator is colon in GNU and GNU-like systems."
(lambda (f) (and (file-directory-p f) 'dir-ok)))
(error "No such directory found via CDPATH environment variable"))))
-(defun directory-files-recursively (dir regexp &optional include-directories)
+(defun directory-files-recursively (dir regexp
+ &optional include-directories
predicate)
"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 alphabetical order.
-Each file name appears in the returned list in its absolute form.
-Optional argument INCLUDE-DIRECTORIES non-nil means also include in the
-output directories whose names match REGEXP."
+This function works recursively. Files are returned in \"depth
+first\" order, and files from each directory are sorted in
+alphabetical order. Each file name appears in the returned list
+in its absolute form.
+
+Optional argument INCLUDE-DIRECTORIES non-nil means also include
+in the output directories whose names match REGEXP.
+
+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)."
(let* ((result nil)
(files nil)
(dir (directory-file-name dir))
@@ -832,10 +841,20 @@ output directories whose names match REGEXP."
(let* ((leaf (substring file 0 (1- (length file))))
(full-file (concat dir "/" leaf)))
;; Don't follow symlinks to other directories.
- (unless (file-symlink-p full-file)
- (setq result
- (nconc result (directory-files-recursively
- full-file regexp include-directories))))
+ (when (and (not (file-symlink-p full-file))
+ ;; 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))
+ (directory-files-recursively
+ full-file regexp include-directories))))
+ (setq result (nconc result sub-files))))
(when (and include-directories
(string-match regexp leaf))
(setq result (nconc result (list full-file)))))
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Emacs-diffs] master 4529057: Make directory-files-recursively take a PREDICATE parameter,
Lars Ingebrigtsen <=