大缓冲区的处理

beginning-of-buffer 中,内层 if 判断缓冲区大小是否超过 10000 字符。它使用 > 函数和 let 表达式中计算出的 size

早期版本使用 buffer-size,该函数会被多次调用,且返回整个缓冲区大小而非可访问部分。只对可访问部分计算才更合理。(关于聚焦到可访问部分的更多信息,参见 See Narrowing and Widening。)

判断语句如下:

(if (> size 10000)

如果缓冲区很大,就会执行 if 表达式的 then 分支。格式化以便阅读后,代码如下所示:

(*
  (prefix-numeric-value arg)
  (/ size 10))

该表达式是一个乘法运算,向函数 * 传入两个参数。

第一个参数是 (prefix-numeric-value arg)。当 "P" 用作 interactive 的参数时,传递给函数的参数是一个 原始前缀参数(raw prefix argument),而非数字。(它是一个包含数字的列表。)要进行算术运算,需要进行类型转换,而 prefix-numeric-value 就承担这一工作。

第二个参数是 (/ size 10)。该表达式将缓冲区可访问部分的大小对应的数值除以十。由此得到的数值,表示缓冲区大小的十分之一对应多少个字符。(在 Lisp 中,/ 用于除法,正如 * 用于乘法。)

在整个乘法表达式中,该数值会与前缀参数的值相乘 — 乘法形式如下:

(* numeric-value-of-prefix-arg
   number-of-characters-in-one-tenth-of-the-accessible-buffer)

例如,若前缀参数为 ‘7’,十分之一长度的数值会乘以 7,得到缓冲区百分之七十位置的偏移量。

综上,当缓冲区可访问部分较大时,goto-char 表达式如下:

(goto-char (* (prefix-numeric-value arg)
              (/ size 10)))

这样就将光标定位到了目标位置。