Проблемы инициализации системы 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

Другие вопросы по тегам