Perché devo aggiungere ciascun pacchetto al percorso di caricamento? (o Problema con il requisito richiede nel mio file init)


17

Ogni volta che installo un pacchetto dal menu Pacchetto, se provo ad requireesso nel mio file init ricevo un errore a meno che non lo aggiunga manualmente al percorso di caricamento:

(add-to-list 'load-path "/home/nick/.emacs.d/elpa/use-package-20141220.1645")

(require 'use-package-autoloads)
(require 'use-package)

È noioso. E di solito il percorso del pacchetto contiene numeri di versione. Se un pacchetto è stato aggiornato, devo modificare manualmente il percorso di caricamento.

C'è un modo per automatizzare questo?

Risposte:


23

TL; DR:

Aggiungi la seguente riga all'inizio del file init ( .emacs.d/init.elo .emacs):

(package-initialize)

La spiegazione

Creare più file che Emacs potrebbe usare come l' user-init-fileapproccio non è sicuramente il giusto. Poiché il manuale non dice quale sia preferito in caso di conflitto, almeno non nella parte che hai citato, tutto ciò che serve è aggiungere confusione - ora non sappiamo quale sia effettivamente il user-init-file(il cui valore potresti desiderare ispezionare per scoprirlo).

Quindi inizia rimuovendo tutti i candidati tranne quelli ~/.emacs.d/init.elche sono generalmente preferiti (dagli utenti) perché non contribuiscono al disordinato pasticcio che è $HOMEe consente di mantenere tutti i file di configurazione di Emacs, incluso quello più importante, sotto controllo della versione usando un repository solo per Emacs.

Per impostazione predefinita, Emacs chiama package-initialize dopo aver caricato il file init dell'utente. Lo fa affatto , perché al giorno d'oggi la maggior parte degli utenti installa i propri pacchetti usando package.el- quindi non dovrebbero fare nulla per rendere disponibili questi pacchetti.

D'altra parte non tutti lo fanno, quindi dovrebbe essere possibile non chiamare package-initialize. Impedire che tale funzione venga chiamata viene eseguita aggiungendo (setq package-enable-at-startup nil)al file init dell'utente (dove altro potresti metterlo?).

package-initializenon può essere chiamato prima che l'utente abbia apportato una modifica per dire a Emacs di non farlo, e quindi deve essere fatto dopo aver caricato il file init. Finché l'utente installa solo i pacchetti e li utilizza così come sono o li personalizza utilizzando l'interfaccia personalizzata che funziona perfettamente. Ma se vuoi personalizzare i tuoi pacchetti usando elisp, devi assicurarti che siano effettivamente attivi load-pathprima di usare le funzioni che definiscono.

È abbastanza facile da fare e adeguatamente documentato (se avessi cercato prima quello, non avrei dovuto scrivere la maggior parte di quanto sopra: - /

Il motivo per cui il caricamento automatico del pacchetto si verifica dopo aver caricato il file init è che le opzioni utente ricevono i loro valori personalizzati solo dopo aver caricato il file init, comprese le opzioni utente che influiscono sul sistema di packaging. In alcune circostanze, potresti voler caricare esplicitamente i pacchetti nel tuo file init (di solito perché qualche altro codice nel tuo file init dipende da un pacchetto). In tal caso, il tuo file init dovrebbe chiamare la funzione package-initialize. Spetta a te accertarti che le opzioni utente pertinenti, come package-load-list(vedi sotto), siano impostate prima della package-initializechiamata. Dovresti anche impostare package-enable-at-startupsunil, per evitare di caricare nuovamente i pacchetti dopo l'elaborazione del file init. In alternativa, puoi scegliere di inibire completamente il caricamento del pacchetto all'avvio e invocare il comando "Mx pacchetto-inizializza" per caricare manualmente i tuoi pacchetti.

Così:

;;; .emacs.d/init.el -- the `user-init-file'

(package-initialize)
(setq package-enable-at-startup nil)

(require 'use-package)

(use-package some-package
  :init (setq some-package-variable "foobar")

    ...

;;; .emacs.d/init.el ends here

Naturalmente il problema (o un ulteriore problema) potrebbe anche essere che il refuso Symbol's function definition is void: use-packgeè nel tuo file init e non si è verificato fino a quando non lo hai digitato in emacs.se.



Va bene usare (require 'use-package)prima (package-initialize)?
力 力

3

Penso che la after-init-hooksoluzione menzionata in questa risposta di overflow dello stack debba essere menzionata:

(defun my-packages-init ()
  (require 'some-great-package))

(add-hook 'after-init-hook 'my-packages-init)

Pensavo che fosse così che doveva essere fatto, ma le altre risposte forniscono informazioni su altri modi per farlo.


0

Quanto segue aggiunge tutte le directory sotto ~/.emacs.d/site-lispal percorso di caricamento, quindi puoi solo requireil pacchetto e il gioco è fatto:

(let* ((my-lisp-dir "~/.emacs.d/site-lisp/")
       (default-directory my-lisp-dir)
       (orig-load-path load-path))
  (setq load-path (cons my-lisp-dir nil))
  (normal-top-level-add-subdirs-to-load-path)
  (nconc load-path orig-load-path))
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.