最近在编写自己的Emacs配置的过程当中,对于插件管理上,我曾经尝试过package.el、Elpaca,但是如论坛所指出的,有些在elpa的包会有版本低、安全性差的问题,有些甚至不提供elpa的安装方式,另外,我自己日常工作是在Linux和Windows下进行的,于是在近期也是看到论坛提到用git submodule的方式手动管理,也想做出尝试。
一开始我是按照这篇文章来做的:
Managing packages in Emacs · Daniel Yaren
仿照这篇文章,我初步写出了这些配置:
Mika-Lahtinen/kemacs (github.com)
但是加载的时候,后台还是直接开始扫描melpa仓库安装,而不是直接使用submodule加载的插件。
现在有问题:
我在论坛里看到的还只是分散在各个话题当中提到git submodule这种方式,可否以成文章的形式介绍一下更为详细的使用git submodule管理插件的步骤和方法?
我在配置AucTeX的时候,发现通过源码还要在不同平台下先单独在命令行编译,有没有什么方法在比如.gitmodule文件下提前写好配置或者预编译代码,这样尽量让配置开箱即用?
可以尝试使用 Borg 做包管理,很接近直接用 git submodule 手动管理。就算不喜欢 borg 也可以读一下源码或文档(因为很好懂),理解它的原理和做法以后自己模仿
1 个赞
说到这又一个新问题:这种手动管理插件的方法,会不会遇见不同插件有着同名的依赖但是不同版本的情况,这时候一般又会如何处理?
关于 submodule 的用法可以看我的博客介绍 我平常是怎么折腾Emacs插件的?
请先认真看我上面的内容, 然后看下面的回答:
添加插件: git submodule add 就好了, 插件更新就是切换到子目录 git pull 就好了, 配置仓库只保存每个插件的 commit id, 并不会保存任何插件内容, 这样你的配置仓库以后再次 clone 的时候会很小
删除插件: git submodole remove, 目前 git 没有针对 submodule remove 提供开箱即用的命令, eaf-git 可以帮助我们快速清理 submodule
插件更新: 去插件目录 git pull 就好了, submodule 最妙的是, 如果你觉得插件新版有bug, 可以直接 git reset 到稳定的 commit id 继续用老版的插件, 不会像 elpa 这种一股脑全部升级, 万一新版有问题, 只能硬着头皮折腾的尴尬情况
关于不同平台编译的情况: 我的方式是不同平台编译好放在目录下, 自己在配置文件中写 if else 来选择加载不同平台对应的编译目录
手动管理插件: 手动是麻烦, 遇到差依赖就继续手动下载就好了, 但是就是require的时候麻烦, 以后一点麻烦都没有, 因为你永远不会遇到你不知道升级了啥就挂了, 手动管理插件的出错路径非常清晰, 只有你今天手动升级才是挂的原因, 你很容易通过上面说的 git reset 命令来回滚到任意版本
不同插件有着同名的依赖但是不同版本的情况: 我手动管理插件十多年了, 很少遇到这种问题, 一般都是某个公共库太新导致了, 遇到这种情况, 给公共库提交一个issue后, 马上 git reset 回到稳定 commit 集合, 继续稳定的干活
手动管理插件, 如果用 eaf-git 这种插件, 你会发现一个命令都不用敲, 全傻瓜操作。
如果用git命令管理, 基本上就是安装的时候多费5分钟时间安装一下依赖, 但是好处就是你永远都可以稳定的工作。
最后分享一下我的经验: 手动插件管理 + 扁平化配置(不要追求所谓美观配置给自己带镣铐) + 没事别升级插件 + git是唯一能够让Emacs插件稳定工作的方式。
12 个赞
感谢您的回复,刚才去在Windows试着安装了一下EAF-git,用msys2编译的Emacs 30.0.50 会报错json-parse-buffer的Symbol’s function is void 错误, 换到Emacs 28.2就没有问题了,我回去先研究一下,装几个常用的插件试试看
看了一下Borg的文档,这个方案留待后面直接用git submodule用着不顺利的时候再试试
可以看看我目前的方法,把所有的包当作一个 submodule,绕开依赖管理。
项目地址:
起因:
使用 emacs ,免不了对插件进行管理,我对其的要求是简单、减少依赖、不影响启动时间。
尝试过多种包管理插件后,都有各自的痛点 – 包括但不限于占用过大、与某些包冲突、依赖管理麻烦,最后又回到 package.el ,对于未进 (m)elpa 的包使用 quelpa 进行下载管理。
目前这种方式也有一定的问题,一是 archive-contents 文件过大影响启动时间,二是 quelpa 在启动时会检测更新,也会干扰启动。
实现:
quelpa 有编译包后放在 elpa 文件夹中这一特性, redguardtoo 的 elpa-mirror 可以备份 elpa 文件夹生成 mirror ,结合 GitHub action 实现自动生成和更新自己独有的 elpa-mirror ,从而减少本地的依赖和启动时间。
后续:
经过各种尝试后,结合 讨论一下Emacs半手动包管理 ,还是对 git submodule 这一方式向往,但这种方式对我来说有一痛点 – 包多后依赖管理麻烦,而我目前还处于频繁尝试插件的阶段。
基于目前的实现,可以将整个 elp…
项目地址更改为
Borg 严重依赖 magit,在Liunx 上体验应该会很好。但在Windows 下 magit 太慢。楼主如果主力系统是 Linux的话,推荐用 Borg,否则不建议。
我是主力用 macOS,其次是 Windows,配置主要在 macOS上更新。
我是属于,Windows和Linux都用,五五开那种,magit在Windows下的性能不行这个我还是清楚的,之前还没开始重新组织配置的时候,也是听的陈斌先生的建议,用的vc
来个文不对题(不使用git submodule)的回复:
可以看看我写的一个包:新包:pie - package installer for Emacs
不依赖package.el,支持git clone仓库或者http下载单个文件,支持定制化构建包。不过我不用windows,不确定在win上会不会有啥问题。
不依赖magit,依赖vc(对于git仓库,一开始用的是vc,后来改成直接使用git这个命令行工具,对于hg之类的其他类型仓库,依赖vc,不过其他仓库我没测过。。。)
出现一个新问题:我按照use-package的说明,将use-apckage通过git submodule add到我设定的插件目录,在使用git submodule add另一个插件(如markdown-mode),用use-package加载的时候,我的插件路径:load-path是对的,但是还是在打开Emacs的时候,给我直接从elpa上查找markdown-mode,而不是直接使用我本地的文件,这样的问题怎么解决?
xiyang
2023 年6 月 27 日 16:03
15
我使用的是 use-package+quelpa+git submodule
管理我自己写的一些package
首先所有的子模块我都放在 .emacs.d/site-lisp
目录下,所以需要添加 site-lisp
路径到 load-path
https://github.com/honmaple/maple-emacs/blob/master/core/core.el#L126
然后是使用 use-package+quelpa
, 其中的 quelpa
关键词是我自定义的
https://github.com/honmaple/maple-emacs/blob/master/core/core-use-package.el#L197
其中关键的地方就在于会优先查找本地的package,如果没有才会下载远程的包
(defun use-package-handler/:quelpa (name _keyword args rest state)
"NAME KEYWORD ARGS REST STATE."
(use-package-concat
`((unless (or (locate-library ,(format "%s" name))
(package-installed-p ',(pcase (car args)
((pred listp) (caar args))
((pred symbolp) (car args)))))
(apply 'quelpa ',args)))
(use-package-process-keywords name rest state)))
如果我在其它地方使用emacs(非我本机),可以选择是否克隆子模块,不克隆的话会使用quelpa下载package。
如果不想使用子模块,而是一个独立的本地包,和emacs配置一起管理,同样可以放到site-lisp目录下,只需要添加:ensure nil
即可,具体这些都可以在我的配置里找到
https://github.com/honmaple/maple-emacs
我用magit加submodule,按提示就搞定了,什么都没学的
前不久换成了straight,现在是elpa+少量straight,straight相比submodule好处是原样给你目录,可以直接git/magit操作。不过默认只认elisp文件,找了好久怎么把lsp-bridge的py文件放进去。
昨天试了一天把use-package用上,失败了,还是暂时考虑直接require了
use-package没什么坑,只要注意 always-ensure always-defer 和 demand 应该就可以了。搞好之后已经require了的不用动,加新插件再用use-package就行
我是当时面对的问题是这样,use-package的load-path读取的路径,我按照插件的绝对路径写的,但是似乎它还是给我搞的是相对路径,这就是我不得不暂时放弃使用use-package的原因
tyr
2023 年6 月 28 日 05:19
20
use-package
里的 load-path
是配合和 user-emacs-directory
展开的,有什么理由一定要用绝对路径咧?
3.7 Setting a custom ‘load-path’
================================
If a package resides in some directory that is not in your ‘load-path’,
use the ‘:load-path’ keyword to add it. It takes a symbol, a function,
a string or a list of strings. If the path is relative, it is expanded
within ‘user-emacs-directory’.