Menggunakan package.el untuk menginstal dan memperbarui tetapi menggunakan paket untuk memuat dan mengkonfigurasi

15

Setelah baru-baru ini belajar tentang use-packagesaya memutuskan untuk port konfigurasi saya untuk itu tetapi menemukan diri saya enggan untuk memberikan kemudahan menggunakan package.elmenginstal paket dan tetap memperbaruinya. Saya merasa agak sulit untuk menggabungkan use-packagedan package.el.

Saya umumnya tertarik mempelajari bagaimana orang-orang bergabung use-packagedengan package.elsistem, tetapi untuk pertanyaan yang lebih spesifik, teruslah membaca.

Inilah yang saya inginkan:

  1. Untuk memiliki paket yang diinstal oleh manajer paket sehingga saya dapat dengan mudah menelusuri paket dan terus memperbaruinya list-packages.
  2. Untuk mengkonfigurasi dan memuat paket secara eksklusif use-package, jadi saya dapat dengan mudah melihat di file init saya persis apa yang saya muat dan bagaimana hal itu dikonfigurasi.
  3. Opsional, saya ingin juga dapat menginstal paket melalui use-package's :ensurekata kunci.

Jika saya mengerti dengan benar saya ingin sedikit dari apa yang package-initializedilakukan, pada dasarnya hanya cara mengatur load-path. Saat ini saya memiliki ini dalam konfigurasi saya:

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

Baris pertama, yang dikomentari, adalah agar Emacs 25 tidak membantu menambahkan (package-initialize)file init saya. Bit with normal-top-level-add-subdirs-to-load-pathadalah aproksimasi terhadap apa yang package-initializeakan membuat load-path, aproksimasi yang tampaknya cukup baik.

Ini tampaknya mencapai keinginan saya 1 dan 2, tetapi tidak 3. Jika saya mencoba menggunakan :ensure, saya mendapatkan pesan kesalahan yang mengatakan bahwa package.elitu tidak diinisialisasi. Memanggil package-initializeakan memperbaikinya, tetapi saya ingin menghindari itu karena a) Saya tidak ingin semua autoload yang sangat banyak dimuat (saya lebih suka menggunakan use-packageuntuk membuat secara tepat autoload yang saya butuhkan), dan b) Saya ingin dapat dengan mudah hindari memuat paket yang diinstal tertentu kapan pun saya mau (yang mudah dilakukan use-package).

Adakah yang punya rekomendasi untuk bagaimana melakukan ini?

Omar
sumber

Jawaban:

11

IIUC yang ingin Anda lakukan adalah:

(package-initialize t)

Catat targumennya, yang merupakan kunci kebahagiaan Anda di sini karena ini akan (atau paling tidak, harus menginisialisasi package.el tanpa mengaktifkan semua paket yang diinstal.

Stefan
sumber
1
Ini menjawab pertanyaan saya, meskipun sekarang saya cenderung menggunakan package-initializeyang membuat pertanyaan saya diperdebatkan.
Omar
15

Dengan konfigurasi Anda saat ini, Anda telah secara efektif menonaktifkan package.el, karena Anda tidak menginisialisasi manajer paket dan mencegah Emacs menginisialisasi secara otomatis. Yang Anda lakukan sebagai gantinya adalah menambahkan ELPA ke load-path, tapi itu hanya sebagian kecil dari apa yang dilakukan package.el. Saya tidak yakin mengapa Anda melakukan itu, tetapi ini bukan pengaturan yang saya sarankan.

Khususnya, Anda tidak akan mendapatkan autoload paket dengan pendekatan Anda, yang berarti pada awalnya tidak ada perintah dari paket apa pun yang akan tersedia.

Dengan kata lain, M-xhanya akan menawarkan Anda perintah bawaan. Untuk menambahkan perintah dari paket Anda, Anda harus menambahkan :commandsdefinisi eksplisit untuk semuause-package deklarasi Anda , yang berarti banyak upaya pemeliharaan - terutama untuk paket besar seperti Magit - untuk dasarnya nol kenaikan - package.el memberi Anda autoloads gratis .


Menggabungkan use-packagedengan package.el sebenarnya sangat sederhana — seluruh pengaturan didasarkan pada kombinasi ini — tetapi jauh lebih baik membiarkan package.el benar-benar melakukan tugasnya. Inisialisasinya package.el di awal file init Anda:

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

Untuk kenyamanan Anda selanjutnya ingin bootstrap use-package, jika belum diinstal:

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

Ini memungkinkan Anda memulai sesi Emacs pada sistem yang baru, dan init.el Anda akan secara otomatis menginstal use-package.

Pada akhirnya Anda perlu memuat use-package:

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

Sekarang Anda dapat menggunakan use-packageuntuk menginstal dan mengkonfigurasi paket:

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

Ketika Emacs sekarang mengevaluasi formulir ini selama startup, use-packageakan memeriksa apakah Magit sudah diinstal, dan secara otomatis menginstalnya jika perlu.

lunaryorn
sumber
3
"Saya tidak yakin mengapa Anda melakukan itu": satu-satunya alasan yang dapat saya lihat adalah tentang waktu startup: package-initializemembutuhkan waktu untuk mengisi path, menentukan autoloads, dan melakukan sisanya. Saya pikir saya membaca di suatu tempat bahwa Jon Wiegley sendiri (penulis use-package) lebih suka mendeklarasikan semua perintah yang dimuat secara otomatis dalam use-packagebait daripada mengandalkan package.el.
François Févotte
Terakhir kali saya melihat dia tidak menggunakan package.el sama sekali, dan dalam hal apapun, saya pikir Anda tidak akan mendapatkan banyak. Anda perlu mengisi load-pathdan menambahkan pengisian otomatis dalam kedua kasus, baik melalui use-packageatau melalui package.el. Saya ragu bahwa ada perbedaan yang terukur, terutama jika Anda memiliki sistem modern dengan disk cepat.
lunaryorn
3
Sepakat. Saya melakukan timing sendiri. Dengan cakram cepat, Anda secara efektif tidak melihat banyak perbedaan. Dengan disk yang lambat, startup bisa terasa lebih lambat (sekitar 0,2 detik) package-initializedibandingkan daftar kustom load-path. Saya mengaitkan ini dengan "eksplorasi" sistem file yang package.elmelakukannya. Namun, saya tidak pernah mengukur perbedaan yang signifikan dalam kinerja antara memuat autoloaddefinisi dari file dan memilikinya dalam use-packagebait.
François Févotte
Yah, aku tidak akan mengatakan saya sudah dinonaktifkan pada package.elsistem, saya akan mengatakan saya hanya dinonaktifkan package-initialize! Alasannya adalah bahwa walaupun saya suka list-packagesmenelusuri paket-paket baru dan secara khusus memperbarui semua paket yang saya instal saat ini, saya pikir saya lebih suka memuat yang ditargetkan use-package. Bagi saya memiliki autoloads hanya untuk perintah yang saya gunakan terdengar seperti hal yang baik!
Omar
1
@ OmarAntolín-Camarena Mengapa tidak? Autoloads pada dasarnya adalah antarmuka publik dari paket yang menghadap pengguna, dan karena package.el menjadi cara standar untuk mendistribusikan paket, kita dapat mengandalkan keberadaannya.
lunaryorn