Użycie package.el do instalacji i aktualizacji, ale use-package do załadowania i konfiguracji

15

Po niedawnym zapoznaniu się z use-packagetym zdecydowałem się na przeniesienie do niego konfiguracji, ale nie chciałem rezygnować z wygody package.elinstalowania pakietów i aktualizowania ich. Uważam, że to trochę trudne do połączenia use-packagei package.el.

Zasadniczo jestem zainteresowany nauczeniem się, jak ludzie łączą się use-packagez package.elsystemem, ale aby uzyskać bardziej szczegółowe pytanie, czytaj dalej.

Oto czego chcę:

  1. Aby pakiety zostały zainstalowane przez menedżera pakietów, dzięki czemu mogę łatwo przeglądać pakiety i aktualizować je list-packages.
  2. Aby skonfigurować i ładować pakiety wyłącznie przez use-package, dzięki czemu mogę łatwo zobaczyć w moim pliku init dokładnie to, co ładuję i jak to jest skonfigurowane.
  3. Opcjonalnie, chciałbym być w stanie zainstalować pakiety poprzez use-package„s :ensuresłowa kluczowego.

Jeśli dobrze rozumiem, bardzo mało chcę tego, co package-initializerobi, w zasadzie tylko sposób, w jaki to konfiguruje load-path. Obecnie mam to w mojej konfiguracji:

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

Pierwsza komentowana linia jest taka, że ​​Emacs 25 nie dodaje pomocniczo (package-initialize)do mojego pliku init. Bit z normal-top-level-add-subdirs-to-load-pathjest przybliżeniem tego package-initialize, co by czyniło load-path, przybliżeniem, które wydaje się wystarczająco dobre.

To wydaje się spełniać moje pragnienia 1 i 2, ale nie 3. Jeśli spróbuję użyć :ensure, pojawi się komunikat o błędzie informujący, że package.elnie został zainicjowany. Wywołanie package-initializeto naprawiłoby to, ale chcę tego uniknąć, ponieważ a) nie chcę, aby ładowane były wszystkie niezliczone autoloady (wolę use-packagetworzyć dokładnie te autoloady, których potrzebuję), i b) chcę mieć możliwość łatwego unikaj ładowania niektórych zainstalowanych pakietów, kiedy tylko chcę (co jest łatwe do zrobienia use-package).

Czy ktoś ma zalecenie, jak to zrobić?

Omar
źródło

Odpowiedzi:

11

IIUC, co chcesz zrobić, to:

(package-initialize t)

Zwróć uwagę na targument, który jest kluczem do twojego szczęścia tutaj, ponieważ zainicjuje (a przynajmniej powinien) zainicjować pakiet.el bez aktywacji wszystkich zainstalowanych pakietów.

Stefan
źródło
1
To odpowiada na moje pytanie, chociaż teraz skłaniam się ku użyciu, package-initializeco sprawia, że ​​moje pytanie jest dyskusyjne.
Omar,
15

Przy obecnej konfiguracji skutecznie wyłączyłeś pakiet.el, ponieważ nie inicjujesz menedżera pakietów i nie uniemożliwiasz Emacsowi automatycznego inicjowania go. W zamian dodajesz ELPA do load-path, ale to tylko niewielki podzbiór tego, co robi pakiet.el. Nie jestem pewien, dlaczego to robisz, ale nie jest to konfiguracja, którą poleciłbym.

W szczególności nie otrzymasz autoloadów pakietów z twoim podejściem, co oznacza, że ​​początkowo żadne polecenia z żadnego pakietu nie będą dostępne.

Innymi słowy, M-xbędzie oferować tylko wbudowane polecenia. Aby dodać poleceń z paczek trzeba by dodać wyraźne :commandsdefinicje wszystkich swoich use-packageoświadczeniach, które sprowadza się do partii konserwacji wysiłku, szczególnie w przypadku dużych pakietów takich jak MAGIT-na zasadzie zerowy przyrost-package.el daje autoloads za darmo .


Łączenie use-packagez pakietem.el jest w rzeczywistości bardzo proste - cała konfiguracja oparta jest na tej kombinacji - ale o wiele lepiej jest pozwolić pakietowi.el faktycznie wykonać swoją pracę. Po prostu zainicjuj pakiet.el na samym początku pliku 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)

Dla wygody możesz później chcieć uruchomić use-package, jeśli nie jest jeszcze zainstalowany:

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

To pozwoli ci rozpocząć sesję Emacsa w nowym systemie, a Twój plik init.el zostanie automatycznie zainstalowany use-package.

Ostatecznie musisz załadować use-package:

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

Teraz możesz użyć use-packagedo zainstalowania i skonfigurowania pakietów:

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

Gdy Emacs oceni teraz ten formularz podczas uruchamiania, use-packagesprawdzi, czy Magit jest już zainstalowany i automatycznie zainstaluje go, jeśli to konieczne.

księżycowy
źródło
3
„Nie jestem pewien, dlaczego to robisz”: jedynym powodem, który widzę, są czasy uruchamiania: package-initializezajmuje trochę czasu, aby zapełnić ścieżkę, zdefiniować automatyczne ładowanie i zrobić resztę rzeczy. Wydaje mi się, że czytałem gdzieś, że sam Jon Wiegley (autor use-package) woli zadeklarować wszystkie automatycznie ładowane polecenia w use-packagezwrotkach zamiast na nich polegać package.el.
François Févotte
Ostatnim razem, gdy patrzyłem, w ogóle nie korzystał z package.el, a poza tym nie sądzę, żebyś dużo zyskał. Musisz wypełnić load-pathi dodać automatyczne ładowanie w obu przypadkach, zarówno przez, jak use-packagei przez package.el. Wątpię, aby istniała mierzalna różnica, szczególnie jeśli masz nowoczesny system z szybkim dyskiem.
lunaryorn
3
Zgoda. Sam wykonałem pomiary. Dzięki szybkiemu dyskowi skutecznie nie widzisz dużej różnicy. Przy wolnym dysku uruchamianie może być zauważalnie wolniejsze (coś w rodzaju 0.2s) package-initializeniż lista niestandardowa load-path. Przypisuję to „eksploracji” systemu plików, który to package.elrobi. Jednak nigdy nie mierzyłem żadnej znaczącej różnicy w wydajności między ładowaniem autoloaddefinicji z plików a umieszczaniem ich w use-packagesekcjach.
François Févotte
Cóż, nie powiedziałbym Mam wyłączone z package.elsystemu, powiedziałbym, że tylko wyłączone package-initialize! Powodem jest to, że chociaż lubię list-packagesprzeglądać nowe pakiety, a szczególnie aktualizować wszystkie aktualnie zainstalowane pakiety, myślę, że wolę ukierunkowane ładowanie use-package. Dla mnie posiadającego automatyczne ładowanie tylko dla poleceń używam dźwięków jak dobrą rzecz!
Omar
1
@ OmarAntolín-Camarena Dlaczego nie? Automatyczne ładowanie jest zasadniczo publicznym interfejsem pakietu skierowanego do użytkownika, a ponieważ pakiet.el stał się standardowym sposobem dystrybucji pakietów, możemy polegać na ich obecności.
lunaryorn