前面的一系列文章中, 我们差不多介绍完了 major mode 相关的一些概念。但是我们还有两个问题没有解决。之前的测试用例需要手动触发mode开启函数,我们需要的是它能根据一定的规则自动开启major mode。而且我们开发的major mode,我只希望在打开对应文件时加载,而不是无脑加载我们在 .emacs.d 中的所有配置。
背景知识
文件关联
Emacs支持通过正则表达式对文件名进行匹配,根据匹配规则加载自动设置对应buffer的major mode。二者的匹配关系由全局的 auto-mode-alist 变量存储。
列表中的每一项都是一个cons cell,它的写法为 (REGEX . mode-function) , 其中mode-function 是启动major mode的函数。例如我想要添加一条规则:所有的.c文件都使用我们之前开发的简易的 my-simplec-mode,可以写下如下代码:
(add-to-list 'auto-mode-alist '("\\.c\\'" . my-simplec-mode)))autoload 延迟加载
一般情况下,外部要引用子模块的内容,可以使用 require 关键字,假设我们将之前编写的 my-simplec-mode 放到一个名为 my-simplec-c.el 文件中,如果外部要加载可以写下:
(require 'my-simplec-c)Emacs 在读到这句时会将整个文件都加载进来,并且对文件中所有代码执行。虽然它能保证文件中的代码执行一次,但是有时候文件中某些耗时的操作我并不会在开启时就执行,甚至有时候直到关闭Emacs都不会被执行。此时这种全盘执行的方案就有点浪费时间了。
Emacs 允许我们对一些函数或者代码添加autoload 注释,以便延迟加载。注释的写法如下:
;;;###autoload当我们需要执行一个 elisp 文件时,例如使用 load-file、package-install 时,它会扫描该文件,对于使用该注释修饰的函数,它不会执行而是生成一条记录,写入对应的 -autoloads.el 文件中,例如对于上面的 my-simplec-c.el ,它会生成一个 my-simplec-c-autoloads.el 的文件。文件中记录需要延迟加载的函数信息。
在真正需要执行的时候再根据 autoloads 文件中记录的信息查找到具体代码位置,正式加载并执行函数。
其实它的加载时机并不只有主动load的时候。而且我们前面说的启动Emacs时执行也不太准确。至于具体的时机我们将在后面详细讨论,在这一阶段读者只用记住autoload 是只在必须调用的时候加载,能加速启动即可。
总结
本篇我们简单讨论了一下关于 auto-mode-alist 和 autoload 的内容。前者可以将文件后缀和对应的mode绑定,后者可以做到延迟加载。要达到效果很简单,但是背后的原理我们在这里展开又太大了,后面我打算在打包与模块化等专题的时候详细讨论。
评论 (0)