4.3.1 mark-whole-buffer 的函数体

mark-whole-buffer 的函数体由三行代码组成:

(push-mark (point))
(push-mark (point-max) nil t)
(goto-char (point-min))

第一行是表达式 (push-mark (point))

该行的作用与 simplified-beginning-of-buffer 函数体第一行 (push-mark) 完全相同。两种写法下,Lisp 解释器都会在光标当前位置设置标记。

我不清楚为何 mark-whole-buffer 中写作 (push-mark (point)),而 beginning-of-buffer 中写作 (push-mark)。或许编写代码的人不知道 push-mark 的参数是可选的,若不传入参数,函数会默认在光标位置设置标记。也可能是为了与下一行代码结构保持一致。无论如何,该行都会让 Emacs 获取光标位置并在此设置标记。

在早期版本的 GNU Emacs 中,mark-whole-buffer 的下一行是 (push-mark (point-max))。该表达式会在缓冲区编号最大的位置设置标记,即缓冲区结尾(若缓冲区已缩窄,则为可访问区域的结尾。有关缩窄的更多内容,参见 See Narrowing and Widening。)设置该标记后,原先在光标位置设置的标记会失效,但 Emacs 会像保存其他最近标记一样记住其位置。这意味着你可以按需按下两次 C-u C-SPC 回到该位置。

在 GNU Emacs 22 中,(point-max) 相关写法略微复杂。该行代码为:

(push-mark (point-max) nil t)

该表达式的功能与之前基本相同,会在缓冲区可访问的最大编号位置设置标记。不过此版本中 push-mark 多了两个参数。push-mark 的第二个参数为 nil,表示该函数 需要在设置标记时显示 “Mark set” 提示信息。第三个参数为 t,表示在临时标记模式开启时激活标记。临时标记模式会高亮当前活动区域,该模式通常处于关闭状态。

最后一行函数代码为 (goto-char (point-min)),写法与 beginning-of-buffer 中完全一致。该表达式将光标移至缓冲区最小位置,即缓冲区开头(或可访问区域的开头)。执行后,光标位于缓冲区开头,标记位于结尾,整个缓冲区即为选中区域。