Проблемы инициализации системы Emacs 24
Мне кажется, что новая система Package, встроенная в Emacs 24, имеет некоторые недостатки, когда дело доходит до правильной загрузки и инициализации установленных пакетов.
Недавно я обновился до Emacs 24.1.1, который был выпущен 6/10/2012, и я пытался использовать встроенную систему пакетов и установил несколько пакетов, используя ее, но у всех них есть похожая проблема, связанная с автозагрузкой и инициализация.
Например, я использую пакет под названием smex
который обеспечивает улучшения для использования M-x
аккорд. Требуется определить ключ для M-x
вот я и добавил (global-set-key (kbd "M-x") 'smex)
в моем init.el
файл. Но после запуска Emacs я нажимаю M-x
Аккорд и я получаю сообщение "Определение функции символа недействительно: Smex"... Если я также поставил (require 'smex)
в моем файле init.el я получаю сообщение об ошибке "Ошибка файла: не удается открыть загрузочный файл, smex"
Добавление местоположения smex в переменную load-path делает его работающим, как и ожидалось, однако это, похоже, сводит на нет всю цель иметь систему пакетов в первую очередь...
Какие-нибудь мысли? Есть ли лучший способ или мы пока живем с этим ограничением?
2 ответа
Пакеты, которые вы устанавливаете с package.el
активируются по умолчанию после вашего .emacs
загружен. Чтобы иметь возможность использовать их до конца вашего .emacs
вам нужно активировать их с помощью команд:
(setq package-enable-at-startup nil)
(package-initialize)
Стоит отметить, почему Emacs откладывает инициализацию пакета:
Смотри Chяг (emacs) Package Installation
RET, и в частности:
Причина, по которой автоматическая загрузка пакета происходит после загрузки файла инициализации, заключается в том, что пользовательские параметры получают свои настроенные значения только после загрузки файла инициализации, включая пользовательские параметры, которые влияют на систему упаковки. В некоторых случаях вы можете явно загружать пакеты в ваш файл инициализации (обычно потому, что какой-то другой код в вашем файле инициализации зависит от пакета). В этом случае ваш файл инициализации должен вызывать функцию
package-initialize
, Это зависит от вас, чтобы убедиться, что соответствующие параметры пользователя, такие какpackage-load-list
(см. ниже), устанавливаются доpackage-initialize
вызов. Вы также должны установитьpackage-enable-at-startup
вnil
, чтобы избежать повторной загрузки пакетов после обработки файла инициализации. В качестве альтернативы вы можете полностью запретить загрузку пакетов при запуске и вызвать командуM-x package-initialize
загрузить ваши пакеты вручную.
Таким образом, при условии, что вы убедитесь, что ваш файл инициализации заботится о любых значениях не по умолчанию, которые вы хотите для переменных в package
группа настройки1 перед вызовом package-initialize
- и что вы поддерживаете этот подход всякий раз, когда настраиваете конфигурацию библиотеки пакетов - все должно быть в порядке.
В качестве альтернативы, потому что after-init-hook
запускается после завершения стандартной инициализации пакета, вы можете использовать это для оценки любого кода инициализации, который зависит от пакетов. Так что вместо звонка package-initialize
прямо в init.el, вы могли бы вместо этого написать:
(add-hook 'after-init-hook 'my-after-init-hook)
(defun my-after-init-hook ()
;; do things after package initialization
)
поместить код, требующий инициализированной системы пакетов, в эту функцию.
YMMV.
(Примечание: я не тестировал подход после инициализации, так как на самом деле я не использую package.el; но я подтвердил последовательность событий в коде запуска, поэтому я считаю, что он будет работать так, как описано.)
1 мкс customize-group
RET package
RET