Utilisation de package.el pour installer et mettre à jour mais use-package pour le chargement et la configuration

15

Après avoir récemment pris connaissance de ces informations, use-packagej'ai décidé d'y porter ma configuration, mais je me suis montré réticent à renoncer à la commodité de l'utilisation package.elpour installer des packages et les maintenir à jour. Je l'ai trouvé un peu difficile à combiner use-packageet package.el.

Je suis généralement intéressé à savoir comment les gens se combinent use-packageavec le package.elsystème, mais pour une question plus spécifique, continuez à lire.

Voici ce que je veux:

  1. Pour que les packages soient installés par le gestionnaire de packages afin que je puisse facilement rechercher des packages et les maintenir à jour list-packages.
  2. Pour configurer et charger des packages exclusivement via use-package, afin que je puisse facilement voir dans mon fichier init exactement ce que je charge et comment il est configuré.
  3. En option, j'aimerais également pouvoir installer des packages via use-packagele :ensuremot-clé de.

Si je comprends bien, je veux très peu de ce qui se package-initializepasse, essentiellement la façon dont il configure le load-path. Actuellement, j'ai ceci dans ma configuration:

;(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 première ligne, commentée, est donc Emacs 25 n'ajoute pas utilement un (package-initialize)à mon fichier init. Le bit avec normal-top-level-add-subdirs-to-load-pathest une approximation de ce package-initializequi ferait le load-path, une approximation qui semble assez bonne.

Cela semble réaliser mes désirs 1 et 2, mais pas 3. Si j'essaye d'utiliser :ensure, j'obtiens un message d'erreur disant que ce package.eln'est pas initialisé. L'appel package-initializerésoudrait cela, mais je souhaite éviter cela car a) je ne veux pas que toutes les myriades de chargements automatiques soient chargés (je préfère utiliser use-packagepour créer précisément les chargements automatiques dont j'ai besoin), et b) je veux pouvoir facilement évitez de charger certains packages installés quand je veux (ce qui est facile à faire use-package).

Quelqu'un at-il une recommandation sur la façon de procéder?

Omar
la source

Réponses:

11

IIUC ce que vous voulez faire est:

(package-initialize t)

Notez l' targument, qui est la clé de votre bonheur ici car il va (ou devrait au moins) initialiser package.el sans activer tous les packages installés.

Stefan
la source
1
Cela répond à ma question, même si maintenant je penche pour l'utilisation, package-initializece qui rend ma question théorique.
Omar
15

Avec votre configuration actuelle, vous avez effectivement désactivé package.el, car vous n'initialisez pas le gestionnaire de packages et empêchez Emacs de l'initialiser automatiquement. Tout ce que vous faites en retour est d'ajouter ELPA à la load-path, mais ce n'est qu'un petit sous-ensemble de ce que fait package.el. Je ne sais pas pourquoi vous faites cela, mais ce n'est pas une configuration que je recommanderais.

Plus précisément, vous n'obtiendrez pas de chargement automatique des packages avec votre approche, ce qui signifie qu'au départ, aucune commande d'aucun package ne sera disponible.

En d'autres termes, M-xne vous offrira que des commandes intégrées. Pour ajouter des commandes à partir de vos packages, vous devez ajouter des :commandsdéfinitions explicites à toutes vos use-packagedéclarations, ce qui représente beaucoup d'efforts de maintenance - en particulier pour les gros packages tels que Magit - pour un gain essentiellement nul - package.el vous offre des chargements automatiques gratuits .


La combinaison use-packageavec package.el est en fait très simple - toute l'installation est basée sur cette combinaison - mais il est préférable de laisser package.el faire son travail. Initialisez simplement package.el au tout début de votre fichier 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)

Pour plus de commodité, vous pouvez par la suite vouloir démarrer use-package, s'il n'est pas déjà installé:

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

Cela vous permet de démarrer une session Emacs sur un nouveau système et votre init.el s'installera automatiquement use-package.

En fin de compte, vous devez charger use-package:

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

Vous pouvez maintenant utiliser use-packagepour installer et configurer des packages:

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

Lorsque Emacs évalue maintenant ce formulaire au démarrage, use-packagevérifie si Magit est déjà installé et l'installe automatiquement si nécessaire.

lunaryorn
la source
3
"Je ne sais pas pourquoi vous faites cela": la seule raison que je peux voir est à propos des temps de démarrage: package-initializeprend un certain temps pour remplir le chemin, définir les chargements automatiques et faire le reste. Je pense avoir lu quelque part que Jon Wiegley lui-même (l'auteur de use-package) préfère déclarer toutes les commandes chargées automatiquement dans les use-packagestrophes plutôt que de se fier à lui package.el.
François Févotte
La dernière fois que j'ai regardé, il n'a pas du tout utilisé package.el, et en tout cas, je ne pense pas que vous gagnerez beaucoup. Vous devez remplir load-pathet ajouter des chargements automatiques dans les deux cas, via use-packageou via package.el. Je doute qu'il y ait une différence mesurable, en particulier si vous avez un système moderne avec un disque rapide.
lunaryorn
3
D'accord. J'ai fait le timing moi-même. Avec un disque rapide, vous ne voyez vraiment pas beaucoup de différence. Avec un disque lent, le démarrage peut être sensiblement plus lent (quelque chose comme 0,2 s) qu'avec package-initializeune liste personnalisée dans load-path. J'attribue cela à "l'exploration" du système de fichiers qui le package.elfait. Cependant, je n'ai jamais mesuré de différence significative de performances entre le chargement de autoloaddéfinitions à partir de fichiers et leur mise en use-packagestrophes.
François Févotte
Eh bien, je ne dirais pas que j'ai désactivé le package.elsystème, je dirais que je l'ai seulement désactivé package-initialize! La raison en est que même si j'aime list-packagesparcourir de nouveaux packages et spécialement pour mettre à jour tous mes packages actuellement installés, je pense que je préfère le chargement ciblé de use-package. Pour moi, ayant des chargements automatiques uniquement pour les commandes, j'utilise des sons comme une bonne chose!
Omar
1
@ OmarAntolín-Camarena Pourquoi pas? Les chargements automatiques sont essentiellement l'interface publique d'un package accessible aux utilisateurs, et depuis que package.el est devenu le moyen standard de distribuer les packages, nous pouvons compter sur leur présence.
lunaryorn