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?

115
demandé sur nbro 2012-04-10 20:07:15

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)))
99
répondu Nicolas Dudebout 2014-01-23 19:15:37

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)
45
répondu RNA 2014-02-20 00:05:23

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

32
répondu Nick McCurdy 2017-04-21 22:19:56

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.

17
répondu Bozhidar Batsov 2013-09-27 09:47:30

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 .

7
répondu Alastair 2015-02-09 07:02:00

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))
4
répondu ataylor 2012-04-10 16:23:48

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)))
3
répondu Frank Henard 2017-05-23 11:46:58
(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)
3
répondu Dunaevsky Maxim 2015-09-10 06:25:19

, 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))
0
répondu yPhil 2017-07-20 18:23:07

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 .

0
répondu Lei Zhao 2017-12-17 07:57:03