164

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

(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

4

4 回答 4

177
  1. 为了自动更新包列表,只有在没有包列表的情况下,才使用以下命令:

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

    要更新所有已安装的包,请键入package-list-packages,这会将您带到*Packages*缓冲区(并且还会更新包列表),然后键入U x

    package-refresh-contents无条件地尝试从您添加到的所有存储库中下载包列表package-archivespackage-archive-contents如果您已经下载了包列表,则为非 nil。

  2. ELPA是原创的。我不认为它真的被维护了,但我不确定。我不使用它。

    GNU是“官方的”。它与 Emacs 一起维护,这意味着事情应该总是可以工作,但更新和新包不会经常出现。

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

    Melpa获取一个 URL,例如 EmacsWiki lisp 区域或 github 存储库,并从它自动构建一个包。因此,它通常最多比它跟踪的任何东西晚一天。虽然它跟踪上游,但我在实践中从来没有遇到过问题,这就是我的大部分包裹的来源。还有Melpa Stable,它类似于 Melpa,但抓取上游 repo 的标记修订而不是最新修订。Melpa stable 的软件包比 Melpa 少。

    Org 模式有自己的package.elrepo ( http://orgmode.org/elpa/ )。

    所有包 repos 的工作方式都是一样的,您只需将它们添加到您的package-archives.

    这是关于这个主题的更深入的博客文章,我非常同意。

  3. 我不确定,但我认为如果一个包在不同的 repos 中重复,repos 出现的顺序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))))
于 2013-02-12T17:21:35.297 回答
117

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

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


顺序package-archives无关紧要。Emacs 将所有档案的内容聚合成一个可用包及其版本的连贯列表,存储在.package-archive-contents

在 之后package-install,Emacs 将简单地选择包的最新版本,而不管原始存档。为了更好地控制包的来源,MELPA 提供了melpa 包,它允许将来自指定档案的包列入黑名单或白名单。

于 2013-02-12T17:59:20.673 回答
39

在终端:

emacs

M-x list-packages

这会让你进入 *packages* 缓冲区

shift-u x

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

C-x k <ret>

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

C-x-C-c

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

emacs

我的 2¢

于 2017-10-01T00:19:49.077 回答
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)))。

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

我没有考虑是否有更有效的解决方案来解决我的问题;首先,我要看看这个调整是否会解决问题。

于 2014-03-10T09:45:18.350 回答