~.emacs

I have been using emacs for a while now. I would guess about five years. I would classify myself as a power user and not really a true emacs user. To be a ‘true’ emacs user you should at least be able to write elisp and generally hack emacs. Instead, I rely very heavily on existing elisp code and blogs. Of course, you can not mention emacs without pointing to http://emacswiki.org.

Writing about your dot emacs has become all the rage lately and I figured I would join in the fun. By writing about this I hope to do a few things;

  • filter out the junk in my dot emacs
  • get tips and/or ideas about what I can do better
  • finally get the motivation to write some elisp

The ~.emacs

(setq my-init-dir "~/.emacs.lisp"
      my-pkg-dir (concat my-init-dir "/pkg")
      my-site-dir (concat my-pkg-dir "/share/emacs/site-lisp"))
(load "~/.emacs.lisp/init.el")

And the ~/.emacs.lisp/init.el

(add-to-list 'load-path (expand-file-name "~/.emacs.lisp"))
(add-to-list 'load-path (expand-file-name (concat my-init-dir "/pkg")))
(load "safe-load")

(dolist (file  (reverse
                (mapcar 'file-name-sans-extension
                        (file-expand-wildcards
                         (concat my-init-dir "/conf[0-9][0-9].d/[a-z-]*.el")))))
  (safe-load (expand-file-name file)))

(safe-load "keys.el")

I can not recall where I got this idea from, but it has served me well so far. As any *nix user will note, this is inspired by the rc.d runlevel concept. I can have conf00.d to conf99.d as sub directories to the main .emacs.lisp directory. This allows for relatively easy control of ‘boot’ order of various modes,apps,etc…

I have only been bitten by the implicit boot order a couple of times. Currently, I only have 0-3 and I am just thinking about adding a 4.

One thing to note is the keys.el file is at the bottom, I wanted a single place to find all my global key bindings.

In later posts I will go over what is hiding in the conf00.d-conf03.d directories, but for now I will move on.

Here are some stats:

  • 36 elisp files
  • 854 loc
  • 73 packages

Packages

I have still not found a way to deal with packages well at all. As the stat above shows, I have 73 of something via ls -l|wc -l.

I decided to put all pkgs under ~/.emacs.lisp/pkg Normally I just grab a release tarbal and extract it there. Then have the elisp file under conf??.d add the path to the load-path list and its working. Sometimes I do grab a clone of a repos and dump it in there too.

This works out ok, except that when the pkg needs to ./configure the parameters can get quite hairy, keeping the ‘install’ under ~/.emacs.lisp/pkg is messy then.

DVCS

Of course I keep the entire ~/.emacs.lisp dir under hg, pushed to a remote server. This way I can pull onto my laptop or anyother random *nix and get my exact environment.

Does this work in practice? Not really.

Often times the ~/.emacs.lisp gets too far out of sync and I have to choose what to blow away. (I can be lazy with horrible merges.) Also having clones of other repos in ~/.emacs.lisp/pkg means I have to delete their .git or .hg and lose all of that info. (No I am not going to commit those dirs). Also, I get lazy and forget to commit and/or push and when I pull everything is ancient.

I like it, kind of

There are downsides to this method, finding where you configured something can be a pain, grep’ing files all the time does become tedious.

I would say it is a win so far. At least I have not discovered a better method for managing a huge emacs config.

Ideas welcome.

Comments (2)

  1. Aaron Culich wrote::

    I came across your post and thought I would offer a couple tips:

    1) The emacs manual talks about the init file and says this:

    “Emacs looks for your init file using the filenames `~/.emacs’, `~/.emacs.el’, or `~/.emacs.d/init.el’; you can choose to use any one of these three names.”

    So if you instead rename your ~/.emacs.lisp directory to ~/.emacs.d then you can get rid of your ~/.emacs file altogether and when emacs loads it will automatically read the ~/.emacs.d/init.el file.

    2) If you use tip #1 then it will automatically set user-emacs-directory to ~/.emacs.d which you can then add to your load-path since it doesn’t add it by default:

    (add-to-path ‘load-path user-emacs-directory)

    3) Now if you want to load the other .el files that may be in your load-path instead of using your rc.d-like system you can just use:

    (require ‘feature)

    presuming that those packages use:

    (provide ‘feature)

    By convention you’ll usually find that at the end of the .el file. Those files ought to require any dependencies they need, so it (usually) shouldn’t matter what order you have your requires in (thankfully modern rc.d systems like the ones found in debian use dependency based ordering as well!)

    The use of “require”, though, is kind of an atomic bomb when you usually only need a flyswatter, but it’s quick & simple.

    However, with a little more work it is better to use autoload instead. The advantage to autoload is that it will lazily load whatever you need when you need it, but it’s a little more work to set up. The advantage is that emacs will start faster because it doesn’t have to load in everything at once… however in practice that shouldn’t matter if you use (server-start) or daemon mode for emacs… you start emacs once and there is no reason to ever exit, right?

    Anyway, Luckily many packages are written with the following convention on function definitions intended to be called by the user:

    ;;;###autoload

    So that you can create a file called something like ~/.emacs.d/init-autoloads.el and then use:

    M-x generate-file-autoloads

    Which will prompt you for the file you want to scan for autoload hints. Then you can add something like this to your ~/.emacs.d/init.el file:

    (load “init-autoloads”)

    (I give the file a name like that because you don’t want it to accidentally have the name of another file on your load path like “autoload.el”).

    Note that many older packages on emacswiki do not use the ;;;###autoload convention, so you’ll have to add the autoloads by hand for those functions that don’t have it.

    4) My final tip for the day is to install the auto-install package from emacswiki which will then allow you to easily and quickly install any package from a variety of sources by using:

    M-x auto-install-from-{emacswiki,url,gist,dired,buffer,library,directory}

    (and it even has tab-completion for package names on emacswiki).

    5) And here is an excellent source for even more tips:

    http://www.masteringemacs.org/

    Tuesday, November 23, 2010 at 11:16 am #
  2. zion wrote::

    @aaron

    Thanks for all those tips. I had no idea about the ~/.emacs.d/init.el. I admit I was lazy way back when I learned emacs, saw an emacs.d and all the ‘crud’ that ended up there. Figured I better not mess with it until I know better and promptly forgot. Removing code is just elegant.

    On the ‘require bomb. Yes I hit that a while ago, started to migrate to autoloads. Then emacs –daemon showed up and I promptly became very lazy. You are right when you say that daemon removes the need for this I agree. I do like lazy loading though and do use eval-after-load a lot in my config files

    I was completely ignorant of auto-install! I tried elpa, but it confused me greatly.

    Thanks for all the tips. They are going in my .org file for something to do this weekend :)

    Thursday, November 25, 2010 at 12:31 am #