Sunday, April 17, 2011

Emacs Lisp: How to add a folder and all its first level sub-folders to the load-path

If I have a folder structure set up like this:

~/Projects
    emacs
        package1
            package1-helpers
        package2
            package2-helpers
            package2-more-helpers
        package3
            package3-helpers

How do I add these folders:

  • ~/Projects/emacs
  • ~/Projects/emacs/package1
  • ~/Projects/emacs/package2
  • ~/Projects/emacs/package3

...to the load-path from my .emacs file?

I basically need a short automated version of this code:

(add-to-list 'load-path "~/Projects/emacs")
(add-to-list 'load-path "~/Projects/emacs/package1")
(add-to-list 'load-path "~/Projects/emacs/package2")
(add-to-list 'load-path "~/Projects/emacs/package3")
From stackoverflow
  • (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)))))
    
    Alexander Kojevnikov : Thanks Jouni! Unfortunately I receive an error: "An error has occurred while loading `c:/Users/Alex/AppData/Roaming/.emacs': Symbol's function definition is void: do". I have Emacs 22.2.1 running under Vista.
    Jouni K. Seppänen : Oops - "do" is in cl.el, so you can make the original suggestion work by adding "(require cl)" in the beginning. But I modified the answer to use dolist, which both makes it simpler and avoids the need for cl.el.
    Alexander Kojevnikov : Works as a charm, many thanks!
  • I suggest you to use subdirs.el

    Alexander Kojevnikov : That's good to know, thanks!
  • Here's something I use in my .emacs:

    (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))
    

    If you look at the description for normal-top-level-add-subdirs-to-load-path, it's somewhat smart about picking which directories to exclude.

    Masi : Note that this code also include subdirectories at /.elisp.
  • This is my hacked up version :P

    (defun add-to-list-with-subdirs (base exclude-list include-list)
      (dolist (f (directory-files base))
     (let ((name (concat base "/" f)))
       (when (and (file-directory-p name)
         (not (member f exclude-list)))
      (add-to-list 'load-path name)
      (when (member f include-list)
       (add-to-list-with-subdirs name exclude-list include-list)))))
      (add-to-list 'load-path base))
    

    This will add all first level dirs from base and exclude the ones in exclude-list, while for the dirs in include-list, it will add all the first level dirs of that dir too.

    (add-to-list-with-subdirs "~/.emacs.d" '("." ".." "backup") '("vendor" "my-lisp"))
    

0 comments:

Post a Comment