你为什么要使用 Cask来管理 Emacs 的 Packages?

因为我录制的第八天视频里面,忘记讲了这个东西有啥用了,导致有初学者看完后,感觉完全没学到到东西。。。

其实我们之前的视频里面已经简单写了一个 package 管理工具了,就是可以在 Emacs 启动的时候,自动根据我们定义的包名来下载对应的 package。但是,如果你要更新包的话,你还是得先启动 Emacs,然后再执行 package-list-packages → press U → press x 来更新所有的 packages。

如果这个时候某个 package 挂了,完了,你的 Emacs 启动不起来了。这时候,你有两种选择,要么把那个包和相关配置注释掉,然后给包的作者提 issue,等他修复完这个 bug,再重新激活你的配置。

这种做法需要时间,因为 Melpa每五小时更新一次,而且作者修复 bug 可能也需要等一两天,如果你每天用 Emacs 来工作,这肯定是不能忍的。

所以,有方法二:回退你的包的版本,比如回退到某个稳定版本,这时候你可以使用 melpa-stable。 如果你不使用 cask,这时候你又需要修改.el 文件,这时候别忘记了你的 Emacs 配置是挂的呢?我以前一般用 vim 来 fix emacs 的问题。。。

但是,vim 里面编辑 lisp 是非常不方便的,而且极易出错。如果只时你用了 cask,那么你可以在命令行和配置里面简单地修改便可以完成 “安装源”的修改以及插件的更新。

Don’t touch your code until you have to!

Prefer configuration over code!

2 个赞

我也遇到过这种问题,用vim来改配置启动。。。 看看Cask

Cask 能锁定包的版本吗?

Melpa 就得做好随时挂掉的准备,所以我把配置分成

  • basic.el
  • extra.el

两部分。basic.el 不依赖任何扩展,确保在任何情况下,都能有最基本的快捷键可用,摆脱用 Vim 编辑 Emacs 配置的窘境。

自从把 C-h 绑定成删除(跟osx/shell/vim 所有能编辑的地方保持一致)之后,再也没法使用默认配置的 Emacs 了。别看就这一个键,简直太致命了。

可以锁定包的版本的

(depends-on "ecukes")
(depends-on "magit" "0.8.1")
(depends-on "magit" :git "https://github.com/magit/magit.git")
(depends-on "magit" :git "https://github.com/magit/magit.git" :ref "7j3bj4d")
(depends-on "magit" :git "https://github.com/magit/magit.git" :branch "next")
(depends-on "magit" :git "https://github.com/magit/magit.git" :files ("*.el" (:exclude "magit-svn.el")))

https://cask.github.io/dsl.html

1 个赞

文档说这里的版本号是用来指定最小版本的,并不能指定特定版本。我试了试指定这个版本号,似乎指定任意的版本号,效果都一样,换句话说这个参数似乎没什么用。

Function depends-on package-name &optional minimum-version

Cask Domain Specific Language — Cask 0.8.4

实际上,以 Magit 为例,MELPA stable 只提供 2.7.0,MELPA 只提供 20160523.1922,旧的版本根本就不会被保存。虽然 GNU ELPA 和 Org ELPA 提供了旧的版本,但是 package.el 似乎没有提供安装旧版本的方法。所以从 ELPA 只能安装最新的版本。

package.el 倒是提供了 pin 某个 ELPA 的方法(package-pinned-packages),比如只想用稳定版本的 Magit 的话,pin 住 MELPA-stable 就行。

那如果我使用 :git :ref 是不是就可以直接指定 github 上面某个 commit 了? 把 Github 上面的 release 对应的 commit 放进来,也相当于使用了特定的版本?

是。从 git 安装可以指定 commit、tag 了,估计 cask 就是把代码 clone 下来,在本地构建这个包,再给 Emacs 安装。相当于其它包管理器的「从源码安装」。

恩, 这个功能其实挺好的,可以用来 fix package 作者的 mistake…

刚刚测试了一下 cask 的 ref 功能,并没有任何卵用,还不如直接用 quelpa

我刚刚试了下,ref 应该是有用的。

;; Hash
(depends-on "plur" :git "https://github.com/xuchunyang/plur.git" :ref "4dc05ee")
;; 或 Tag
(depends-on "plur" :git "https://github.com/xuchunyang/plur.git" :ref "v0.1")

Cask clone 的位置在

~/Projects/plur $ ls $TMPDIR/cask/checkout
plur

包安装在

~/Projects/plur $ ls .cask/25.1.50.11/elpa/plur-20160504.1711 
plur-autoloads.el  plur-pkg.el  plur.el  plur.elc

只是版本号还是用 melpa (-unstable) 的方式命名的:比如 plur-20160504.1724,即便你指定的 ref 是 Tag。

(这里的日期版本号是指 Repo 中需要打包的文件中的最后一次 commit 的日期)

另外,对于比较复杂的包还需要设置 :files patterns

哦,我忘记给 ref 和 hash 添加引号了。。。 失误,感谢反馈。