Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
254 views
in Technique[技术] by (71.8m points)

Emacs 24 Package System Initialization Problems

It seems to me that the new Package system that is built-in on Emacs 24 has some flaws when it comes to properly loading and initializing the installed packages.

Recently, I upgraded to Emacs 24.1.1 which was realeased on 6/10/2012 and I have been trying to use the built-in package system and have installed several packages using it, but they all have a similar problem related to autoload and initialization.

For example, I use a package called smex which provides enhancements for using the M-x chord. It requires you to define a key for M-x, so I added (global-set-key (kbd "M-x") 'smex) in my init.el file. But after starting emacs I press the M-x chord and I get the message "Symbol's function definition is void: smex" ... If I also put (require 'smex) in my init.el file I get the error message "File error: Cannot open load file, smex"

Adding the location of smex to the load-path variable makes it work as expected, however, that seems to defeat the whole purpose of having a package system in the first place...

Any thoughts? Is there a better way or do we live with this limitation for now?

Question&Answers:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

It's worth noting why Emacs defers the package initialization:

See C-hig (emacs) Package Installation RET, and in particular:

The reason automatic package loading occurs after loading the init file is that user options only receive their customized values after loading the init file, including user options which affect the packaging system. In some circumstances, you may want to load packages explicitly in your init file (usually because some other code in your init file depends on a package). In that case, your init file should call the function package-initialize. It is up to you to ensure that relevant user options, such as package-load-list (see below), are set up prior to the package-initialize call. You should also set package-enable-at-startup to nil, to avoid loading the packages again after processing the init file. Alternatively, you may choose to completely inhibit package loading at startup, and invoke the command M-x package-initialize to load your packages manually.

So provided you make sure that your init file takes care of any non-default values you want for variables in the package customization group1 before calling package-initialize -- and that you maintain this approach whenever customizing the package library config -- it should be okay to do this.

Alternatively, because after-init-hook runs after the standard package initialization has completed, you could use that to evaluate any init code which depends upon packages. So instead of calling package-initialize directly in init.el, you could instead write:

(add-hook 'after-init-hook 'my-after-init-hook)
(defun my-after-init-hook ()
  ;; do things after package initialization
  )

putting the code requiring the initialized package system within that function.

YMMV.

(n.b. I haven't tested the after-init approach, as I don't really use package.el; but I did confirm the sequence of events in the start-up code, so I believe it will work as described.)

1 M-x customize-group RET package RET


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...