onsdag, maj 21, 2008

How large is your .emacs?

I've been reading lots of blogs and opinions about emacs the last few days. What strikes me is all of these people who brag about how large their .emacs files have become. So let me make this very clear:

If your .emacs file is longer than a page YOU ARE DOING IT WRONG.

Why? Well. Unless you are a casual Emacs user, your .emacs should not be regarded as a configuration file. Rather, the .emacs file is actually the entry point to the source repository of your own version of Emacs. In effect, when you configure Emacs you create a fork, which has it's own source that you need to maintain. This is not configuration. This is programming and you should approach it like you do all programming. What does that mean? Modularization. Clean code. Code comments. Source control. Tests. But modularization and source control are the ones that are most important for my Emacs configuration. I have loads of files in ~/emacs and every kind of extension I do has it's own kind of file or directory to put it in. The ~/emacs directory is checked out from source control, and has got customizations for different platforms. That's why my .emacs file is 4-5 lines long. Two for setting customizations that are specific to this computer, and the rest to load the stuff inside of ~/emacs. And that's all.

So how do you handle modularization of Emacs Lisp code? This won't be a tutorial. Just a few advices that might make things easier.

In no specific order:
  • (load "file.el") will allow you to just load another file.
  • (require 'cl) will give you lots of nice functionality from Common Lisp
  • I recommend you have one place where you add all your load paths. Mine look something like this:
    (labels ((add-path (p)
    (add-to-list 'load-path
    (concat emacs-root p))))
    (add-path "emacs/jde/lisp")
    (add-path "emacs/nxml")
    (add-path "emacs/own") ;; Personal elisp code
    (add-path "emacs/lisp") ;; Various elisp code, just dumped here
    )
  • Why do it like this? Well, it gives you an easier way to add full paths to your load path without repeating lots of stuff. This depends on you defining emacs-root somewhere - do define it, it can be highly useful.
  • Set custom-file. (The custom-file is the file where Emacs saves customizations. If you don't set a specific file for this, you will end up getting all customizations saved into .emacs which you really don't want.) The code for this is simple. Just do (setq custom-file "the-file-name.el")
  • Use hooks and advice liberally. They allow you to attach new functionality without monkey patching.
  • If you ever edit XML, NEVER use Emacs builtin XML editor. Instead download the excellent NXML package.
  • Learn how to use Info and customizations
  • Use Ido mode
Feel free to add other good advice in the comments. These were just a small smattering of stuff I like and which helps your environment quite seriously. But the most important part is the whole thing about keeping your .emacs extremely small!

Addendum: As Phil just pointed out (and which was part of my plan from the beginning) is that Autoloads should be used as much as possible. Also, make sure to bytecompile as much as possible.

4 kommentarer:

Phil sa...

I think when people brag about the size of their .emacs they really are talking about their whole emacs directory, not necessarily a single file. But yeah, any project like that belongs in version control! (http://github.com/technomancy/dotfiles)

One thing you didn't mention is autoloads. I find them to be really handy, especially since Emacs can generate autoload definitions for you automatically. I have a snippet in my .emacs to automatically regenerate my autoloads if the autoload definitions file is older than a couple weeks:

http://paste.lisp.org/display/61089

Jim Menard sa...

http://www.io.com/~jimm/emacs_tips.html#my-dot-emacs explains what I do, which is very similar to Ola's method. Not only do I have machine-specific customization, optional before and after files get loaded around the main config file.

piyo sa...

I totally agree with this post. "when you configure Emacs you create a fork", that's a good one.

But who uses .emacs for the startup these days? It should be .emacs.d/init.el. So version control that directory. You can even junction/symlink that directory from some other place.

Mainly, I separate code that creates new functionality from the actual activation of that code.

My setup is pretty much just like yours, except I don't put my load-path redefs in one place, because I reuse the subdirs.el and add-load-path-subdirs functionality. How about using mapc instead of typing add-path over and over again?

I put my input (keyredefs and macros, mouse settings) in one file as well. I have a macro library that does my key defines with less typing and it keeps redefinition history dynamically, not that I ever use that.

I type too much.
defadvice: yes
flet: yes
customize: yes
org tables: yes

Anonym sa...

Your description of a modular Emacs finally inspired me to clean up my config. I've created a screencast of it here: http://weblog.hypotheticalabs.com/?p=265.

It deals only with configuring Emacs to work with Erlang's emacs mode and setting up flymake, but I think it illustrates the concepts you described.