Actualización de paquetes en Emacs

144

Tengo la siguiente configuración para paquetes (no estoy seguro si hay uno mejor recomendado):

(require 'package)
(setq package-archives '(("ELPA" . "http://tromey.com/elpa/") 
                          ("gnu" . "http://elpa.gnu.org/packages/")
                          ("marmalade" . "http://marmalade-repo.org/packages/")))

; Apparently needed for the package auto-complete (why?)
(add-to-list 'package-archives
             '("melpa" . "http://melpa.milkbox.net/packages/") t)

(package-initialize)
(setq url-http-attempt-keepalives nil)

Tengo tres preguntas relacionadas con la instalación y actualización de paquetes.

Q1. ¿Hay alguna manera de actualizar la lista de paquetes disponibles (y las versiones más recientes) y actualizar un paquete específico?

Q.2 ¿Cuál es la diferencia entre las siguientes fuentes de paquetes ?:

  • ELPA
  • ÑU
  • mermelada
  • melpa

Q.3 ¿Importa el orden en que se agregan package-archives?

Amelio Vazquez-Reina
fuente
13
MELPA es necesario para el autocompletado ya que obviamente ninguno se molestó en hacer que el autocompletado esté disponible en Marmalade. No te molestes, más bien limpia tu package-archives. Deshágase del archivo ELPA, que ya no se mantiene, y del archivo de mermelada, que es un desastre de paquetes obsoletos y duplicados sin orientación y mantenimiento claros. Utilice solo el archivo GNU estándar y MELPA>
lunaryorn
2
Gracias @lunaryorn! Eso es muy útil ¿Sabes cómo podría mantenerme informado sobre cosas como esta? (es decir, "cosas buenas para saber" como estas a medida que Emacs evoluciona)
Amelio Vazquez-Reina
3
La información fluye libremente en la web, solo tómala: sigue / emacs en Reddit, sigue blogs y twitter de personas reconocidas de Emacs como Nic Ferrier, Bozhidar Batsov, Magnar Sveen, John Wiegley, etc., únete a #emacs en Freenode IRC, y muchos más.
lunaryorn
3
Deberías (setq package-enable-at-startup nil)si te vas a llamar a (package-initialize)ti mismo.
phils
2
Gracias @phils - ¿Por qué es necesario?
Amelio Vazquez-Reina

Respuestas:

163
  1. Para actualizar automáticamente la lista de paquetes, solo si aún no hay una lista de paquetes , use lo siguiente:

    (when (not package-archive-contents)
        (package-refresh-contents))

    Para actualizar todos los paquetes instalados, escriba package-list-packages, que lo llevará al *Packages*búfer (y también actualizará la lista de paquetes), y luego escriba U x.

    package-refresh-contentsintenta incondicionalmente descargar una lista de paquetes de todos los repositorios que haya agregado package-archives; package-archive-contentses nulo si ya ha descargado la lista de paquetes.

  2. ELPA es el original. Ya no creo que se mantenga realmente, pero no estoy seguro. No lo uso

    GNU es "oficial". Se mantiene junto con Emacs, lo que significa que las cosas siempre deberían funcionar, pero las actualizaciones y los nuevos paquetes no llegan muy a menudo.

    Marmalade es básicamente un sitio web donde puede cargar un paquete completo, y se agregará al repositorio de mermelada. No solo envía un enlace a la cadena del paquete, y no automatiza completamente la creación del paquete por completo. Creo que esto es lo correcto, porque no necesariamente desea realizar un seguimiento aguas arriba. Desafortunadamente, no se ha mantenido por un tiempo, pero alguien lo asumió recientemente, por lo que debería estar de regreso y mejorar en algún momento.

    Melpa toma una URL para, por ejemplo, el área EmacsWiki lisp o un repositorio github, y crea un paquete automáticamente a partir de ella. Por lo tanto, suele estar a lo sumo un día menos de lo que está rastreando. Aunque rastrea aguas arriba, nunca he tenido un problema en la práctica, y aquí es de donde provienen la mayoría de mis paquetes. También está Melpa Stable , que es como Melpa pero toma revisiones etiquetadas del repositorio ascendente en lugar de la última revisión. Melpa estable tiene menos paquetes que Melpa.

    El modo Org tiene su propio package.elrepositorio ( http://orgmode.org/elpa/ ).

    Todos los repositorios de paquetes funcionan igual, solo los agrega a su package-archives.

    Aquí hay una publicación de blog más detallada sobre este tema, con la que estoy más de acuerdo.

  3. No estoy seguro, pero creo que si un paquete se duplica en repositorios diferentes, el orden en que aparecen los repos package-archivesdetermina la prioridad. No sé si hay mayor prioridad al principio o al final de la lista.

    Actualización: en Emacs 25, hay una variable package-archive-prioritiesque puede usar para priorizar los repositorios de sus paquetes (por ejemplo, prefiere ELPA sobre MELPA).


Aquí está la sección relevante de mi init.el, si está interesado:

(setq jpk-packages
      '(
        ac-dabbrev
        ...
        yasnippet
        ))

(package-initialize)
(add-to-list 'package-archives
             '("melpa" . "http://melpa.org/packages/"))
(add-to-list 'package-archives
             '("org" . "http://orgmode.org/elpa/"))

;; install any packages in jpk-packages, if they are not installed already
(let ((refreshed nil))
  (when (not package-archive-contents)
    (package-refresh-contents)
    (setq refreshed t))
  (dolist (pkg jpk-packages)
    (when (and (not (package-installed-p pkg))
             (assoc pkg package-archive-contents))
      (unless refreshed
        (package-refresh-contents)
        (setq refreshed t))
      (package-install pkg))))

(defun package-list-unaccounted-packages ()
  "Like `package-list-packages', but shows only the packages that
  are installed and are not in `jpk-packages'.  Useful for
  cleaning out unwanted packages."
  (interactive)
  (package-show-package-list
   (remove-if-not (lambda (x) (and (not (memq x jpk-packages))
                            (not (package-built-in-p x))
                            (package-installed-p x)))
                  (mapcar 'car package-archive-contents))))
jpkotta
fuente
2
¡Gracias! ¿Qué hace el when (not package-archive-contents)cheque?
Amelio Vazquez-Reina
3
El condicional evita la actualización cada vez que inicio emacs (por lo general, solo quiero que verifique cuando se lo indique). Solo verifica si no hay archivos de paquetes, lo que debería ser el caso la primera vez que clono mi configuración en una nueva máquina.
jpkotta
Solo para hacerle saber la respuesta de @Brandy Trainor, que parece complementar su respuesta, en caso de que sea útil.
Amelio Vazquez-Reina
Creo que esto debe llamar (refresh-package-contents)incondicionalmente antes de descargar nuevos paquetes, ya que de lo contrario Emacs puede intentar descargar una versión anterior del paquete (que para entonces es 404), fallar y dejar de cargar.
Vladimir Panteleev
¿Cuál es la mejor manera de entender qué paquete no es deseado? @jpkotta
Alper
103

Dentro de Emacs, use M-x list-packagespara enumerar todos los paquetes que actualizarán automáticamente el contenido del archivo. Luego, use Upara marcar todos los paquetes actualizables que se actualizarán y xpara realizar las nuevas actualizaciones. Luego, Emacs buscará e instalará todas las actualizaciones, y luego le preguntará si desea eliminar las versiones antiguas y obsoletas.

También es posible que desee echar un vistazo a Carton, que proporciona una forma más conveniente de administrar sus paquetes declarándolos en un archivo dedicado e incluye un conveniente cliente de línea de comandos para instalar y actualizar automáticamente los paquetes declarados de esta manera.


El orden de package-archivesno no importa. Emacs agrega el contenido de todos los archivos en una sola lista coherente de paquetes disponibles y sus versiones, almacenados en package-archive-contents.

Luego package-install, Emacs simplemente elegirá la versión más reciente de un paquete, independientemente del archivo de origen. Para un mayor control sobre el origen del paquete, MELPA proporciona el paquete melpa que permite incluir paquetes en la lista negra o en la lista blanca desde archivos específicos.

Lunaryorn
fuente
2
Eso S-upara ser más preciso.
Lenar Hoyt
@mcb ¿Qué hay S-u? El menú del paquete no usa ese enlace.
lunaryorn
2
Quiero decir Shift-ucon eso.
Lenar Hoyt
8
@mcb Bueno, por eso escribí una U mayúscula l
lunaryorn
1
Es solo para los confundidos como yo que piensan que esto significa <kbd> U </kbd>.
Lenar Hoyt
23

En terminal:

emacs

M-x list-packages

esto te pone en el búfer * paquetes *

shift-u x

emacs le preguntará (sí / no), espere actualizaciones

C-x k <ret>

esto matará el búfer * paquetes * y lo regresará a * scratch *

C-x-C-c

esto saldrá de emacs y le permitirá reiniciar vía, pero es posible que deba depurar :(

emacs

my 2 ¢

rezwits
fuente
Obtuve "sin comando especificado" o algo así cuando escribí "U". Después de ejecutar M-x package-refresh-contents, me solicitó que escriba "U" para marcar todo para la actualización, y luego pude escribir "x" para ejecutar las actualizaciones.
MrColes
2

Este es más un comentario extendido sobre la respuesta de jpkotta.

Este es un ajuste con el que estoy experimentando para la respuesta de jpkotta anterior:

(setq n 0)                                  ; set n as 0
(dolist (pkg pkgs-2b-present)               ; for each pkg in list
  (unless (or                               ; unless
           (package-installed-p pkg)        ; pkg is installed or
           (assoc pkg                       ; pkg is in the archive list
                  package-archive-contents))
    (setq n (+ n 1))))                      ; add one to n
(when (> n 0)                               ; if n > 0, 
  (package-refresh-contents))               ; refresh packages

(reemplazando (when (not package-archive-contents) (package-refresh-contents))).

La lista de paquetes no se actualizaba con la frecuencia suficiente para mi caso de uso.

No he considerado si hay una solución más eficiente para mi problema; primero, tengo que ver si el problema desaparece con este ajuste.

Brady Trainor
fuente
En mi respuesta, package-archive-contentsse actualiza solo si no existe. La idea es que copie su .emacs.d en una nueva máquina e instale automáticamente todos sus paquetes, pero después de eso debe actualizarlo manualmente. Intento actualizar aproximadamente una vez cada dos semanas. Supongo que agregó un paquete a su lista, pero ¿ package-archive-contentsera demasiado viejo para tenerlo?
jpkotta
@jpkotta, tengo un arranque dual, cada uno con su configuración predeterminada ~/.emacs.d/elpa/para la ubicación de los paquetes. Sin embargo, mi versión de su paquete de código de instalación está en una "tercera" partición, ( e:/emacs-configo /e/emacs-config/). Entonces agrego un paquete a la lista mientras estoy en un sistema operativo, y debería actualizarse cuando lo cargue Emacsen el otro sistema operativo. Seguramente hay algún elemento de exageración en mi solución, pero parece estar funcionando al menos.
Brady Trainor
@jpkotta, por qué mi package-archive-contentsparecía estar tan fuera de control se me escapa. Ese es un problema que no limité. Si busco y encuentro una solución "más elegante" en el futuro, la agregaré a mi publicación.
Brady Trainor
1
(package-refresh-contents)escribe a ~/.emacs.d/elpa/archives. No está claro si tiene ese directorio compartido entre sistemas operativos. Recomiendo no compartir los elpa/directorios, porque el código de elpa/bytes de Emacs (el código está compilado por bytes) no es compatible con versiones anteriores ( gnu.org/software/emacs/manual/html_node/elisp/… ). Debería asegurarse de que ambas instalaciones tengan la misma versión de Emacs. Mantengo mi .emacs.dcontrol de versiones y sincronizo diferentes instalaciones con eso.
jpkotta