gsl
gsl

Reputation: 1163

Faster Emacs directory walker

Walking a directory tree in Emacs using the cookbook recipe (http://www.emacswiki.org/emacs/ElispCookbook#toc59), or the solution at Walk up the directory tree is quite slow.

Could one use Unix's find instead, via shell-command or call-process, and perform a funcall on the returned list?

Is there any cons to that idea (perhaps too much memory consumption for large trees?), and what would be the idiomatic way to do that in elisp, ie calling find with some given arguments and mapping a funcall on the returned value?

One possible benefit I can see is that the shell process could be launched asynchronously, without Emacs stopping at all when the process is started.

Upvotes: 0

Views: 195

Answers (1)

Stefan
Stefan

Reputation: 28571

Yes, of course you can call find via call-process an then split the result line-by-line. Note that walk-path can be made significantly more efficient by the use of file-name-all-completions in place of directory-files and file-directory-p:

(defun my-walk-directory (dir action)
  "walk DIR executing ACTION with (dir file).
DIR needs to end with /."
  (dolist (file (let ((completion-ignored-extensions nil)
                      (completion-regexp-list nil))
                  (file-name-all-completions "" dir)))
    (cond
     ((member file '("./" "../")) nil)
     ((eq ?/ (aref file (1- (length file)))) (my-walk-directory (concat dir file) action))
     (t (funcall action dir file)))))

Of course, it's still not going to be as fast as find, but in my experience, this is about 10 times faster than using directory-files plus file-directory-p.

Upvotes: 1

Related Questions