]> git.eshelyaron.com Git - emacs.git/commitdiff
Added file-tree-walk to files.el.
authorEric S. Raymond <esr@thyrsus.com>
Wed, 3 Dec 2014 14:28:09 +0000 (09:28 -0500)
committerEric S. Raymond <esr@thyrsus.com>
Wed, 3 Dec 2014 14:28:09 +0000 (09:28 -0500)
lisp/ChangeLog
lisp/files.el

index 10d48884b2ec2dd751df31d670d2a4781a703fb3..b79b918dc77228aa3fa12ac055a84b9b21e6c042 100644 (file)
@@ -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.
index c9d1d2da3b8db6661a7f2344598a19b87156ab64..720a633761a354cb9cb9998eebb910a263f01241 100644 (file)
@@ -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.