views:

356

answers:

6

I've decided to rewrite my .emacs from the ground up, and I want to setup something that's modular, in order to avoid a dreaded 1k+ LoC init.el file...

I think there are some basic concerns that each configuration needs to address :

  • global options
  • editing functions
  • navigation (frames & buffers)
  • keybindings
  • modes customizations

While I'm still tying to think the structure through, I'm looking for some pointers on how to achieve this.
I've looked at some .emacs on github and such, and there seems to be deifferent approaches, and no preferred way to go with this, which is a bit confusing.
I would be interested in reading some ideas regarding how to structure such a setup, and especially some related elisp code.


edit : Been caught up with things, and haven't had much time to play with this yet. Will try out the proposed methods in a few days, and see what's best, meanwhile thanks for all the recommendations !


edit2 : I've been using a literate init file with org-mode, and this is absolutely terrific !
I 'm not yet set on a specific load mechanism, I've been using this code, to recursively load my elisp directory, then require or whatever the setup instructions say.

  (if (fboundp 'normal-top-level-add-subdirs-to-load-path)
  (let* ((my-lisp-dir "~/.emacs.d/elisp/")
  (default-directory my-lisp-dir))
  (setq load-path (cons my-lisp-dir load-path))
  (normal-top-level-add-subdirs-to-load-path)))

I still need to polish this, maybe using autoload, and some byte-recompile if modified tricks ; would love to hear suggestions on that.

A: 

What's wrong with using load-file?

Some additional bits you might find useful include

  • file-exists-p
  • file-expand-wildcards

Use C-h f <function> to get help, and you might find An Introduction to Programming in Emacs Lisp useful (or download the PDF)

dmckee
+6  A: 

My .emacs file loads ~/.emacs.d/init.el, which defines the following functions, written first for XEmacs, but working well enough for Emacs these days:

(defconst user-init-dir
  (cond ((boundp 'user-emacs-directory)
         user-emacs-directory)
        ((boundp 'user-init-directory)
         user-init-directory)
        (t "~/.emacs.d/")))


(defun load-user-file (file)
  (interactive "f")
  "Load a file in current user's configuration directory"
  (load-file (expand-file-name file user-init-dir)))

Then the rest of the file goes and loads lots of individual files with forms like this:

(load-user-file "personal.el")

My current set of files is as follows:

  • personal.el
  • platform.el
  • cygwin.el
  • variables.el
  • paths.el
  • mail-news.el
  • misc-funcs.el
  • bbdb.el
  • calendar.el
  • gnus-funcs.el
  • c-and-java.el
  • lisp.el
  • clojure.el
  • sgml-xml.el
  • tex.el
  • spelling.el
  • org.el
  • packages.el
  • fonts.el
  • frame.el
  • server.el
  • keys.el

Some of them are much more specific in intent than others, as the names suggest. The more fine-grained the files, the easier it is to disable a cluster of forms when you're reinstalling a package or library. This is especially useful when "moving in" to a new system, where you drag your configuration files over but don't yet have all the supporting packages installed.

seh
Just what I was aiming at. Nice.
dmckee
That is why I tend to have the supporting packages tucked away somewhere in my .emacs folder.
klynch
A: 

What I have done is for each thing, X, that I might want to use, create a file called configure-X, and put a corresponding require in .emacs. This feature can then be removed by commenting out one line.

For example, to pick the simplest (if most poorly-named), I have configure-picture-and-artist-mode.el. This file is very simple:

(global-set-key (kbd "C-M-P")
                'picture-mode)

(provide 'configure-picture-and-artist-mode)

And in .emacs:

(require 'configure-picture-and-artist-mode)

After sorting this out I don't have anything in my .emacs except for a big list of requires and a few changes to load-path, a given package can be removed quite easily, and all the configuration for each package is in one place.

(I've also got a catch-all .el file that I use to store things that don't have any obvious home (my global keybindings, helper functions, etc.) but still ideally want to stay out of .emacs. This bit isn't very modular, and may introduce implicit dependencies on packages that my scheme is supposed to make unloadable easily, but in practice it doesn't seem to be a big deal.)

brone
Can you share more of how you coax 'require' to find the files that contain the 'provide' forms? Do you specify a file name for `require`'s second argument?
seh
@seh you don't need to as long as the 'provided' file is in the load-path. I could have a file foo.el, within which I have (provide 'foo) or (provide 'foobar) or whatever, then in my init file I can say (require 'foo) (or foobar or whatever) and it'll load the file.
vedang
I named each file after the symbol provided, made sure the containing folder is in load-path... and it just worked. (I'm not sure of the detailed ins and outs of this mechanism, but I suspect that require just knows to try to load a file named after the symbol if no loaded file has already provided the requested symbol. Anyway this is just what I'd noticed other elisp files doing, so I copied it.)
brone
Thanks. I'm going to experiment with setting this up in my own configuration files today.
seh
+1  A: 

You can do (require 'foo) and that will load the first "foo.el" elisp finds in your load path, or (require 'foo "/home/user/experimental/foo.el") for something outside your load path. It will report an error if "foo.el" does not contain the expression (provide 'foo). In a perverse situation you could do (require 'foo "bar.el"), and this would work as long as "bar.el" had a (provide 'foo) clause.

Justin Smith
+1  A: 

Have a look at the excellent emacs starter kit which is very nicely organised and also includes ELPA packages. I used the structure as inspiration for my own much simpler setup.

justinhj
A: 

To split customizations into different files, you can use initsplit.el. Also, the wiki has a page on modular .emacs layout.

Joe Casadonte