Usando package.el para instalar y actualizar, pero use package para cargar y configurar

15

Después de conocerlo recientemente use-package, decidí transferir mi configuración a él, pero me encontré reacio a renunciar a la comodidad de usar package.elpara instalar paquetes y mantenerlos actualizados. Me ha resultado un poco complicado combinar use-packagey package.el.

En general, estoy interesado en aprender cómo las personas se combinan use-packagecon el package.elsistema, pero para una pregunta más específica, sigue leyendo.

Esto es lo que quiero:

  1. Tener paquetes instalados por el administrador de paquetes para poder buscarlos fácilmente y mantenerlos actualizados list-packages.
  2. Para configurar y cargar paquetes exclusivamente use-package, para que pueda ver fácilmente en mi archivo de inicio exactamente lo que estoy cargando y cómo está configurado.
  3. Opcionalmente, también me gustaría poder instalar paquetes a través use-packagede la :ensurepalabra clave.

Si estoy entendiendo correctamente, quiero muy poco de lo que package-initializehace, básicamente solo la forma en que configura el load-path. Actualmente tengo esto en mi configuración:

;(package-initialize)
(setq package-enable-at-startup nil)
(let ((default-directory "~/.emacs.d/elpa"))
  (normal-top-level-add-subdirs-to-load-path))
(require 'use-package)

La primera línea comentada es para que Emacs 25 no agregue una (package-initialize)a mi archivo init. El bit con normal-top-level-add-subdirs-to-load-pathes una aproximación a lo package-initializeque haría el load-path, una aproximación que parece lo suficientemente buena.

Esto parece lograr mis deseos 1 y 2, pero no 3. Si trato de usar :ensure, recibo un mensaje de error que dice que package.elno está inicializado. Llamar package-initializesolucionaría eso, pero deseo evitar eso ya que a) no quiero que se carguen todas las innumerables cargas automáticas (prefiero usarlas use-packagepara crear con precisión las cargas automáticas que necesito), yb) quiero poder fácilmente evito cargar ciertos paquetes instalados cuando quiera (lo cual es fácil de hacer use-package).

¿Alguien tiene una recomendación sobre cómo hacer esto?

Omar
fuente

Respuestas:

11

IIUC lo que quieres hacer es:

(package-initialize t)

Tenga en cuenta el targumento, que es la clave de su felicidad aquí, ya que (al menos debería) inicializar package.el sin activar todos los paquetes instalados.

Stefan
fuente
1
Esto responde a mi pregunta, aunque ahora me estoy inclinando hacia el uso package-initializeque hace que mi pregunta sea discutible.
Omar
15

Con su configuración actual, ha deshabilitado efectivamente package.el, ya que no inicializa el administrador de paquetes y evita que Emacs lo inicialice automáticamente. Todo lo que debe hacer a cambio es agregar ELPA al load-path, pero eso es solo un pequeño subconjunto de lo que hace package.el. No estoy seguro de por qué haces eso, pero no es una configuración que recomiendo.

Específicamente, no obtendrá cargas automáticas de paquetes con su enfoque, lo que significa que inicialmente no habrá comandos de ningún paquete disponibles.

En otras palabras, M-xsolo le ofrecerá comandos integrados. Para agregar comandos desde sus paquetes, tendría que agregar :commandsdefiniciones explícitas a todas sus use-packagedeclaraciones, lo que equivale a un gran esfuerzo de mantenimiento, particularmente para paquetes grandes como Magit, para obtener esencialmente cero ganancias. Package.el le proporciona cargas automáticas gratis .


La combinación use-packagecon package.el es realmente muy simple: toda la configuración se basa en esta combinación, pero es mucho mejor dejar que package.el realmente haga su trabajo. Simplemente inicialice package.el al comienzo de su archivo init:

(require 'package)
(setq package-enable-at-startup nil)   ; To prevent initialising twice
(add-to-list 'package-archives '("melpa" . "https://stable.melpa.org/packages/"))

(package-initialize)

Para mayor comodidad, es posible que posteriormente desee iniciar use-package, si aún no está instalado:

(unless (package-installed-p 'use-package)
  (package-refresh-contents)
  (package-install 'use-package))

Esto le permite iniciar una sesión de Emacs en un sistema nuevo, y su init.el se instalará automáticamente use-package.

Finalmente necesitas cargar use-package:

(eval-when-compile
  (require 'use-package))

Ahora puede usar use-packagepara instalar y configurar paquetes:

(use-package magit                      ; The one and only Git frontend
  :ensure t
  :bind (("C-c v c" . magit-clone)
         ("C-c v v" . magit-status)
         ("C-c v g" . magit-blame)
         ("C-c v l" . magit-log-buffer-file)
         ("C-c v p" . magit-pull))
   :config (setq magit-save-repository-buffers 'dontask))

Cuando Emacs ahora evalúa este formulario durante el inicio, use-packageverificará si Magit ya está instalado y lo instalará automáticamente si es necesario.

Lunaryorn
fuente
3
"No estoy seguro de por qué haces eso": la única razón por la que puedo ver es sobre los tiempos de inicio: package-initializetoma un tiempo completar la ruta, definir las cargas automáticas y hacer el resto de sus cosas. Creo que leí en alguna parte que el propio Jon Wiegley (el autor de use-package) prefiere declarar todos los comandos cargados automáticamente en use-packageestrofas en lugar de confiar en ellos package.el.
François Févotte
La última vez que miré no usó package.el en absoluto, y en cualquier caso, no creo que ganes mucho. Es necesario para poblar el load-pathy añadir autoloads en cualquiera de los casos, ya sea a través use-packageo por medio package.el. Dudo que haya una diferencia medible, particularmente si tienes un sistema moderno con un disco rápido.
lunaryorn
3
Convenido. Hice los horarios yo mismo. Con un disco rápido, efectivamente no ve mucha diferencia. Con un disco lento, el inicio puede ser notablemente más lento (algo así como 0.2s) con package-initializeuna lista personalizada load-path. Atribuyo esto a la "exploración" del sistema de archivos que lo package.elhace. Sin embargo, nunca medí ninguna diferencia significativa en el rendimiento entre cargar autoloaddefiniciones de archivos y tenerlas en use-packageestrofas.
François Févotte
Bueno, no diría que he desactivado el package.elsistema, ¡diría que solo lo he desactivado package-initialize! La razón es que, si bien me gusta list-packagesbuscar nuevos paquetes y, especialmente, actualizar todos mis paquetes instalados actualmente, creo que prefiero la carga específica de use-package. ¡Para mí, tener cargas automáticas solo para comandos que uso suena como algo bueno!
Omar
1
@ OmarAntolín-Camarena ¿Por qué no? Las cargas automáticas son esencialmente la interfaz pública de un paquete orientado al usuario, y dado que package.el se convirtió en la forma estándar de distribuir paquetes, podemos confiar en su presencia.
lunaryorn