5

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?

Community
  • 1
  • 1
Léo Léopold Hertz 준영
  • 134,464
  • 179
  • 445
  • 697

3 Answers3

9

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))
  (normal-top-level-add-subdirs-to-load-path)
  (nconc load-path orig-load-path))
Community
  • 1
  • 1
Nicholas Riley
  • 43,532
  • 6
  • 101
  • 124
  • @Nicholas: Why do you use the star? – Léo Léopold Hertz 준영 Apr 27 '09 at 00:17
  • 2
    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 00:42
  • 1
    To see what directories are excluded, run C-h f normal-top-level-add-subdirs-to-load-path. – Nicholas Riley Apr 27 '09 at 00:43
  • @Nicholas: How can you see what is inside the functions such as the one in you last comment? – Léo Léopold Hertz 준영 Apr 27 '09 at 00:51
  • 1
    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 03:34
  • -1: it puts default libs AFTER the custorm ones. So that if You install `Icicles` or `Sunrise Commander` - many of it's keys got shadowed by emacs's core `simple.el`, `window.el` and so on. – Adobe Mar 07 '12 at 10:05
1

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)))
Robert P. Goldman
  • 860
  • 1
  • 8
  • 16
0

Simple answer:

 (normal-top-level-add-subdirs-to-load-path)
user347585
  • 101
  • 1