昨晚看到电报群里热闹的讨论,抛砖分享个人学习的工作流,引引玉。(感谢学姐,这篇文章完全学习她无私分享和慷慨助人
浏览论坛内入门elisp学习的讨论,会发现都在强调 save-excursion
这个函数,可能是写elisp最有用的函数之一。
在 rush blindly into details 之前,或者用 C-h f 打开 save-excursion 的黑匣子之前。我们先从抽象的思维层面考察此函数。
一、Literallly 字面义分析
先 literally 从字面上思考save-excursion,save毋庸赘言,拆解 excursion 为 ex + cur + sion 三个部分,其中 ex 是 out 向外 比如 exit, 而 cur 是行走,与 car 汽车同源,sion 为名词后缀,因此 excursion 就是走出去,远足,或者短途旅行的含义。
那么 save-excursion 是保存我的短途旅行吗(这句话非正常的表达)?或是保存远足旅行线路(似乎正常一点)? 也是教人一头雾水。
在引用手册定义之前,我们考察一个高频的应用场景。
二、工作流场景
假设当前正在读 elisp-introduction 手册,看到 save-excursion 函数,想要查询。
最便捷的方式就是 C-h f save-excursion:
但我比较不推荐这种方式,一是 help-info 不能编辑, 二是 不能对 save-excursion 这个函数一眼看到底的穷尽展示。
推荐从 elisp-manual 的 org 文件中查询:
在此处,一个亟待解决的问题凸显,我从当前的焦点走出去 excursion 出去做其他的事情,一番折腾之后,我还回得来吗?
可以想见,在excursion出去参阅manual的时候,又会遇到其他问题,比如查询单词,比如又查询新的函数,比如查看今天的任务等等,excursion 之外又有 excursion。只要分心走出去,几乎必然回不到最初的焦点。
此时,point-to-register 如及时雨赶到。在我们出发之前,就有了如下工作流:
1)C-x r Spc Spc 调用 point-to-register 在出发去excursion 之前,保存当前的焦点到 Spec 键上;
2) Excursion 浪出去,尽情肆意的做任何任务;
3) 任务完成之后,回到最初的焦点,C-x r j Spec 调用 jump-to-register。
以上三个步骤保障我们在任何时候,excursion出去做事,都能迷途知返。是最高频应用的工作流。
三、定义 save-excursion
以上三步的具体操作工作流,我们将其抽象出来,命名为 save-point-before-excurion 或者 save-point-for-excursion,或者将中间的两个单词去掉就是 save-excursion.
(save-excursion
task1
task2
...
last-task)
也就是说 save-excursion 自动完成了 point-to-register 和 jump-to-register 这两步启动和收尾的步骤,我们只须放宽心在excursion里做任务即可。
这时候,我们再打开黑匣子,查看定义:
This special form saves the identity of the current buffer and the value of point in it, evaluates BODY, and finally restores the buffer and its saved value of point. Both saved values are restored even in case of an abnormal exit via ‘throw’ or error (*note Nonlocal Exits::).
从定义中能窥见,能自然流畅逻辑无阻塞的从抽象思维到具体使用的save-excursion这个函数的方法,就是在大脑里将其自动扩展为:save-point-for-excursion.
如果本文不会招来评论区无价值的讨论,就做成日课,每日分享。