Elisp: Walk Directory

By Xah Lee. Date: . Last updated: .

Here's how to walk directory.

List Directory

(directory-files DIRECTORY &optional FULL MATCH NOSORT)
Return a list of names of files in DIRECTORY. If FULL is non-nil, return absolute file names. If MATCH is non-nil, only return matched files. If NOSORT is non-nil, the list is not sorted, order is unpredictable.
;; walk dir

(mapc
 (lambda (x) (insert x "\n"))
 (directory-files "/Users/x/em/emacs/i" nil "\.jpg$" t))

;; sample output

;; ztn_emacs_pinky_wedge_2018-02-24.jpg
;; xah_lee_photo_2018-06-28.jpg
;; xah-fly-keys_kinesis_2017-09_60363.jpg
;; the_book_of_shen_lang.jpg
;; sun_type_6_keyboard_meta_compose_altgraph_keys.jpg

[see Elisp: Regex Tutorial]

List Directory and All Subdir

(directory-files-recursively DIR REGEXP &optional INCLUDE-DIRECTORIES)
Return list of all files under DIR and all its subdir that have file names matching REGEXP. (note, the match is done against file name only, not full path.) Returned list elements are full path. Optional argument INCLUDE-DIRECTORIES non-nil means also include in the output directories whose names match REGEXP.
;; walk dir and all subdir

(mapc (lambda (x) (insert x "\n"))
      (directory-files-recursively "/Users/x/em/" "\.jpg$" ))

;; sample output

;; /Users/x/em/emacs/i/Apple_G4_iBook_Snow_Euro_layout_keyboard_62224.jpg
;; /Users/x/em/emacs/i/Apple_iBook_G4_Snow_77735.jpg
;; /Users/x/em/misc/i/typing_of_the_dead_36588.jpg
;; /Users/x/em/misc/i/vim_fitness.jpg
;; /Users/x/em/tn/emacs/emacs_logo/emacs_logo_large.jpg
;; /Users/x/em/tn/emacs/i/unicode/Carbon_emacs_22_unicode.jpg

Skipping Subdir

In other programing languages (perl python golang), usually the dir walker lets you skip some specified directory. The walker calls a doFile function you write, and pass current dir or file, so you can skip it to prevent going into.

In elisp, there's a package find-lisp.el that lets you use a regex to filter dir, but is very slow. I do not recommend it. [Elisp: find-lisp.el]

To skip some subdir, it's faster if you just use directory-files-recursively then filter result.

(setq
 skipDirs
 [
  "ergoemacs_org/emacs_manual/"
  "xahlee_info/REC-SVG11-20110816/"
  "xahlee_info/clojure-doc-1.8/"
  "xahlee_info/js_es2016/"
  "xahlee_info/python_doc_3.3.3/"
  ])

(seq-filter
 (lambda (path)
   (not (seq-some
         (lambda (x) (string-match x path))
         skipDirs )))
 (directory-files-recursively "/Users/xah/web/xahlee_info/" "\\.svg$" ))

seq-filter and seq-some are in emacs 25.

[see Elisp: Sequence Functions]

If you have a question, put $5 at patreon and message me on xah discord.
Or support me by Buy Xah Emacs Tutorial

Emacs Tutorial

Emacs Init

Emacs Keys

ELisp

ELisp Examples

ELisp Write Major Mode


ELisp

Basics

Basic Functions

Writing Command

Writing Script

Lisp Data Structure

Lisp Symbol

Elisp Misc