在Emacs中更新包

时间:2013-02-12 16:20:30

标签: emacs elpa

我对包有以下设置(不确定是否有更好的建议):

(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 以下包源有什么区别?:

  • ELPA,
  • GNU
  • 果酱
  • melpa

Q.3 package-archives添加顺序是否重要?

4 个答案:

答案 0 :(得分:151)

  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 基本上是一个网站,您可以上传完整的包,它将被添加到橘子酱回购中。您不仅要提交包的上游链接,而且还不能完全自动创建包。我认为这是正确的事情,因为你不一定想跟踪上游。不幸的是,它已经有一段时间没有维护了,但是有人最近接受了它,所以它应该在某些时候恢复并且更好。

    Melpa 会将网址带到例如EmacsWiki lisp区域或github repo,并从中自动构建包。因此,通常最多只追踪它追踪的一天。虽然它跟踪上游,但我在实践中从未遇到过问题,而这正是我的大多数软件包所在的地方。还有 Melpa Stable ,就像Melpa一样,但是抓取了上游回购的标记版本,而不是最新版本。 Melpa stable的包装少于Melpa。

    组织模式有自己的package.el回购(http://orgmode.org/elpa/)。

    所有的包重新发布都是相同的,您只需将它们添加到package-archives

    以下是关于此主题的更深入blog post,我非常赞同。

  3. 我不确定,但我认为如果一个包在不同的repos中重复,那么repos在package-archives中出现的顺序决定了优先级。我不知道更高的优先级是否在列表的开头或结尾。

    更新:在Emacs 25中,有一个变量package-archive-priorities可用于确定包装回购的优先顺序(例如,更喜欢ELPA而不是MELPA)。


  4. 以下是我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))))
    

答案 1 :(得分:90)

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

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


package-archives的顺序很重要。 Emacs将所有档案的内容汇总到一个连贯的可用包及其版本列表中,存储在package-archive-contents中。

package-install后,无论原始档案如何,Emacs都会选择最新版本的软件包。为了更好地控制包源,MELPA提供melpa package,允许从指定的档案中对包进行黑名单或白名单。

答案 2 :(得分:15)

在终端:

sys.maxsize

这会让你进入* packages * buffer

emacs

M-x list-packages

emacs会问你(是/否),等待更新

shift-u x

这将终止* packages *缓冲区并返回* scratch *

C-x k <ret>

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

C-x-C-c

我的2¢

答案 3 :(得分: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)))。

对于我的用例,包列表不够经常刷新。

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