elisp的package管理和其他语言的相比,好像没有版本依赖性这一块。
java有pom.xml,perl有cpan,ruby有Gemfile,go有Gopkg.toml。它们都能很好的解决代码间的依赖关系
而由于历史和现实的原因,elisp对版本的依赖需求并不是很高。
-
底层的版本依赖,emacs已经保证了。
-
elisp的package大部分是由一两个文件组成,接口一般相对稳定,并且规模不是很大,导致package对外接口和版本的对应关系不是严格绑定。
-
emacs自身是一个整体的运行环境,而不像其它语言,开发出的软件是各自独立运行。独立的运行环境内,要求版本之间是不能冲突的。
-
即使emacs有版本链这一说,只要emacs的版本决定下来了,在其上的各package就基于它来保证正常运行。也就是emacs的一个版本决定一个版本链。
我说的是package的版本依赖,不是package依赖,比如我写的elisp必须xxx package的某某版本以上,没有的话相应的工具就帮着自动下载。其他语言都有这种版本链。现在的状况是,只要都取最新的package,好像就不会出现冲突问题。
欢迎大家来讨论!我是新手,难免理解有误,欢迎指正。
怎么可能没有呢?ELPA 上几千个包不可能个个都相互独立、没有依赖关系。
比如 Magit 就有不少依赖:MELPA
除了特殊情况,用户配置与 require 的时机是没关系的,之前或者之后都没有影响
init.el和各package中代码执行的先后关系呢?
一般不需要关心setq的先后,但是如果有的插件作者在代码里把配置项作为右值赋值给其他变量的话,就需要在require之前setq。比如早期projectile的前缀键就需要在(require 'projectile)
之前(setq projectile-prefix-key "C-x p")
,因为在require/autoload之后,前缀键已经用来生成完整快捷键了。
此外,对于defvar来说,如果被定义的名字已经存在,则不会重新初始化。setq会生成一个名字,defvar不会覆盖它。
总结一下,大部分插件require/autoload之后再设置配置项,特殊情况需要在require之前配置某些配置项。
好的,谢谢!
在这之前,我理解有误,以为所有package加载时,像projectile的前缀键绑定那样,都要在启动时,用到手动设置的参数。
正确的理解是不是,大部分的设置是在当前mode的各种hook触发时才被用到?
和hook是没有关系的,你可能想复杂了,这些配置项是在执行某个函数时用到的。
所有的配置项都是全局变量,我们setq
就是在修改这些全局变量,插件模块根据这些全局变量调整自身行为,如此而已。
你可以在xxx-mode-hook
里写个函数去setq
,也可以require
这个包之后再setq
,也可以require
之前setq
,因为即使这个变量没有被定义,setq
会创建这个变量。
但是一般为了缩短启动时间,大家倾向避免直接require,而是在xxx-mode-hook
里setq
,或者在(with-)eval-after-load
某个包之后setq
。当某个autoload的函数(比如所有的xxx-mode函数都是autoload的)被执行了,emacs才会require整个包。
顺便给一个eval-after-load
和xxx-mode-hook
的区别:
xxx-mode-hook
每打开一个buffer都执行一次,eval-after-load
只在第一次require包时执行一次。
对于buffer-local的配置,eval-after-load
可以用来设置默认值(用setq-default
),而xxx-mode-hook
可以设置在特定mode下,某个配置项的值,也因此xxx-mode-hook
会在eval-after-load
之后执行。
1 个赞