An Optimal .emacs File

I recently stumbled across this old post from Nickel's Worth on optimizing your .emacs file. It's from 2009 so it is, in some parts, dated but it still contains a lot of good ideas.

To me, the most controversial piece of advice is to avoid using load or require in your .emacs. I'll let you read the post for the reasons for that but I will say that the suggestion is not without merit.

Another idea that solves a problem I seem to keep having is to use eval-after-load so that you can set various package-configuration variables without loading the package. For example, you might have the autoloaded package foo that requires that you configure the foo-blah1 and foo-blah2 variables. The way to do that is

(eval-after-load "foo"
  '(progn
    (setq foo-blah1 "some string")
    (setq foo-blah2 "some other string")))

That way, the setting of the foo-blah1 and foo-blah2 variables is not executed until the package is actually loaded so you won't get a void-variable error. This suggestion alone makes the post worth reading.

This is a short post so there's no reason not to give it a look. You may get some ideas that hadn't occurred to you before.

This entry was posted in General and tagged . Bookmark the permalink.
  • Anonymous Coward

    > so you won't get void-variable error

    This is incorrect. The setq form will never fail to assign a value to a variable (unless the evaluated expression has an error), so it does not need to be wrapped in an eval-after-load. In addition, the defvar form assigns an initial value which is only given to the variable when it is unset. Therefore it is perfectly safe to set your variables with setq before they are defined by defvar, and they will retain the values you set them to.

    I still agree that you should put your setqs in your eval-after-loads (to not clutter the namespace until the package is loaded). But sometimes in poorly written packages (e.g. glasses) the way the package is loaded depends on variables assigned before it was loaded (glasses-*-separator).

    • http://irreal.org jcs

      Good point. I was actually thinking of things like

      (add-to-list 'foo-list "something")

      where you the object does need to exist. I got bitten by that several times when I first started using ELPA.

      Also a good point about some packages loading differently depending on the existing environment. I hadn't thought about that.

  • http://lamattgrind.tumblr.com Matthew Darling

    I've been trying to move towards John Wiegley's use-package in my own configuration. I'm not sure if it solves the same problem, because I'm still fairly new to all of this, but he seems to have been pretty thorough in the options provided.

    • Josh Tolle

      It does solve that problem, and because it delays loading the specified packages until they are used, it fosters a fully customized Emacs startup time that rivals that of vanilla Emacs startup.

  • http://www.puercopop.com PuercoPop

    One question, is there a performance difference between autoload and load/require? If so, Why?

    • Spacebat

      Autoload is an optimisation that allows a function to be registered as a stub, that when called causes all the of the code the function depends on to be loaded, including the function itself which replaces the stub, and then the function is called.

      Reading these stubs can be much, much faster at emacs init time than loading and parsing and running all the initialisation code for every module you may end up wanting to load. However these days its not as important for those who run emacs as an editing daemon and connect to it with emacsclient.

      I have an /etc/init.d/emacs service that starts emacs at system boot time.

  • http://www.puercopop.com PuercoPop

    Btw, I've found a better way to measure the startup time. Apparently Emacs measures it for you, you only need to display it. Adapting it from here I've arrived to this

    (add-hook 'after-init-hook (lambda ()
    (growl-notify-notification "Emacs Startup" (format "The init sequence took %g seconds." (float-time (time-subtract after-init-time before-init-time)))))

    • http://irreal.org jcs

      Or just call emacs-init-time.

      • http://www.puercopop.com PuercoPop

        Nice!