Использование package.el для установки и обновления, но использование package для загрузки и настройки

15

После недавнего изучения use-packageя решил портировать свою конфигурацию на него, но обнаружил, что не хочу отказываться от удобства использования package.elдля установки пакетов и их обновления. Я нашел это немного сложным для объединения use-packageи package.el.

Мне, как правило, интересно узнать, как люди объединяются use-packageс package.elсистемой, но для более конкретного вопроса продолжайте читать.

Вот что я хочу:

  1. Чтобы пакеты были установлены менеджером пакетов, чтобы я мог легко просматривать пакеты и постоянно обновлять их list-packages.
  2. Настраивать и загружать пакеты исключительно через use-package, чтобы я мог легко видеть в моем файле инициализации, что именно я загружаю и как он настроен.
  3. По желанию, я хотел бы также иметь возможность установить пакеты через use-package«s :ensureключевое слово.

Если я правильно понимаю, я хочу очень мало того, что package-initializeделает, в основном только то, как это настраивает load-path. В настоящее время у меня есть это в моей конфигурации:

;(package-initialize)
(setq package-enable-at-startup nil)
(let ((default-directory "~/.emacs.d/elpa"))
  (normal-top-level-add-subdirs-to-load-path))
(require 'use-package)

Первая закомментированная строка такова, что Emacs 25 не добавляет (package-initialize)в мой файл инициализации. Бит с normal-top-level-add-subdirs-to-load-pathявляется приближением к тому, package-initializeчто сделало бы load-path, приближение, которое кажется достаточно хорошим.

Это, кажется, достигает моих желаний 1 и 2, но не 3. Если я пытаюсь использовать :ensure, я получаю сообщение об ошибке, говорящее, что package.elэто не инициализировано. Вызов исправил package-initializeбы это, но я хотел бы избежать этого, так как а) я не хочу, чтобы загружались все бесчисленные автозагрузки (я предпочитаю использовать use-packageдля создания именно тех автозагрузок, которые мне нужны), и б) я хочу иметь возможность легко Старайтесь не загружать определенные установленные пакеты в любое время (это легко сделать use-package).

У кого-нибудь есть рекомендации как это сделать?

Омар
источник

Ответы:

11

IIUC, что вы хотите сделать, это:

(package-initialize t)

Обратите внимание на tаргумент, который является ключом к вашему счастью, поскольку он будет (или должен, по крайней мере) инициализировать package.el без активации всех установленных пакетов.

Стефан
источник
1
Это отвечает на мой вопрос, хотя сейчас я склоняюсь к использованию, package-initializeкоторое делает мой вопрос спорным.
Омар
15

С вашей текущей конфигурацией вы фактически отключили package.el, поскольку вы не инициализируете менеджер пакетов и не препятствуете его автоматической инициализации в Emacs. Все, что вы делаете в ответ, - это добавление ELPA в load-path, но это лишь небольшая часть того, что делает package.el. Я не уверен, почему вы это делаете, но я не рекомендую эту настройку.

В частности, вы не получите автозагрузку пакетов с вашим подходом, что означает, что изначально никакие команды из любого пакета не будут доступны.

Другими словами, вам M-xпредложат только встроенные команды. Чтобы добавить в командах из пакетов , которые вы должны были бы добавить явные :commandsопределения для всех ваших use-packageзаявлений, что составляет к многим поддерживающего усилию, особенно для больших пакетов , таких как Magit-за практически равен нуль коэффициент усиления package.el дает автозагрузки бесплатно ,


Объединение use-packageс package.el на самом деле очень просто - вся установка основана на этой комбинации - но гораздо лучше позволить package.el фактически выполнить свою работу. Просто инициализируйте package.el в самом начале вашего файла инициализации:

(require 'package)
(setq package-enable-at-startup nil)   ; To prevent initialising twice
(add-to-list 'package-archives '("melpa" . "https://stable.melpa.org/packages/"))

(package-initialize)

Для удобства вы можете впоследствии начать загрузку use-package, если она еще не установлена:

(unless (package-installed-p 'use-package)
  (package-refresh-contents)
  (package-install 'use-package))

Это позволит вам начать сеанс Emacs на новой системе, и ваш init.el будет автоматически установлен use-package.

В конечном итоге вам нужно загрузить use-package:

(eval-when-compile
  (require 'use-package))

Теперь вы можете использовать use-packageдля установки и настройки пакетов:

(use-package magit                      ; The one and only Git frontend
  :ensure t
  :bind (("C-c v c" . magit-clone)
         ("C-c v v" . magit-status)
         ("C-c v g" . magit-blame)
         ("C-c v l" . magit-log-buffer-file)
         ("C-c v p" . magit-pull))
   :config (setq magit-save-repository-buffers 'dontask))

Когда Emacs теперь оценивает эту форму во время запуска, use-packageпроверит, установлен ли Magit, и автоматически установит ее при необходимости.

lunaryorn
источник
3
«Я не уверен, почему вы это делаете»: единственная причина, которую я вижу, касается времени запуска: package-initializeтребуется некоторое время, чтобы заполнить путь, определить автозагрузку и сделать все остальное. Мне кажется, я где-то читал, что сам Джон Уигли (автор use-package) предпочитает объявлять все автоматически загружаемые команды в use-packageстрофах, а не полагаться на них package.el.
Франсуа Февот
В прошлый раз, когда я смотрел, он вообще не использовал package.el, и в любом случае, я не думаю, что вы получите много. Вам нужно заполнить load-pathи добавить автозагрузку в любом случае, через use-packageили через package.el. Я сомневаюсь, что есть ощутимая разница, особенно если у вас современная система с быстрым диском.
lunaryorn
3
Согласовано. Я сделал время сам. С быстрым диском вы фактически не видите большой разницы. На медленном диске запуск может быть заметно медленнее (примерно 0,2 с), package-initializeчем в пользовательском списке load-path. Я приписываю это «исследованию» файловой системы package.el. Однако я никогда не измерял сколько-нибудь существенных различий в производительности между загрузкой autoloadопределений из файлов и их размещением в use-packageстрофах.
Франсуа Февот
Ну, я бы не сказал , я отключил в package.elсистему, я бы сказал , что я только инвалид package-initialize! Причина в том, что, хотя мне нравится list-packagesискать новые пакеты и специально обновлять все мои установленные в настоящее время пакеты, я думаю, что я предпочитаю целевую загрузку use-package. Для меня автозагрузки только для команд, я использую звуки, как хорошая вещь!
Омар,
1
@ OmarAntolín-Camarena Почему бы и нет? Автозагрузки - это, по сути, открытый интерфейс пакета, ориентированного на пользователя, и поскольку package.el стал стандартным способом распространения пакетов, мы можем положиться на их наличие.
lunaryorn