diff options
| author | Lars Ingebrigtsen <larsi@gnus.org> | 2019-07-15 11:52:42 +0200 |
|---|---|---|
| committer | Lars Ingebrigtsen <larsi@gnus.org> | 2019-07-15 11:52:42 +0200 |
| commit | 4529057c97322893fb415512a2a51bc4616754f7 (patch) | |
| tree | 104c09b9cb03bfe49eb7b9fd0b2bad01ba77bfa9 /lisp/files.el | |
| parent | dbd1d2ebf868964fa5b2db5440ba27560846f95f (diff) | |
| download | emacs-4529057c97322893fb415512a2a51bc4616754f7.tar.gz | |
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.
Diffstat (limited to 'lisp/files.el')
| -rw-r--r-- | lisp/files.el | 39 |
1 files changed, 29 insertions, 10 deletions
diff --git a/lisp/files.el b/lisp/files.el index b2249bfcb48..f76b08f4cb7 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))))) |
