Чому я повинен додати кожен пакунок до завантажувального контуру? (або Проблема з пакувачем на вимогу в моєму файлі init)


17

Кожен раз, коли я встановлюю пакет з меню пакета, якщо я намагаюся requireйого в своєму файлі init, я отримую помилку, якщо я вручну не додаю його до шляху завантаження:

(add-to-list 'load-path "/home/nick/.emacs.d/elpa/use-package-20141220.1645")

(require 'use-package-autoloads)
(require 'use-package)

Це нудно. І зазвичай шлях пакета містить номери версій. Якщо пакет було оновлено, мені доведеться вручну редагувати шлях завантаження.

Чи є спосіб автоматизувати це?

Відповіді:


23

TL; DR:

Додайте наступний рядок у верхню частину файлу init ( .emacs.d/init.elабо .emacs):

(package-initialize)

Пояснення

Створення більшої кількості файлів, які Emacs може використовувати в якості user-init-file, безумовно, не є правильним підходом. Оскільки в посібнику не сказано, що є кращим у випадку виникнення конфлікту, принаймні, не в тій частині, яку ви цитували, все це вводить плутанину - тепер ми не знаємо, що насправді є user-init-file(чию цінність ви могли б хотіти оглянути, щоб дізнатися).

Тож почніть з видалення всіх кандидатів, за винятком тих, ~/.emacs.d/init.elщо, як правило, бажано (користувачами), оскільки це не сприяє нечестивому безладу, $HOMEі це дозволяє зберігати всі файли конфігурації Emacs, включаючи найважливіший, під контролем версій, використовуючи сховище тільки для Emacs

За замовчуванням Emacs дзвонить package-initialize після завантаження файлу init користувача. Він робить це на всіх , тому що в наш час більшість користувачів встановлюють свої пакети з допомогою package.el- тому вони не повинні робити нічого , щоб ці пакети повинні бути доступні.

З іншого боку , НЕ все робить, так що це повинно бути можливо НЕ назвати package-initialize. Запобігання виклику цієї функції здійснюється шляхом додавання (setq package-enable-at-startup nil)до файлу init користувача (куди б ви його могли розмістити?).

package-initializeне можна викликати, перш ніж користувач змінив, щоб сказати Emacs не робити цього, і це потрібно зробити після завантаження файлу init. Поки користувач встановлює лише пакети, а потім використовує їх як є або налаштовує їх за допомогою користувальницького інтерфейсу, який працює чудово. Але якщо ви хочете налаштувати ваші пакунки за допомогою elisp, тоді вам доведеться переконатися, що вони фактично перебувають load-pathраніше, ніж використовувати функції, які вони визначають.

Це досить легко зробити і правильно задокументувати (якби я переглянув це в першу чергу, мені б не довелося писати більшість із зазначеного вище: - /

Причина автоматичного завантаження пакета після завантаження файлу init полягає в тому, що користувацькі параметри отримують свої індивідуальні значення лише після завантаження файлу init, включаючи параметри користувача, які впливають на систему упаковки. За певних обставин, можливо, ви захочете явно завантажити пакунки у свій файл init (як правило, тому, що якийсь інший код у вашому файлі init залежить від пакета). У цьому випадку ваш файл init повинен викликати функцію package-initialize. Ви повинні переконатися, що відповідні параметри користувача, наприклад package-load-list(див. Нижче), будуть встановлені перед package-initializeвикликом. Ви повинні також встановити package-enable-at-startupвnil, щоб уникнути завантаження пакетів після обробки файлу init. Крім того, ви можете повністю призупинити завантаження пакета при запуску та застосувати команду `Mx package-Initialize ', щоб завантажити ваші пакунки вручну.

Так:

;;; .emacs.d/init.el -- the `user-init-file'

(package-initialize)
(setq package-enable-at-startup nil)

(require 'use-package)

(use-package some-package
  :init (setq some-package-variable "foobar")

    ...

;;; .emacs.d/init.el ends here

Звичайно, проблема (або додаткова проблема) також може полягати в тому, що помилка друку Symbol's function definition is void: use-packgeє у вашому файлі init, і вона не сталася, поки ви не ввели її в emacs.se.


1
Також покриті в stackoverflow.com/questions/11127109 / ...
Филс

Це добре використовувати (require 'use-package)раніше (package-initialize)?
陳 力

3

Я думаю, що after-init-hookрішення, вказане в цій відповіді про переповнення стека, слід згадати:

(defun my-packages-init ()
  (require 'some-great-package))

(add-hook 'after-init-hook 'my-packages-init)

Я думав, що це було так, як це слід було зробити, але інші відповіді дають інформацію про інші способи цього зробити.


0

Далі додано всі грі під, ~/.emacs.d/site-lispщоб завантажити шлях, так що ви можете просто requireпакет і ви готові:

(let* ((my-lisp-dir "~/.emacs.d/site-lisp/")
       (default-directory my-lisp-dir)
       (orig-load-path load-path))
  (setq load-path (cons my-lisp-dir nil))
  (normal-top-level-add-subdirs-to-load-path)
  (nconc load-path orig-load-path))
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.