Function: directory-files-recursively
directory-files-recursively is a byte-compiled function defined in
files.el.gz.
Signature
(directory-files-recursively DIR REGEXP &optional INCLUDE-DIRECTORIES PREDICATE FOLLOW-SYMLINKS)
Documentation
Return list of all files under directory DIR 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.
By default, the returned list excludes directories, but if optional argument INCLUDE-DIRECTORIES is non-nil, they are included.
PREDICATE can be either nil (which means that all subdirectories of DIR are descended into), t (which means that subdirectories that can't be read are ignored), or a function (which is called with the name of each subdirectory, and should return non-nil if the subdirectory is to be descended into).
If FOLLOW-SYMLINKS is non-nil, symbolic links that point to directories are followed. Note that this can lead to infinite recursion.
Other relevant functions are documented in the file group.
Probably introduced at or before Emacs version 25.1.
Shortdoc
;; file
(directory-files-recursively "/tmp/" "\\.png\\'")
e.g. => ("/tmp/foo.png" "/tmp/zot.png" "/tmp/bar/foobar.png")
Source Code
;; Defined in /usr/src/emacs/lisp/files.el.gz
(defun directory-files-recursively (dir regexp
&optional include-directories predicate
follow-symlinks)
"Return list of all files under directory DIR 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.
By default, the returned list excludes directories, but if
optional argument INCLUDE-DIRECTORIES is non-nil, they are
included.
PREDICATE can be either nil (which means that all subdirectories
of DIR are descended into), t (which means that subdirectories that
can't be read are ignored), or a function (which is called with
the name of each subdirectory, and should return non-nil if the
subdirectory is to be descended into).
If FOLLOW-SYMLINKS is non-nil, 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))
;; When DIR is "/", remote file names like "/method:" could
;; also be offered. We shall suppress them.
(tramp-mode (and tramp-mode (file-remote-p (expand-file-name dir)))))
(dolist (file (sort (file-name-all-completions "" dir)
'string<))
(unless (member file '("./" "../"))
(if (directory-name-p file)
(let* ((leaf (substring file 0 (1- (length file))))
(full-file (concat dir "/" leaf)))
;; Don't follow symlinks to other directories.
(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)
(ignore-error file-error
(directory-files-recursively
full-file regexp include-directories
predicate follow-symlinks))
(directory-files-recursively
full-file regexp include-directories
predicate follow-symlinks))))
(setq result (nconc result sub-files))))
(when (and include-directories
(string-match regexp leaf))
(setq result (nconc result (list full-file)))))
(when (string-match regexp file)
(push (concat dir "/" file) files)))))
(nconc result (nreverse files))))