Take the 2-minute tour ×

The question is similar to one.

However, it differs in putting all subdirectories achievable in the folder too.

Jouni's code which puts first level folders achievable

(let ((base "~/Projects/emacs"))
  (add-to-list 'load-path base)
  (dolist (f (directory-files base))
    (let ((name (concat base "/" f)))
      (when (and (file-directory-p name) 
                 (not (equal f ".."))
                 (not (equal f ".")))
        (add-to-list 'load-path name)))))

How can you put a directory and all its subdirectories to load-path in Emacs?

share|improve this question
add comment

3 Answers

up vote 8 down vote accepted

My answer in the other question does handle multiple levels of subdirectories.

The code for reference

(let* ((my-lisp-dir "~/.elisp/")
       (default-directory my-lisp-dir)
       (orig-load-path load-path))
  (setq load-path (cons my-lisp-dir nil))
  (nconc load-path orig-load-path))
share|improve this answer
@Nicholas: Thank you for pointing that out! –  Masi Apr 27 '09 at 0:14
I am rather new in Lisp. What does let* mean in your code? –  Masi Apr 27 '09 at 0:17
let* is shorthand for many nested lets, each of which binds a single variable; regular old let binds all the variables at once. So, with let instead of let*, I could not refer to my-lisp-dir in the binding for default-directory because it would not be available until the body of the let. –  Nicholas Riley Apr 27 '09 at 0:42
To see what directories are excluded, run C-h f normal-top-level-add-subdirs-to-load-path. –  Nicholas Riley Apr 27 '09 at 0:43
If you click on "startup.el" in the help window, you'll go to the function's definition (assuming it's written in elisp, not C.) –  Nicholas Riley Apr 27 '09 at 3:34
show 5 more comments

Here's an adaptation of Jouni's answer that uses a helper function that you can tailor.

One advantage of the helper function is that you can trace it when it does something unexpected, because it's a pure function, so doesn't side-effect into your load-path. I tried using the normal-top-level-add-subdirs-to-load-path, but everything in it is so side-effecting and dependent on unpredictable special variables, that it was just easier to write something fresh that was clean. Note that my answer does not use inodes, so may be less efficient.

A second advantage of this approach is that it lets you tailor what files you would like to ignore.

(defun add-to-load-path-with-subdirs (directory &optional endp)
  (let ((newdirs (lp-subdir-list directory)))
    (if endp (setq load-path (append load-path newdirs))
      (setq load-path (nconc newdirs load-path)))))

(defconst +lp-ignore-list+
  (list "CVS" ".git" ".svn" ".." "."))

(defun lp-subdir-list (base &optional ignore)
  (unless ignore
    (setq ignore +lp-ignore-list+))
  (let ((pending (list base))
 (retval nil))
    (while pending
      (let ((dir (pop pending)))
 (push dir retval)
 (dolist (f (directory-files dir))
   (let ((name (concat dir "/" f)))
     (when (and (not (member f ignore))
         (file-directory-p name))
       (push name pending)
       (push name retval))))))
    (reverse retval)))
share|improve this answer
add comment

Simple answer:

share|improve this answer
add comment

Your Answer


