Как автоматически установить пакеты Emacs, указав список имен пакетов?
Я использую package
для управления расширениями Emacs. Чтобы синхронизировать Мои настройки Emacs на разных компьютерах, я хотел бы указать список имен пакетов в .emacs
файл, а потом package
может автоматически искать и устанавливать пакеты, так что мне не нужно устанавливать их вручную, позвонив M-x package-list-packages
. Как это сделать?
10 ответов:
; list the packages you want (setq package-list '(package1 package2)) ; list the repositories containing them (setq package-archives '(("elpa" . "http://tromey.com/elpa/") ("gnu" . "http://elpa.gnu.org/packages/") ("marmalade" . "http://marmalade-repo.org/packages/"))) ; activate all the packages (in particular autoloads) (package-initialize) ; fetch the list of packages available (unless package-archive-contents (package-refresh-contents)) ; install the missing packages (dolist (package package-list) (unless (package-installed-p package) (package-install package)))
на основе комментариев Profpatsch и ответов ниже:
(defun ensure-package-installed (&rest packages) "Assure every package is installed, ask for installation if it’s not. Return a list of installed packages or nil for every skipped package." (mapcar (lambda (package) ;; (package-installed-p 'evil) (if (package-installed-p package) nil (if (y-or-n-p (format "Package %s is missing. Install it? " package)) (package-install package) package))) packages)) ;; make sure to have downloaded archive description. ;; Or use package-archive-contents as suggested by Nicolas Dudebout (or (file-exists-p package-user-dir) (package-refresh-contents)) (ensure-package-installed 'iedit 'magit) ; --> (nil nil) if iedit and magit are already installed ;; activate installed packages (package-initialize)
Emacs 25.1 + будет автоматически отслеживать установленные пользователем пакеты в настраиваемом
package-selected-packages
переменной.package-install
обновить настройки переменной, и вы можете установить все выбранные пакеты с .еще одним удобным преимуществом этого подхода является то, что вы можете использовать
package-autoremove
для автоматического удаления пакетов, которые не включены вpackage-selected-packages
(хотя это сохранит зависимости).(package-initialize) (unless package-archive-contents (package-refresh-contents)) (package-install-selected-packages)
источник: http://endlessparentheses.com/new-in-package-el-in-emacs-25-1-user-selected-packages.html
вот код, который я использую для Прелюдия Emacs:
(require 'package) (require 'melpa) (add-to-list 'package-archives '("melpa" . "http://melpa.milkbox.net/packages/") t) (package-initialize) (setq url-http-attempt-keepalives nil) (defvar prelude-packages '(ack-and-a-half auctex clojure-mode coffee-mode deft expand-region gist haml-mode haskell-mode helm helm-projectile inf-ruby magit magithub markdown-mode paredit projectile python sass-mode rainbow-mode scss-mode solarized-theme volatile-highlights yaml-mode yari yasnippet zenburn-theme) "A list of packages to ensure are installed at launch.") (defun prelude-packages-installed-p () (loop for p in prelude-packages when (not (package-installed-p p)) do (return nil) finally (return t))) (unless (prelude-packages-installed-p) ;; check for new packages (package versions) (message "%s" "Emacs Prelude is now refreshing its package database...") (package-refresh-contents) (message "%s" " done.") ;; install the missing packages (dolist (p prelude-packages) (when (not (package-installed-p p)) (package-install p)))) (provide 'prelude-packages)
Если вы не используете MELPA вам не нужно требовать его (и если вы делаете
melpa.el
должен быть на своемload-path
(или устанавливается через MELPA). БД пакетов не обновляется каждый раз (поскольку это значительно замедлит запуск) - только там, где присутствуют удаленные пакеты.
никто не упомянул бочковой пока нет, но вполне подходят для этой задачи.
в основном вы создаете
~/.emacs.d/Cask
список пакетов, которые вы хотите установить. Например:(source melpa) (depends-on "expand-region") (depends-on "goto-last-change") ; ... etc
под управлением
cask
из командной строки установит эти пакеты для вас, и любые зависимости, которые им нужны.кроме того, вы можете автоматически обновлять установленные пакеты с помощью
cask update
.
вызов
package-install
имя пакета в качестве символа. Вы можете найти имена пакетов для ваших пакетов, позвонивpackage-install
интерактивно и завершая на имя. Функцияpackage-installed-p
сообщит вам, если он уже установлен.например:
(mapc (lambda (package) (or (package-installed-p package) (package-install package))) '(package1 package2 package3))
Мне нравится проверять, если пользователь хочет установить пакеты, как это сделано в ответ. Также Я обновляю содержимое пакета один раз перед установкой чего-либо. Я не уверен, что это лучший способ, но я не думаю, что лучшие ответы делали это для меня.
(setq required-pkgs '(jedi flycheck cider clojure-mode paredit markdown-mode jsx-mode company)) (require 'cl) (setq pkgs-to-install (let ((uninstalled-pkgs (remove-if 'package-installed-p required-pkgs))) (remove-if-not '(lambda (pkg) (y-or-n-p (format "Package %s is missing. Install it? " pkg))) uninstalled-pkgs))) (when (> (length pkgs-to-install) 0) (package-refresh-contents) (dolist (pkg pkgs-to-install) (package-install pkg)))
(require 'cl) (require 'package) (setq cfg-var:packages '( emmet-mode ergoemacs-mode flycheck flycheck-pyflakes monokai-theme py-autopep8 py-isort rainbow-mode yafolding yasnippet)) (defun cfg:install-packages () (let ((pkgs (remove-if #'package-installed-p cfg-var:packages))) (when pkgs (message "%s" "Emacs refresh packages database...") (package-refresh-contents) (message "%s" " done.") (dolist (p cfg-var:packages) (package-install p))))) (add-to-list 'package-archives '("gnu" . "http://elpa.gnu.org/packages/") t) (add-to-list 'package-archives '("melpa" . "http://melpa.org/packages/") t) (add-to-list 'package-archives '("melpa-stable" . "http://stable.melpa.org/packages/") t) (add-to-list 'package-archives '("org" . "http://orgmode.org/elpa/") t) (package-initialize) (cfg:install-packages)
вот мой, он короче:)
(mapc (lambda (package) (unless (package-installed-p package) (progn (message "installing %s" package) (package-refresh-contents) (package-install package)))) '(browse-kill-ring flycheck less-css-mode tabbar org auto-complete undo-tree clojure-mode markdown-mode yasnippet paredit paredit-menu php-mode haml-mode rainbow-mode fontawesome))
я столкнулся с проблемой, что ничего не произошло после добавления
(package-install 'org)
на.emacs
. Я хотел установить последнюю версиюorg-mode
и вorg-mode
довольно старый.я откопал исходный код
package-install
от Emacs 25.3.1. Функция self уже проверяет, установлен ли пакет или нет, и отказывается устанавливать его, если пакет уже установлен. Так что чек(unless (package-installed-p package) ...)
из ответа 10093312 на самом деле неуместно для.(defun package-install (pkg &optional dont-select) "Install the package PKG. PKG can be a package-desc or a symbol naming one of the available packages in an archive in `package-archives'. Interactively, prompt for its name. If called interactively or if DONT-SELECT nil, add PKG to `package-selected-packages'. If PKG is a package-desc and it is already installed, don't try to install it but still mark it as selected." (interactive (progn ;; Initialize the package system to get the list of package ;; symbols for completion. (unless package--initialized (package-initialize t)) (unless package-archive-contents (package-refresh-contents)) (list (intern (completing-read "Install package: " (delq nil (mapcar (lambda (elt) (unless (package-installed-p (car elt)) (symbol-name (car elt)))) package-archive-contents)) nil t)) nil))) (add-hook 'post-command-hook #'package-menu--post-refresh) (let ((name (if (package-desc-p pkg) (package-desc-name pkg) pkg))) (unless (or dont-select (package--user-selected-p name)) (package--save-selected-packages (cons name package-selected-packages))) (if-let ((transaction (if (package-desc-p pkg) (unless (package-installed-p pkg) (package-compute-transaction (list pkg) (package-desc-reqs pkg))) (package-compute-transaction () (list (list pkg)))))) (package-download-transaction transaction) (message "`%s' is already installed" name))))
встроенный
org-mode
также считается установленным иpackage-install
отказывается устанавливать более новую версию из ELPA. Потратив некоторое время на чтение пакета.Эл, я придумал следующее решение.(dolist (package (package-compute-transaction () (list (list 'python '(0 25 1)) (list 'org '(20171211))))) ;; package-download-transaction may be more suitable here and ;; I don't have time to check it (package-install package))
причина, почему она работает
package-*
семейные функции обрабатывают аргументы по-разному в зависимости от того, является ли это символом или
Comments