summaryrefslogtreecommitdiff
path: root/lisp
diff options
context:
space:
mode:
authorEric S. Raymond <esr@thyrsus.com>2014-12-03 09:28:09 -0500
committerEric S. Raymond <esr@thyrsus.com>2014-12-03 09:28:09 -0500
commite820f16c06a5a6be4bc87910b349c7c3c6eca0f4 (patch)
tree87e1f6bcbb2dcc53136d5a858fe4d33f9da41800 /lisp
parenteb608f9ef2d018191d614bac5cd247d998b6fdfb (diff)
downloademacs-e820f16c06a5a6be4bc87910b349c7c3c6eca0f4.tar.gz
Added file-tree-walk to files.el.
Diffstat (limited to 'lisp')
-rw-r--r--lisp/ChangeLog4
-rw-r--r--lisp/files.el26
2 files changed, 30 insertions, 0 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 10d48884b2e..b79b918dc77 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,7 @@
+2014-12-03 Eric S. Raymond <esr@snark.thyrsus.com>
+
+ * files.el (file-tree-walk): Lisp translation of ANSI ftw(3).
+
2014-12-02 Glenn Morris <rgm@gnu.org>
* whitespace.el (whitespace-big-indent-regexp): Add :version.
diff --git a/lisp/files.el b/lisp/files.el
index c9d1d2da3b8..720a633761a 100644
--- a/lisp/files.el
+++ b/lisp/files.el
@@ -729,6 +729,32 @@ 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 file-tree-walk (dir action &rest args)
+ "Walk DIR executing ACTION. Each call gets as arguments DIR, a file path,
+and optional ARGS. The ACTION is applied to each subdirectory
+before descending into it, and if nil is returned at that point
+the descent will be prevented. Directory entries are sorted with
+string-lessp"
+ (cond ((file-directory-p dir)
+ (or (char-equal ?/ (aref dir (1- (length dir))))
+ (setq dir (file-name-as-directory dir)))
+ (let ((lst (directory-files dir nil nil t))
+ fullname file)
+ (while lst
+ (setq file (car lst))
+ (setq lst (cdr lst))
+ (cond ((member file '("." "..")))
+ (t
+ (and (apply action dir file args)
+ (setq fullname (concat dir file))
+ (file-directory-p fullname)
+ (apply 'file-tree-walk fullname action args)))))))
+ (t
+ (apply action
+ (file-name-directory dir)
+ (file-name-nondirectory dir)
+ args))))
+
(defun load-file (file)
"Load the Lisp file named FILE."
;; This is a case where .elc makes a lot of sense.