Обновление пакетов в Emacs

148

У меня есть следующие настройки для пакетов (не уверен, есть ли лучший вариант):

(require 'package)
(setq package-archives '(("ELPA" . "http://tromey.com/elpa/") 
                          ("gnu" . "http://elpa.gnu.org/packages/")
                          ("marmalade" . "http://marmalade-repo.org/packages/")))

; Apparently needed for the package auto-complete (why?)
(add-to-list 'package-archives
             '("melpa" . "http://melpa.milkbox.net/packages/") t)

(package-initialize)
(setq url-http-attempt-keepalives nil)

У меня три вопроса, связанных с установкой и обновлением пакетов.

Q1. Есть ли способ обновить список доступных пакетов (и самых последних версий) и обновить конкретный пакет?

Q.2 В чем разница между следующими источниками пакетов ?:

  • ELPA,
  • GNU
  • мармелад
  • мелпа

Q.3 Имеет ли значение порядок, в котором они добавлены package-archives?

Амелио Васкес-Рейна
источник
13
MELPA необходима для автозаполнения, поскольку, очевидно, никто не позаботился сделать автозаполнение доступным на Marmalade. Не беспокойтесь, а лучше очистите свой package-archives. Избавьтесь от архива ELPA, который больше не поддерживается, и от архива мармелада, который представляет собой беспорядок из устаревших и дублированных пакетов без четких указаний и обслуживания. Используйте только стандартный архив GNU и MELPA>
lunaryorn
2
Спасибо @lunaryorn! Это очень полезно. Вы знаете, как я могу оставаться в курсе таких вещей? (то есть «полезные сведения», подобные этим по мере развития Emacs)
Амелио Васкес-Рейна
3
Информация свободно циркулирует в сети, просто поймите ее: подписывайтесь на / emacs на Reddit, следите за блогами и твиттером известных людей Emacs, таких как Ник Ферриер, Божидар Бацов, Магнар Свин, Джон Вигли и т. Д., Присоединяйтесь к #emacs на Freenode IRC, и многое другое.
lunaryorn
3
Вы должны, (setq package-enable-at-startup nil)если собираетесь позвонить (package-initialize)себе.
phils
2
Спасибо @phils - Зачем это нужно?
Амелио Васкес-Рейна

Ответы:

166
  1. Для автоматического обновления списка пакетов, только если список пакетов еще не существует , используйте следующее:

    (when (not package-archive-contents)
        (package-refresh-contents))
    

    Чтобы обновить все установленные пакеты, введите package-list-packages, который перенесет вас в *Packages*буфер (а также обновит список пакетов), а затем введите U x.

    package-refresh-contentsбезоговорочно пытается загрузить список пакетов из всех репозиториев, в которые вы добавили package-archives; package-archive-contentsне равно нулю, если вы уже загрузили список пакетов.

  2. ELPA - это оригинал. Я не думаю, что это действительно поддерживается, но я не уверен. Я этим не пользуюсь.

    GNU является «официальным». Он поддерживается вместе с Emacs, что означает, что все должно работать всегда, но обновления и новые пакеты приходят не очень часто.

    Marmalade - это в основном веб-сайт, на который вы можете загрузить полный пакет, и он будет добавлен в репозиторий мармелада. Вы не просто отправляете ссылку на апстрим пакета, и это не совсем автоматизирует создание пакета полностью. Я думаю, что это правильный выбор, потому что вам не обязательно отслеживать восходящий поток. К сожалению, какое-то время он не поддерживался, но недавно кто-то взял его на себя, поэтому в какой-то момент он должен вернуться и стать лучше.

    Melpa берет URL-адрес, например, для области Lisp EmacsWiki или репозитория github, и автоматически создает из него пакет. Таким образом, обычно не более суток отстает от того, что отслеживается. Хотя он отслеживает восходящий поток, на практике у меня никогда не было проблем, и именно отсюда происходит большинство моих пакетов. Существует также Melpa Stable , который похож на Melpa, но использует помеченные версии исходного репо вместо последней версии. У Melpa stable меньше пакетов, чем у Melpa.

    Режим организации имеет собственное package.elрепо ( http://orgmode.org/elpa/ ).

    Все репозитории пакетов работают одинаково, вы просто добавляете их в свой package-archives.

    Вот более подробное сообщение в блоге на эту тему, с которым я в основном согласен.

  3. Я не уверен, но я думаю, что если пакет дублируется в разных репозиториях, порядок, в котором они появляются, package-archivesопределяет приоритет. Я не знаю, находится ли более высокий приоритет в начале или в конце списка.

    Обновление: в Emacs 25 есть переменная, package-archive-prioritiesкоторую вы можете использовать для определения приоритетов ваших репозиториев пакетов (например, предпочитайте ELPA над MELPA).


Вот соответствующий раздел моей статьи init.el, если вам интересно:

(setq jpk-packages
      '(
        ac-dabbrev
        ...
        yasnippet
        ))

(package-initialize)
(add-to-list 'package-archives
             '("melpa" . "http://melpa.org/packages/"))
(add-to-list 'package-archives
             '("org" . "http://orgmode.org/elpa/"))

;; install any packages in jpk-packages, if they are not installed already
(let ((refreshed nil))
  (when (not package-archive-contents)
    (package-refresh-contents)
    (setq refreshed t))
  (dolist (pkg jpk-packages)
    (when (and (not (package-installed-p pkg))
             (assoc pkg package-archive-contents))
      (unless refreshed
        (package-refresh-contents)
        (setq refreshed t))
      (package-install pkg))))

(defun package-list-unaccounted-packages ()
  "Like `package-list-packages', but shows only the packages that
  are installed and are not in `jpk-packages'.  Useful for
  cleaning out unwanted packages."
  (interactive)
  (package-show-package-list
   (remove-if-not (lambda (x) (and (not (memq x jpk-packages))
                            (not (package-built-in-p x))
                            (package-installed-p x)))
                  (mapcar 'car package-archive-contents))))
jpkotta
источник
2
Благодарность! Что when (not package-archive-contents)проверяет?
Амелио Васкес-Рейна
3
Условие предотвращает обновление каждый раз, когда я запускаю emacs (обычно я хочу, чтобы он проверял, только когда я говорю). Он проверяет только отсутствие архивов пакетов, что должно происходить только в том случае, когда я впервые клонирую свою конфигурацию на новую машину.
jpkotta
Просто сообщаю вам об ответе @Brandy Trainor, который, кажется, дополняет ваш ответ - на случай, если он будет полезен.
Амелио Васкес-Рейна
Я думаю, что это должно быть вызвано (refresh-package-contents)безоговорочно перед загрузкой новых пакетов, поскольку в противном случае Emacs может попытаться загрузить старую версию пакета (которая к тому времени является 404), потерпит неудачу и прекратит загрузку.
Владимир Пантелеев
Как лучше всего понять, какой пакет нежелателен? @jpkotta
Alper
109

В Emacs используйте M-x list-packagesдля вывода списка всех пакетов, которые автоматически обновят содержимое архива. Впоследствии используйте Uдля отметки всех обновляемых пакетов, которые необходимо обновить, и xдля фактического выполнения новых обновлений. Затем Emacs загрузит и установит все обновления и спросит вас, следует ли впоследствии удалить старые устаревшие версии.

Вы также можете взглянуть на Carton, который обеспечивает более удобный способ управления вашими пакетами, объявляя их в специальном файле, и включает удобный клиент командной строки для автоматической установки и обновления пакетов, объявленных таким образом.


Порядок package-archivesне имеет значения. Emacs объединяет содержимое всех архивов в единый согласованный список доступных пакетов и их версий, хранящихся в файлах package-archive-contents.

После package-installэтого Emacs просто выберет самую новую версию пакета, независимо от исходного архива. Для большего контроля происхождения пакета MELPA предоставляет пакет melpa, который позволяет заносить пакеты в черный или белый список из указанных архивов.

лунный рог
источник
3
Это , S-uчтобы быть более точным.
Ленар Хойт,
@mcb Что S-u? В меню пакета эта привязка не используется.
lunaryorn
2
Я имею в виду Shift-uэто.
Ленар Хойт,
8
@mcb Ну вот почему я написал заглавную U 😊
lunaryorn
1
Просто для таких запутанных, как я, думают, что это означает <kbd> U </kbd>.
Ленар Хойт
28

В терминале:

emacs

M-x list-packages

это помещает вас в буфер * пакетов *

shift-u x

emacs спросит вас (да / нет), дождитесь обновлений

C-x k <ret>

это убьет буфер * пакетов * и вернет вас обратно к * царапинам *

C-x-C-c

это приведет к выходу из emacs и позволит вам перезапустить через, но вам, возможно, придется отлаживать :(

emacs

мой 2 ¢

Rezwits
источник
Я получил «не указана команда» или что-то в этом роде, когда я набрал «U». После запуска M-x package-refresh-contentsмне было предложено ввести «U», чтобы отметить все для обновления, а затем я смог ввести «x», чтобы запустить обновления.
MrColes
2

Это больше расширенный комментарий к ответу jpkotta.

Это корректировка, с которой я экспериментирую для ответа jpkotta выше:

(setq n 0)                                  ; set n as 0
(dolist (pkg pkgs-2b-present)               ; for each pkg in list
  (unless (or                               ; unless
           (package-installed-p pkg)        ; pkg is installed or
           (assoc pkg                       ; pkg is in the archive list
                  package-archive-contents))
    (setq n (+ n 1))))                      ; add one to n
(when (> n 0)                               ; if n > 0, 
  (package-refresh-contents))               ; refresh packages

(замена (when (not package-archive-contents) (package-refresh-contents))).

Список пакетов обновлялся недостаточно часто для моего случая использования.

Я не думал, есть ли более эффективное решение моей проблемы; Во-первых, я должен посмотреть, исчезнет ли проблема с этой настройкой.

Брэди Трейнор
источник
В моем ответе package-archive-contentsобновляется, только если его не существует. Идея состоит в том, что вы копируете свой .emacs.d на новый компьютер, и он автоматически устанавливает все ваши пакеты, но после этого вам придется обновить его вручную. Я стараюсь обновлять примерно раз в две недели. Я предполагаю, что вы добавили пакет в свой список, но ваш package-archive-contentsбыл слишком стар, чтобы иметь его?
jpkotta
@jpkotta, у меня двойная загрузка, каждая из которых использует свои по умолчанию ~/.emacs.d/elpa/для расположения пакетов. Однако моя версия вашего кода установки пакета находится в «третьем» разделе ( e:/emacs-configили /e/emacs-config/). Поэтому я добавляю пакет в список в одной ОС, и он должен обновляться при загрузке Emacsв другой ОС. Конечно, в моем решении есть элемент излишка, но, похоже, он по крайней мере работает.
Brady Trainor
@jpkotta, почему я, package-archive-contentsвозможно, так не в себе, ускользает от меня. Я не ограничился этим вопросом. Если я буду искать и в будущем найду «более элегантное» решение, я добавлю его в свой пост.
Brady Trainor
1
(package-refresh-contents)пишет в ~/.emacs.d/elpa/archives. Неясно, есть ли у вас общий доступ к этому каталогу между ОС. Я бы рекомендовал не делиться elpa/каталогами, потому что байт-код Emacs (код в elpa/байтовой компиляции) не имеет обратной совместимости ( gnu.org/software/emacs/manual/html_node/elisp/… ). Вы должны убедиться, что обе установки имеют одну и ту же версию Emacs. Я сохраняю свой .emacs.dконтроль версий и синхронизирую с ним разные установки.
jpkotta