Comment installer automatiquement les paquets Emacs en spécifiant une liste de noms de paquets?
j'utilise package
pour gérer mes extensions Emacs. Afin de synchroniser mes paramètres Emacs sur différents ordinateurs, j'aimerais pouvoir spécifier une liste de noms de paquets dans le fichier .emacs
et ensuite package
pourrait automatiquement rechercher et installer les paquets, de sorte que je n'ai pas besoin de les installer manuellement en appelant M-x package-list-packages
. Comment faire?
10 réponses
; 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)))
basé sur les commentaires de Profpatsch et les réponses ci-dessous:
(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+ gardera automatiquement la trace des paquets installés par l'utilisateur dans la variable personnalisable package-selected-packages
. package-install
mettra à jour la variable personnaliser, et vous pouvez installer tous les paquets sélectionnés avec la fonction package-install-selected-packages
.
un autre avantage pratique de cette approche est que vous pouvez utiliser package-autoremove
pour supprimer automatiquement les paquets qui ne sont pas inclus dans package-selected-packages
(bien qu'il préservera les dépendances).
(package-initialize)
(unless package-archive-contents
(package-refresh-contents))
(package-install-selected-packages)
Source: http://endlessparentheses.com/new-in-package-el-in-emacs-25-1-user-selected-packages.html
Voici le code que j'utilise pour Emacs Prélude :
(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)
si vous n'utilisez pas MELPA vous n'avez pas besoin de l'exiger (et si vous utilisez melpa.el
doit être sur votre load-path
(ou installé via MELPA). Le paquet db n'est pas rafraîchi à chaque fois (car cela ralentirait le démarrage de manière significative) - seulement là où il y a des paquets non désinstallés présents.
personne n'a encore mentionné Cask , mais il est tout à fait approprié pour cette tâche.
fondamentalement, vous créez ~/.emacs.d/Cask
en énumérant les paquets que vous voulez installer. Par exemple:
(source melpa)
(depends-on "expand-region")
(depends-on "goto-last-change")
; ... etc
exécuter cask
à partir de la ligne de commande installera ces paquets pour vous, et les dépendances dont ils ont besoin.
de plus, vous pouvez mettre à jour automatiquement les paquets installés en utilisant cask update
.
Appel package-install
avec le nom du package, comme un symbole. Vous pouvez trouver les noms de paquets pour vos paquets en appelant package-install
de façon interactive et en complétant sur le nom. La fonction package-installed-p
vous indiquera si elle a déjà été installée.
par exemple:
(mapc
(lambda (package)
(or (package-installed-p package)
(package-install package)))
'(package1 package2 package3))
j'aime vérifier si l'utilisateur veut installer les paquets en premier comme fait dans cette réponse . De plus, je rafraîchis le contenu de mon paquet une fois avant d'installer quoi que ce soit. Je ne suis pas sûr que ce soit la meilleure façon, mais je ne pense pas que les meilleures réponses le faisaient pour moi.
(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)
, Voici la mienne, c'est plus court :)
(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))
je suis tombé sur un problème que rien ne s'est passé après avoir ajouté (package-install 'org)
dans .emacs
. Je voulais installer la version actuelle de org-mode
et la version intégrée org-mode
est assez ancienne.
j'ai extrait le code source de package-install
D'Emacs 25.3.1. La fonction auto déjà de vérifier si un paquet est installé ou pas et refuse de l'installer si le paquet est déjà installé. Donc le contrôle (unless (package-installed-p package) ...)
de la réponse 10093312 est en fait injustifiés.
(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))))
la version intégrée org-mode
est également considérée comme installée et package-install
refuse d'installer la nouvelle version de L'ELPA. Après avoir passé du temps à lire un paquet.el, je suis venu avec la solution suivante.
(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))
la raison pour laquelle cela fonctionne est que package-*
les fonctions de la famille traitent les arguments différemment selon qu'il s'agit d'un symbole ou d'un objet package-desc
. Vous pouvez spécifiez uniquement les informations de version pour package-install
via un objet package-desc
.