EraEriksson created a simple library for keeping your DotEmacs simple by allowing you to divide it into a modular collection of files. It’s called my-site-start and can be downloaded from http://porkmail.org/elisp
By default it will recursively load all files and directories starting from ~/.emacs.d/site-start.d/ but this can easily be customized to use a different directory, not recurse, etc.
The library is just a simple framework for loading a modularized set of startup files. It does not include any functionality to actually create this modularized set of files.
As of 2009-02-05 this should be considered beta software. The author would appreciate any comments from users; please email ee are aye plus ee el eye es pea at eye kay eye dot ef eye.
Works well in my experience. It echoes Debian’s design for /etc/emacs/ - not sure which came first.
It’s theoretically neat to be able to activate a package for personal use just by symlinking its startup file into ~/.emacs.d/site-start.d/, but I don’t know of any package that uses this method of installing or which supports soft-linking correctly in its startup file. In order to set the load-path correctly even when visited thru a soft symlink, you can write:
(if load-file-name (add-to-list 'load-path (file-name-directory (file-truename load-file-name))))
For multi-file packages, there is unfortunately no convention to indicate to the user which file is the Right File to symlink.
Debian already included a method like the mentioned my-site-start: It’s called debian-run-directories defined in file /usr/share/emacs/site-lisp/debian-startup.el in package emacsen-common. So I put in my .emacs.d/init.el
(setq dotfiles-dir (file-name-directory (or load-file-name (buffer-file-name)))) (let ((user-site-start-dir (concat dotfiles-dir "/site-start.d"))) (debian-run-directories user-site-start-dir))
The follow defun returns a list of all directories under a specific directory tree:
(defun recursive-subdirs (directory &optional withroot) "Return a unsorted list of names of directories in DIRECTORY recursively. If WITHROOT is non-nil, also DIRECTORY will be include." (let (subdirs) (dolist (element (directory-files-and-attributes directory nil nil nil)) (let* ((path (car element)) (isdir (car (cdr element))) (ignore (or (string= path ".") (string= path "..")))) (if (and (eq isdir t) (not ignore)) (let ((dir (concat directory "/" path))) (setq subdirs (append (cons dir subdirs) (recursive-subdirs dir))))))) (if (not (eq withroot nil)) (add-to-list 'subdirs directory)) subdirs))
You can use this function in your InitFile file for reading all “.el” files like in this snippet:
(dolist (dir (recursive-subdirs "~/.emacs.d/config" t)) (dolist (file (directory-files dir t "\.el$" nil)) (load (file-name-sans-extension file))))
A faster alternative to RecursiveSubdirs is this function:
(defun load-directory (directory) "Load recursively all `.el' files in DIRECTORY." (dolist (element (directory-files-and-attributes directory nil nil nil)) (let* ((path (car element)) (fullpath (concat directory "/" path)) (isdir (car (cdr element))) (ignore-dir (or (string= path ".") (string= path "..")))) (cond ((and (eq isdir t) (not ignore-dir)) (load-directory fullpath)) ((and (eq isdir nil) (string= (substring path -3) ".el")) (load (file-name-sans-extension fullpath)))))))
and within InitFile:
$> tree .emacs.d/ .emacs.d/ |-- config/ | |-- completion.el | |-- control-version.el | |-- external-command-whole-buffer.el | |-- highligth-current-line.el | |-- modes/ | | |-- flymake-mode.el | | |-- markdown-mode.el | | |-- po-mode.el | | |-- programming/ | | | |-- c-mode.el | | | |-- css-mode.el | | | |-- global.el | | | |-- js-mode.el | | | |-- perl-mode.el | | | |-- php-mode.el | | | |-- python-mode.el | | | |-- sh-mode.el | | | `-- yasnippet.el | | |-- xml-mode.el | | `-- yaml-mode.el | |-- rename-frame.el | |-- revert-all-buffers.el | |-- sh.el | `-- windows.el `-- load-directory.el
$> cat ~/.emacs ... ;;; Load all ".el" files under ~/.emacs.d/config directory. (load "~/.emacs.d/load-directory") (load-directory "~/.emacs.d/config")
Making modular your config file. Info and source.