在 Emacs 中更新软件包

问题描述 投票:0回答:4

我有以下软件包设置(不确定是否有更好的推荐):

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

我有三个与软件包安装和更新相关的问题。

Q1. 有没有办法更新可用软件包(和最新版本)列表并更新特定软件包?

Q.2 以下包源有什么区别?:

  • 埃尔帕,
  • GNU
  • 果酱
  • 梅尔帕

Q.3 它们添加到

package-archives
的顺序重要吗?

emacs elpa
4个回答
190
投票
  1. 为了自动更新软件包列表,仅当还没有软件包列表时,请使用以下命令:

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

    要更新所有已安装的软件包,请键入

    package-list-packages
    ,这将带您到
    *Packages*
    缓冲区(并更新软件包列表),然后键入 U x

    package-refresh-contents
    无条件尝试从您添加到
    package-archives
    的所有存储库下载软件包列表;如果您已经下载了软件包列表,则
    package-archive-contents
    非零。

  2. ELPA 是原创。我认为它不再被真正维护,但我不确定。我没用过。

    GNU 是“官方”。它与 Emacs 一起维护,这意味着一切应该始终有效,但更新和新软件包不会经常出现。

    Marmalade 基本上是一个网站,您可以在其中上传完整的包,并将其添加到 marmalade 存储库中。您不只是提交到包上游的链接,而且它并不能完全自动创建包。我认为这是正确的事情,因为你不一定想追踪上游。不幸的是,它已经有一段时间没有维护了,但最近有人接管了它,所以它应该会在某个时候回来并且更好。

    Melpa 需要一个 URL,例如EmacsWiki lisp 区域或 github 存储库,并从中自动构建一个包。因此,它通常最多比所跟踪的内容晚一天。尽管它跟踪上游,但我在实践中从未遇到过问题,这也是我的大部分包都来自的地方。还有 Melpa Stable,它与 Melpa 类似,但获取上游存储库的标记修订版而不是最新修订版。 Melpa 马厩的包裹比 Melpa 少。也许 Melpa 应该比 Melpa Stable 更受青睐

    Org 模式 有自己的

    package.el
    存储库 (http://orgmode.org/elpa/)。

    所有软件包存储库的工作原理都是相同的,您只需将它们添加到您的

    package-archives
    中即可。

    这里有一篇关于这个主题的更深入的博客文章,我基本上同意。

  3. 我不确定,但我认为如果一个包在不同的存储库中重复,则存储库在

    package-archives
    中出现的顺序决定了优先级。我不知道更高的优先级是在列表的开头还是结尾。

更新:在 Emacs 25 中,有一个变量

package-archive-priorities
,您可以使用它来确定软件包存储库的优先级(例如,优先选择 ELPA 而不是 MELPA)。


这是我的

init.el
的相关部分,如果你有兴趣:

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

122
投票

在 Emacs 中,使用

M-x list-packages
列出所有包,这将自动刷新存档内容。然后使用
U
标记所有要升级的可升级包,并使用
x
实际执行新的更新。然后,Emacs 将获取并安装所有升级,并询问您是否随后删除旧的、过时的版本。

您可能还想看看 Carton,它提供了一种更方便的方法来管理您的包,通过在专用文件中声明它们,并包含一个方便的命令行客户端来自动安装和升级以这种方式声明的包。


package-archives
的顺序重要。 Emacs 将所有档案的内容聚合到可用软件包及其版本的单个连贯列表中,存储在
package-archive-contents
.

一旦

package-install
,Emacs 将简单地选择软件包的最新版本,而不管原始存档是什么。为了对包来源进行更多控制,MELPA 提供了 melpa 包,它允许将指定档案中的包列入黑名单或白名单。


48
投票

在终端:

emacs

M-x list-packages

这会将您置于*packages*缓冲区中

shift-u x

emacs 会问你(y/n),等待更新

C-x k <ret>

这将杀死*packages*缓冲区并使您返回到*scratch*

C-x-C-c

这将退出 emacs,并让你重新启动 via,但你可能需要调试:(

emacs

我的2美分


2
投票

这更多的是对 jpkotta 答案的扩展评论。

这是我正在尝试对上面 jpkotta 的答案进行的调整:

(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

(替换

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

对于我的用例来说,包列表的刷新频率不够。

我还没有考虑是否有更有效的方案来解决我的问题;首先,我必须看看问题是否会随着此调整而消失。

© www.soinside.com 2019 - 2024. All rights reserved.