elpa emacs
¿Cómo instalar automáticamente los paquetes de Emacs especificando una lista de nombres de paquetes? (10)
Estoy usando el package
para administrar mis extensiones de Emacs. Para sincronizar mis configuraciones de Emacs en diferentes computadoras, me gustaría una forma de especificar una lista de nombres de paquetes en el archivo .emacs
y luego el package
podría buscar e instalar automáticamente los paquetes, para que no tenga que instalarlos manualmente llamando a Mx package-list-packages
. ¿Como hacer eso?
Aquí está el código que uso para Emacs Prelude :
(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 no está utilizando MELPA, no necesita requerirlo (y si lo hace melpa.el
tiene que estar en su load-path
(o instalar a través de MELPA). El paquete db no se actualiza cada vez (ya que ralentizaría considerablemente la puesta en marcha), solo donde haya paquetes desinstalados.
Aquí está el mío, es más corto :)
(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))
Emacs 25.1+ realizará un seguimiento automático de los paquetes instalados por el usuario en la variable package-selected-packages
. package-install
actualizará la variable de personalización y podrá instalar todos los paquetes seleccionados con la función package-install-selected-packages
.
Otra ventaja conveniente de este enfoque es que puede usar package-autoremove
para eliminar automáticamente los paquetes que no están incluidos en package-selected-packages
(aunque conservará las dependencias).
(package-initialize)
(unless package-archive-contents
(package-refresh-contents))
(package-install-selected-packages)
Fuente: http://endlessparentheses.com/new-in-package-el-in-emacs-25-1-user-selected-packages.html
En base a los comentarios de Profpatsch y las respuestas a continuación:
(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)
Llame a package-install
con el nombre del paquete como un símbolo. Puede encontrar los nombres de los paquetes para sus paquetes llamando package-install
interactiva y completando el nombre. La función package-installed-p
le permitirá saber si ya se ha instalado.
Por ejemplo:
(mapc
(lambda (package)
(or (package-installed-p package)
(package-install package)))
''(package1 package2 package3))
Me encontré con un problema que no sucedió nada después de agregar (package-install ''org)
en .emacs
. Quería instalar la versión actualizada de org-mode
y el org-mode
incorporado es bastante antiguo.
Saqué el código fuente de package-install
del package-install
de Emacs 25.3.1. La función self ya verifica si un paquete está instalado o no y se niega a instalarlo si el paquete ya está instalado. Entonces el cheque (unless (package-installed-p package) ...)
de la respuesta 10093312 de hecho no se 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))))
El org-mode
incorporado también cuenta como instalado y la instalación del package-install
niega a instalar la versión más nueva de ELPA. Después de pasar algún tiempo leyendo package.el, se me ocurrió la siguiente solución.
(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 razón por la que funciona es que package-*
funciones de familia manejan los argumentos de forma diferente en función de si se trata de un símbolo o de un objeto package-desc
. Solo puede especificar información de versión para package-install
través de un objeto package-desc
.
Me gusta comprobar si el usuario desea instalar los paquetes primero como se hace en esta respuesta . También estoy refrescando el contenido de mi paquete una vez antes de instalar cualquier cosa. No estoy seguro de si esta es la mejor manera, pero no creo que las mejores respuestas lo hayan hecho por mí.
(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)))
Nadie ha mencionado a Cask todavía, pero es bastante adecuado para esta tarea.
Básicamente, usted crea ~/.emacs.d/Cask
listando los paquetes que desea instalar. Por ejemplo:
(source melpa)
(depends-on "expand-region")
(depends-on "goto-last-change")
; ... etc
Ejecutar cask
desde la línea de comandos instalará estos paquetes por usted y las dependencias que necesiten.
Además, puede actualizar automáticamente los paquetes instalados usando la cask update
.
(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)
; 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)))