Aggiornamento dei pacchetti in Emacs


144

Ho la seguente configurazione per i pacchetti (non sono sicuro se ce n'è uno meglio consigliato):

(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)

Ho tre domande relative all'installazione e all'aggiornamento dei pacchetti.

Q1. C'è un modo per aggiornare l'elenco dei pacchetti disponibili (e le versioni più recenti) e aggiornare un pacchetto specifico?

Q.2 Qual è la differenza tra le seguenti fonti del pacchetto:

  • ELPA,
  • GNU
  • marmellata
  • Melpa

Q.3 Importa l'ordine in cui vengono aggiunti package-archives?


13
MELPA è necessario per il completamento automatico poiché ovviamente nessuno si è preoccupato di rendere disponibile il completamento automatico su Marmalade. Non preoccuparti, ma piuttosto ripulisci il tuo package-archives. Sbarazzarsi dell'archivio ELPA, che non è più gestito, e dell'archivio marmellata, che è un casino di pacchetti obsoleti e duplicati senza una chiara guida e manutenzione. Usa solo l'archivio GNU standard e MELPA>
lunaryorn,

2
Grazie @lunaryorn! Questo è molto utile. Sai come potrei rimanere informato su cose come questa? (ovvero "cose ​​buone da sapere" come queste mentre Emacs evolve)
Amelio Vazquez-Reina,

3
Le informazioni fluiscono liberamente nel Web, basta catturarle: segui / emacs su Reddit, segui i blog e twitter di emacs famosi come Nic Ferrier, Bozhidar Batsov, Magnar Sveen, John Wiegley, ecc., Unisciti a #emacs su Freenode IRC, e molti altri.
lunaryorn,

3
Dovresti (setq package-enable-at-startup nil)se hai intenzione di chiamarti (package-initialize).
phils,

2
Grazie @phils - Perché è necessario?
Amelio Vazquez-Reina

Risposte:


163
  1. Per aggiornare automaticamente l'elenco dei pacchetti, solo se non esiste già un elenco di pacchetti , utilizzare quanto segue:

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

    Per aggiornare tutti i pacchetti installati, digita package-list-packages, che ti porterà al *Packages*buffer (e aggiorna anche l'elenco dei pacchetti), quindi digita U x.

    package-refresh-contentstenta incondizionatamente di scaricare un elenco di pacchetti da tutti i repository a cui hai aggiunto package-archives; package-archive-contentsè nullo se hai già scaricato l'elenco dei pacchetti.

  2. ELPA è l'originale. Non penso che sia più mantenuto, ma non ne sono sicuro. Non lo uso.

    GNU è "ufficiale". È gestito insieme a Emacs, il che significa che le cose dovrebbero sempre funzionare ma gli aggiornamenti e i nuovi pacchetti non arrivano molto spesso.

    Marmalade è fondamentalmente un sito Web in cui è possibile caricare un pacchetto completo e verrà aggiunto al repository marmalade. Non si invia semplicemente un collegamento all'upstream del pacchetto e non si automatizza completamente la creazione del pacchetto. Penso che questa sia la cosa giusta, perché non vuoi necessariamente tracciare a monte. Sfortunatamente, non è stato mantenuto per un po ', ma qualcuno ha recentemente preso il controllo, quindi dovrebbe essere tornato e meglio ad un certo punto.

    Melpa prende un URL, ad esempio l'area lisp di EmacsWiki o un repository github, e crea automaticamente un pacchetto da esso. Quindi di solito è al massimo un giorno dietro qualunque cosa stia monitorando. Sebbene segua a monte, non ho mai avuto problemi in pratica, ed è qui che proviene la maggior parte dei miei pacchetti. C'è anche Melpa Stable , che è come Melpa ma afferra le revisioni con tag del repository upstream invece dell'ultima revisione. Melpa stable ha meno pacchetti di Melpa.

    La modalità Org ha un proprio package.elrepository ( http://orgmode.org/elpa/ ).

    Tutti i repository di pacchetti funzionano allo stesso modo, basta aggiungerli al proprio package-archives.

    Ecco un post sul blog più approfondito su questo argomento, che sono per lo più d'accordo.

  3. Non sono sicuro, ma penso che se un pacchetto viene duplicato in repository diversi, l'ordine in cui compaiono i repository package-archivesdetermina la precedenza. Non so se una precedenza maggiore sia all'inizio o alla fine dell'elenco.

    Aggiornamento: in Emacs 25, esiste una variabile package-archive-prioritiesche è possibile utilizzare per dare priorità ai repository dei pacchetti (ad es. Preferire ELPA a MELPA).


Ecco la sezione pertinente del mio init.el, se sei interessato:

(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))))

2
Grazie! Cosa when (not package-archive-contents)controlla?
Amelio Vazquez-Reina,

3
Il condizionale impedisce l'aggiornamento ogni volta che avvio emacs (di solito voglio solo controllarlo quando lo dico). Controlla solo se non ci sono archivi di pacchetti, il che dovrebbe essere il caso solo la prima volta che clonerò la mia configurazione su una nuova macchina.
jpkotta,

Ti sto solo informando della risposta di @Brandy Trainor, che sembra integrare la tua risposta, nel caso sia utile.
Amelio Vazquez-Reina

Penso che questo debba chiamare (refresh-package-contents)incondizionatamente prima di scaricare nuovi pacchetti, altrimenti Emacs potrebbe provare a scaricare una vecchia versione del pacchetto (che allora è una 404), fallire e interrompere il caricamento.
Vladimir Panteleev,

Qual è il modo migliore per capire quale pacchetto è indesiderato? @jpkotta
Alper

103

All'interno di Emacs, usa M-x list-packagesper elencare tutti i pacchetti che aggiorneranno automaticamente il contenuto dell'archivio. Successivamente, utilizzare Uper contrassegnare tutti i pacchetti aggiornabili da aggiornare e xper eseguire effettivamente i nuovi aggiornamenti. Emacs quindi recupererà e installerà tutti gli aggiornamenti e ti chiederà se rimuovere le vecchie versioni obsolete in seguito.

Puoi anche dare un'occhiata a Carton che fornisce un modo più conveniente per gestire i tuoi pacchetti dichiarandoli in un file dedicato e include un comodo client da riga di comando per installare e aggiornare automaticamente i pacchetti dichiarati in questo modo.


L'ordine di package-archivesnon ha importanza. Emacs aggrega i contenuti di tutti gli archivi in ​​un unico elenco coerente dei pacchetti disponibili e delle loro versioni, archiviati in package-archive-contents.

Dopo package-install, Emacs sceglierà semplicemente la versione più recente di un pacchetto, indipendentemente dall'archivio di origine. Per un maggiore controllo sull'origine dei pacchetti, MELPA fornisce il pacchetto melpa che consente di inserire nella blacklist o nella whitelist i pacchetti dagli archivi specificati.


2
Questo S-uper essere più precisi.
Lenar Hoyt,

@mcb Cos'è S-u? Il menu del pacchetto non utilizza tale associazione.
lunaryorn,

2
Voglio dire Shift-ucon quello.
Lenar Hoyt,

8
@mcb Bene, ecco perché ho scritto una U maiuscola
lunaryorn il

1
È solo per quelli confusi come me che pensano che questo significhi <kbd> U </kbd>.
Lenar Hoyt,

23

Nel terminal:

emacs

M-x list-packages

questo ti mette nel buffer * pacchetti *

shift-u x

emacs ti chiederà (sì / no) di attendere gli aggiornamenti

C-x k <ret>

questo ucciderà il buffer * pacchetti * e ti riporterà a * scratch *

C-x-C-c

questo uscirà da emacs e ti consentirà di riavviare tramite, ma potresti dover eseguire il debug :(

emacs

il mio 2 ¢


Ho ricevuto "nessun comando specificato" o qualcosa del genere quando ho digitato "U". Dopo l'esecuzione M-x package-refresh-contents, mi ha spinto a digitare "U" per contrassegnare tutto per l'aggiornamento, quindi sono stato in grado di digitare "x" per eseguire gli aggiornamenti.
MrColes,

2

Questo è più di un commento esteso sulla risposta di jpkotta.

Questa è una correzione con cui sto sperimentando per la risposta di jpkotta sopra:

(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

(in sostituzione (when (not package-archive-contents) (package-refresh-contents))).

L'elenco dei pacchetti non si aggiornava abbastanza spesso abbastanza per il mio caso d'uso.

Non ho considerato se esiste una soluzione più efficiente al mio problema; per prima cosa, devo vedere se il problema scompare con questa regolazione.


Nella mia risposta, package-archive-contentsviene aggiornato solo se non esiste. L'idea è che copi il tuo .emacs.d su una nuova macchina e che installi automaticamente tutti i tuoi pacchetti, ma dopo devi aggiornare manualmente. Provo ad aggiornare circa una volta ogni due settimane. Immagino che tu abbia aggiunto un pacchetto alla tua lista, ma tu eri package-archive-contentstroppo vecchio per averlo?
jpkotta,

@jpkotta, ho un doppio avvio, ognuno dei quali utilizza il proprio valore predefinito ~/.emacs.d/elpa/per l'ubicazione dei pacchetti. Tuttavia, la mia versione del codice di installazione del pacchetto è in una "terza" partizione ( e:/emacs-configo /e/emacs-config/). Quindi aggiungo un pacchetto all'elenco mentre mi trovo in un sistema operativo e dovrebbe essere aggiornato quando carico Emacsun altro sistema operativo. Sicuramente c'è qualche elemento di eccessivo nella mia soluzione, ma sembra funzionare almeno.
Brady Trainor,

@jpkotta, il motivo per cui il mio package-archive-contentssembrava possibilmente essere così fuori di testa mi sfugge. Questo è un problema che non ho ristretto. Se cerco e trovo una soluzione "più elegante" in futuro, la aggiungerò al mio post.
Brady Trainor,

1
(package-refresh-contents)scrive a ~/.emacs.d/elpa/archives. Non è chiaro se la directory è condivisa tra i sistemi operativi. Consiglio di non condividere le elpa/directory, perché il bytecode Emacs (il codice in elpa/è bytecompiled) non è retrocompatibile ( gnu.org/software/emacs/manual/html_node/elisp/… ). Dovresti assicurarti che entrambe le installazioni abbiano la stessa versione di Emacs. Tengo il mio .emacs.dcontrollo della versione e sincronizzo diverse installazioni con quello.
jpkotta,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.