Usando package.el para instalar e atualizar, mas use-package para carregar e configurar

15

Depois de aprender recentemente, use-packagedecidi portar minha configuração, mas me senti relutante em desistir da conveniência de usar package.elpara instalar pacotes e mantê-los atualizados. Eu achei um pouco complicado de combinar use-packagee package.el.

Geralmente, estou interessado em aprender como as pessoas se combinam use-packagecom o package.elsistema, mas para uma pergunta mais específica, continue lendo.

Aqui está o que eu quero:

  1. Ter pacotes instalados pelo gerenciador de pacotes para que eu possa navegar facilmente por pacotes e mantê-los atualizados list-packages.
  2. Para configurar e carregar pacotes exclusivamente use-package, para que eu possa ver facilmente no meu arquivo init exatamente o que estou carregando e como está configurado.
  3. Opcionalmente, eu também gostaria de poder instalar pacotes através use-packageda :ensurepalavra-chave.

Se estou entendendo corretamente, quero muito pouco do que package-initializefaz, basicamente apenas da maneira como configura o load-path. Atualmente eu tenho isso na minha configuração:

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

A primeira linha comentada é para que o Emacs 25 não adicione uma útil (package-initialize)ao meu arquivo de inicialização. A parte com normal-top-level-add-subdirs-to-load-pathé uma aproximação do que package-initializefaria a load-path, uma aproximação que parece boa o suficiente.

Isso parece alcançar meus desejos 1 e 2, mas não 3. Se eu tentar usar :ensure, recebo uma mensagem de erro dizendo que package.elnão foi inicializado. A chamada package-initializeresolveria isso, mas desejo evitar isso, já que a) não quero que todas as inúmeras cargas automáticas sejam carregadas (prefiro usar use-packagepara criar com precisão as cargas automáticas necessárias) eb) desejo poder facilmente evite carregar certos pacotes instalados sempre que eu quiser (o que é fácil de fazer use-package).

Alguém tem uma recomendação de como fazer isso?

Omar
fonte

Respostas:

11

IIUC o que você quer fazer é:

(package-initialize t)

Observe o targumento, que é a chave da sua felicidade aqui, pois ele (ou deve, pelo menos) inicializar o package.el sem ativar todos os pacotes instalados.

Stefan
fonte
11
Isso responde à minha pergunta, embora agora eu esteja inclinado a usar o package-initializeque torna minha pergunta discutível.
Omar
15

Com sua configuração atual, você desabilitou efetivamente o package.el, pois não inicializa o gerenciador de pacotes e impede que o Emacs o inicialize automaticamente. Tudo o que você faz em troca é adicionar o ELPA ao load-path, mas isso é apenas um pequeno subconjunto do que o package.el faz. Não sei por que você faz isso, mas não é uma configuração que eu recomendo.

Especificamente, você não receberá carregamentos automáticos de pacotes com sua abordagem, o que significa que, inicialmente, nenhum comando de nenhum pacote estará disponível.

Em outras palavras, M-xoferecerá apenas comandos internos. Para adicionar comandos de seus pacotes, você teria que adicionar :commandsdefinições explícitas a todas as suas use-packagedeclarações, o que equivale a muito esforço de manutenção - principalmente para pacotes grandes como o Magit - para ganho praticamente zero - package.el oferece carregamentos automáticos gratuitamente .


Combinar use-packagecom o package.el é realmente muito simples - toda a configuração é baseada nessa combinação - mas é muito melhor deixar o package.el realmente funcionar. Apenas inicialize o package.el no início do seu arquivo 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)

Por conveniência, você pode querer inicializar use-package, se ainda não estiver instalado:

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

Isso permite que você inicie uma sessão do Emacs em um sistema novo, e o init.el será instalado automaticamente use-package.

Por fim, você precisa carregar use-package:

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

Agora você pode usar use-packagepara instalar e configurar pacotes:

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

Quando o Emacs agora avaliar esse formulário durante a inicialização, use-packageverificará se o Magit já está instalado e o instalará automaticamente, se necessário.

lunaryorn
fonte
3
"Não sei por que você faz isso": a única razão que vejo é sobre o tempo de inicialização: package-initializeleva algum tempo para preencher o caminho, definir carregamentos automáticos e fazer o resto. Acho que li em algum lugar que o próprio Jon Wiegley (o autor de use-package) prefere declarar todos os comandos carregados automaticamente em use-packageestrofes, em vez de confiar package.el.
François Févotte 22/09/2015
Da última vez que olhei, ele não usava package.el e, de qualquer forma, acho que você não ganhará muito. Você precisa preencher load-pathe adicionar carregamentos automáticos nos dois casos, seja via use-packageou via package.el. Duvido que exista uma diferença mensurável, principalmente se você tiver um sistema moderno com um disco rápido.
lunaryorn 22/09/2015
3
Acordado. Eu mesmo fiz os horários. Com um disco rápido, você efetivamente não vê muita diferença. Com um disco lento, a inicialização pode ser notavelmente mais lenta (algo como 0,2s) com package-initializeuma lista personalizada load-path. Atribuo isso à "exploração" do sistema de arquivos que package.elfaz. No entanto, nunca medi nenhuma diferença significativa no desempenho entre carregar autoloaddefinições de arquivos e colocá-las em use-packageestrofes.
François Févotte 22/09
Bem, eu não diria que desabilitei o package.elsistema, diria que apenas desabilitei package-initialize! O motivo é que, embora eu goste list-packagesde procurar novos pacotes e principalmente atualizar todos os meus pacotes atualmente instalados, acho que prefiro o carregamento direcionado de use-package. Para mim, tendo autoloads apenas para comandos, uso sons como uma coisa boa!
Omar
11
@ OmarAntolín-Camarena Por que não? Os carregamentos automáticos são essencialmente a interface pública de um pacote voltado para o usuário e, desde que package.el se tornou a maneira padrão de distribuir pacotes, podemos confiar na presença deles.
Lunardorn 5/10