Atualizando pacotes no Emacs

144

Eu tenho a seguinte configuração para pacotes (não tenho certeza se há uma melhor recomendada):

(require 'package)
(setq package-archives '(("ELPA" . "http://tromey.com/elpa/") 
                          ("gnu" . "http://elpa.gnu.org/packages/")
                          ("marmalade" . "http://marmalade-repo.org/packages/")))

; Apparently needed for the package auto-complete (why?)
(add-to-list 'package-archives
             '("melpa" . "http://melpa.milkbox.net/packages/") t)

(package-initialize)
(setq url-http-attempt-keepalives nil)

Eu tenho três perguntas relacionadas à instalação e atualização de pacotes.

Q1 Existe uma maneira de atualizar a lista de pacotes disponíveis (e versões mais recentes) e atualizar um pacote específico?

Q.2 Qual é a diferença entre as seguintes fontes de pacotes:

  • ELPA,
  • GNU
  • marmelada
  • melpa

Q.3 Importa a ordem em que são adicionados package-archives?

Amelio Vazquez-Reina
fonte
13
O MELPA é necessário para o preenchimento automático, pois obviamente ninguém se preocupou em disponibilizar o preenchimento automático no Marmalade. Não se preocupe, mas sim limpe o seu package-archives. Livre-se do arquivo ELPA, que não é mais mantido, e do arquivo marmelada, que é uma bagunça de pacotes desatualizados e duplicados sem orientação e manutenção claras. Use apenas o arquivo GNU padrão e MELPA>
lunaryorn 12/02/2013
2
Obrigado @lunaryorn! Isso é muito útil. Você sabe como eu poderia me manter informado sobre coisas assim? (ou seja, "boas-coisas-a-saber" como estes como evolui Emacs)
Amelio Vazquez-Reina
3
As informações estão circulando livremente na Web, basta ver: Siga / emacs no Reddit, siga blogs e twitter de pessoas de renome do Emacs como Nic Ferrier, Bozhidar Batsov, Magnar Sveen, John Wiegley, etc., junte-se à #emacs no Freenode IRC, e muitos mais.
lunaryorn
3
Você deveria (setq package-enable-at-startup nil)se quiser se chamar (package-initialize).
phils
2
Thanks @phils - Por que isso é necessário?
Amelio Vazquez-Reina

Respostas:

163
  1. Para atualizar automaticamente a lista de pacotes, apenas se ainda não houver uma lista de pacotes , use o seguinte:

    (when (not package-archive-contents)
        (package-refresh-contents))

    Para atualizar todos os pacotes instalados, digite package-list-packages, que o levará ao *Packages*buffer (e também atualize a lista de pacotes) e, em seguida, digite U x.

    package-refresh-contentsincondicionalmente tenta baixar uma lista de pacotes de todos os repositórios que você adicionou package-archives; package-archive-contentsnão é nulo se você já baixou a lista de pacotes.

  2. ELPA é o original. Acho que não é mais mantido, mas não tenho certeza. Eu não uso.

    GNU é "oficial". Ele é mantido junto com o Emacs, o que significa que as coisas sempre devem funcionar, mas as atualizações e os novos pacotes não vêm com muita frequência.

    Marmalade é basicamente um site no qual você pode fazer o upload de um pacote completo, que será adicionado ao repositório de marmeladas. Você não envia apenas um link para o upstream do pacote e isso não automatiza completamente a criação do pacote. Eu acho que essa é a coisa certa, porque você não necessariamente deseja acompanhar a montante. Infelizmente, ele não foi mantido por um tempo, mas alguém recentemente assumiu o controle, de modo que deveria estar de volta e melhor em algum momento.

    O Melpa pega um URL, por exemplo, na área EmacsWiki lisp ou em um repositório do github, e cria um pacote automaticamente a partir dele. Assim, geralmente fica no máximo um dia atrás do que quer que esteja rastreando. Embora ele rastreie a montante, nunca tive um problema na prática, e é daí que vem a maioria dos meus pacotes. Há também o Melpa Stable , que é como o Melpa, mas pega revisões marcadas do repositório upstream, em vez da revisão mais recente. Melpa estável tem menos pacotes que Melpa.

    O modo organizacional possui seu próprio package.elrepositório ( http://orgmode.org/elpa/ ).

    Todos os repositórios de pacotes funcionam da mesma maneira, basta adicioná-los ao seu package-archives.

    Aqui está um post de blog mais aprofundado sobre esse assunto, com o qual concordo principalmente.

  3. Não tenho certeza, mas acho que se um pacote for duplicado em diferentes repositórios, a ordem em que os repositórios aparecerão package-archivesdetermina a precedência. Não sei se a maior precedência está no início ou no final da lista.

    Atualização: No Emacs 25, há uma variável package-archive-prioritiesque você pode usar para priorizar seus repositórios de pacotes (por exemplo, prefira ELPA sobre MELPA).


Aqui está a seção relevante da minha init.el, se você estiver interessado:

(setq jpk-packages
      '(
        ac-dabbrev
        ...
        yasnippet
        ))

(package-initialize)
(add-to-list 'package-archives
             '("melpa" . "http://melpa.org/packages/"))
(add-to-list 'package-archives
             '("org" . "http://orgmode.org/elpa/"))

;; install any packages in jpk-packages, if they are not installed already
(let ((refreshed nil))
  (when (not package-archive-contents)
    (package-refresh-contents)
    (setq refreshed t))
  (dolist (pkg jpk-packages)
    (when (and (not (package-installed-p pkg))
             (assoc pkg package-archive-contents))
      (unless refreshed
        (package-refresh-contents)
        (setq refreshed t))
      (package-install pkg))))

(defun package-list-unaccounted-packages ()
  "Like `package-list-packages', but shows only the packages that
  are installed and are not in `jpk-packages'.  Useful for
  cleaning out unwanted packages."
  (interactive)
  (package-show-package-list
   (remove-if-not (lambda (x) (and (not (memq x jpk-packages))
                            (not (package-built-in-p x))
                            (package-installed-p x)))
                  (mapcar 'car package-archive-contents))))
jpkotta
fonte
2
Obrigado! O que when (not package-archive-contents)verifica?
Amelio Vazquez-Reina
3
O condicional impede a atualização toda vez que inicio o emacs (normalmente, só quero que ele verifique quando é solicitado). Ele verifica apenas se não há arquivos de pacotes, o que deve ocorrer apenas na primeira vez em que clono minha configuração em uma nova máquina.
jpkotta
Basta informar a resposta de @Brandy Trainor, que parece complementar sua resposta - caso seja útil.
Amelio Vazquez-Reina
Eu acho que isso precisa ser chamado (refresh-package-contents)incondicionalmente antes de baixar novos pacotes, caso contrário, o Emacs pode tentar fazer o download de uma versão antiga do pacote (que já é 404), falhar e parar de carregar.
Vladimir Panteleev
Qual é a melhor maneira de entender qual pacote é indesejado? @jpkotta
alper
103

No Emacs, use M-x list-packagespara listar todos os pacotes que atualizarão automaticamente o conteúdo do arquivo. Depois, use Upara marcar todos os pacotes atualizáveis ​​a serem atualizados e xrealmente executar as novas atualizações. O Emacs buscará e instalará todas as atualizações e solicitará a remoção das versões antigas e obsoletas posteriormente.

Você também pode dar uma olhada no Carton, que fornece uma maneira mais conveniente de gerenciar seus pacotes, declarando-os em um arquivo dedicado, e inclui um cliente de linha de comando conveniente para instalar e atualizar automaticamente os pacotes declarados dessa maneira.


A fim de package-archivesque não importa. O Emacs agrega o conteúdo de todos os arquivos em uma única lista coerente de pacotes disponíveis e suas versões, armazenados em package-archive-contents.

Em package-installseguida, o Emacs simplesmente escolherá a versão mais recente de um pacote, independentemente do arquivo de origem. Para obter mais controle sobre a origem do pacote, o MELPA fornece o pacote melpa, que permite pacotes em lista negra ou na lista branca de arquivos especificados.

lunaryorn
fonte
2
Isso é S-upara ser mais preciso.
Lenar Hoyt 12/11/2015
@mcb O que é S-u? O menu do pacote não usa essa ligação.
Lunardorn 12/11
2
Eu quero dizer Shift-ucom isso.
Lenar Hoyt 12/11/2015
8
@mcb Bem, é por isso que eu escrevi um capital U 😊
lunaryorn
1
É apenas para os confusos como eu que pensam que isso significa <kbd> U </kbd>.
Lenar Hoyt 12/11/2015
23

No terminal:

emacs

M-x list-packages

isso coloca você no buffer * packages *

shift-u x

O emacs solicitará (s / n), aguarde atualizações

C-x k <ret>

isso matará o buffer * packages * e retornará você de volta ao * scratch *

C-x-C-c

isso sairá do emacs e permitirá que você reinicie via, mas talvez seja necessário depurar :(

emacs

meus 2 ¢

rezwits
fonte
Eu recebi "nenhum comando especificado" ou algo assim quando digitei "U". Após a execução M-x package-refresh-contents, ele me levou a digitar “U” para marcar todos os itens para atualização e, em seguida, fui capaz de digitar “x” para executar as atualizações.
MrColes
2

Este é mais um comentário estendido sobre a resposta de jpkotta.

Este é um ajuste que estou experimentando para a resposta de jpkotta acima:

(setq n 0)                                  ; set n as 0
(dolist (pkg pkgs-2b-present)               ; for each pkg in list
  (unless (or                               ; unless
           (package-installed-p pkg)        ; pkg is installed or
           (assoc pkg                       ; pkg is in the archive list
                  package-archive-contents))
    (setq n (+ n 1))))                      ; add one to n
(when (> n 0)                               ; if n > 0, 
  (package-refresh-contents))               ; refresh packages

(substituindo (when (not package-archive-contents) (package-refresh-contents))).

A lista de pacotes não era atualizada o suficiente para o meu caso de uso.

Não considerei se existe uma solução mais eficiente para o meu problema; primeiro, tenho que ver se o problema desaparece com esse ajuste.

Brady Trainor
fonte
Na minha resposta, package-archive-contentsé atualizado apenas se não existir. A idéia é que você copie seu arquivo .emacs.d para uma nova máquina e instale automaticamente todos os seus pacotes, mas depois disso você precisará atualizar manualmente. Eu tento atualizar uma vez a cada duas semanas. Acho que você adicionou um pacote à sua lista, mas você package-archive-contentsera muito velho para tê-lo?
jpkotta
@jpkotta, eu tenho uma inicialização dupla, cada uma usando seu padrão ~/.emacs.d/elpa/para localização de pacotes. No entanto, minha versão do seu código de instalação de pacotes está em uma "terceira" partição, ( e:/emacs-configou /e/emacs-config/). Portanto, adiciono um pacote à lista enquanto estiver em um sistema operacional e ele deve ser atualizado quando carregar Emacsno outro sistema operacional. Com certeza há algum elemento de exagero na minha solução, mas parece estar funcionando pelo menos.
Brady Trainor
@ jpkotta, por que minha aparência package-archive-contentsparecia estar tão fora de moda me escapa. Essa é uma questão que não reduzi. Se eu procurar e encontrar uma solução "mais elegante" no futuro, vou adicioná-la à minha postagem.
Brady Trainor
1
(package-refresh-contents)escreve para ~/.emacs.d/elpa/archives. Não está claro se você possui esse diretório compartilhado entre sistemas operacionais. Eu recomendaria não compartilhar os elpa/diretórios, porque o bytecode do Emacs (o código in elpa/é compilado) não é compatível com versões anteriores ( gnu.org/software/emacs/manual/html_node/elisp/… ). Você precisaria garantir que ambas as instalações tenham a mesma versão do Emacs. Eu mantenho meu .emacs.dcontrole de versão e sincronizo diferentes instalações com isso.
Jspkotta