ELPA With Emacs 24

I just installed Emacs 24 and, as expected, everything went very well except for the package system, ELPA. I don't have very many packages that I load with ELPA so at least the number of problems were limited.

First, following Xah Lee's Guide on Emacs 24 Package System page, I moved the old ~/.emacs.d/elpa directory out of the way and then reloaded my packages. The first problem is that you need to replace the

     (expand-file-name "~/.emacs.d/elpa/package.el"))


(require 'package)

After that change I was able to add Marmalade to the list of package sites.

The next problem was that when I restarted Emacs, I got an error saying it couldn't load smex, one of the packages that I load with ELPA. Everything seemed OK: smex was loaded onto my machine and seemed fine. The bit of Elisp in init.el was what the documentation said it should be but I couldn't get it to load from init.el. I went searching on the Web and after a few useless links I found this page on Emacs 24 Package System Problems, again from Xah Lee. In order to get things to work you have to add an explicit load path for some of the packages (smex, magit, dired+, and key-chord for me). My first pass at this was to add commands to explicitly add the load paths:

(add-to-list 'load-path "~/.emacs.d/elpa/smex-1.1.2/") ; XXX Emacs bug
(require 'smex)
(global-set-key (kbd "M-x") 'smex)

This is annoying because the path will have to be changed when I upgrade. It's doubly annoying because ELPA worked just fine without having to do this in Emacs 23. Rather than keep dealing with this every time I upgrade one of the problem packages, I added

(defconst elpa-loads '("smex" "magit" "dired" "key-chord"))
(mapc (lambda (p) (if (file-directory-p p) (add-to-list 'load-path p)))
      (directory-files "~/.emacs.d/elpa" t
                       (concat "^\\("
                               (mapconcat 'identity elpa-loads "\\|")

to my init.el. With that change, the only maintenance required is to add any new problem packages to elpa-loads.

The Emacs 24 ELPA problem appears, from some of the other links I looked at, to be that Emacs 24 deals with the ELPA packages after it has finished processing the .emacs or init.el file and, therefore the .emacs or init.el file knows nothing about the packages. That means you can't set package variables because they haven't been loaded yet. As far as I could find out, the only solution is to load the files with require and that requires that there be a path to the .el or .elc files.

Doubtless, this will all be resolved soon so I'm not overly exercised about it. Now that I have things working again, it's time to explore the new Emacs 24 and see how it improves my life.

Update: Added explicit check for directory when setting paths.

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

    Couldn't you solve the problem with "eval-after-load" to ensure that your package-specific code is loaded after the package it depends on?

    • jcs

      Perhaps. It looks like it should work. I'll try it out when I get a chance and update the post if that solves the problem.

      • jcs

        I tried eval-after-load but it didn't work for me. Emacs still complained that it couldn't load the module.

  • Does adding `(package-initialize)` at the top of your init.el fix the problem?

    Based on the before and after snippets, it looks like it got removed.

    • Philipp

      This was exactly my thought. I faced the same issue with my packages and it seems that `package-initialize` is the function that sets the load-path for each installed package correctly. It should be called right after the other sites have been added.

  • Foo

    Seth Mason is exactly right. You are just missing (package-initialize). Package does not load any of the packages installed until this command has been run or at the end of loading your .emacs.

  • Foo

    And (require 'package) is not needed.

  • jcs

    Thanks guys. Your comments help a lot. I did read the documentation for package and it made it seem as if using (package-initialize) might have undesirable side effects. I'm going to disable all my other stuff and see if adding (package-initialize makes things work.

    Philipp, are you saying I should do the requires (or whatever) for the non-ELPA packages and then (package-initialize) and finally the configurations?

    • Foo

      Do immediately when you start a (package-initialize) so that all your load path are set. Then you can use require since emacs knows the load paths. You can also do any configuration at that point.

      The important thing is to do package-initialize at the beginning.

    • FWIW, I'm using (package-initialize) at the top (along with smex, magit, etc.) and haven't seen any problems.

      YMMV. :)