在大缓冲区中发生了什么

beginning-of-buffer中,内部的if表达式测试缓冲区的大小是否大于10,000个字符。为了做到这一点,它使用了>函数和来自let表达式的size计算。

在旧版本中,使用了buffer-size函数。不仅调用了该函数多次,而且它给出的是整个缓冲区的大小,而不是可访问部分的大小。当只处理可访问部分时,计算会更有意义。关于将注意力集中到可访问部分的更多信息,请参阅《缩小和扩大》。

这一行看起来像这样:

(if (> size 10000)

当缓冲区很大时,if表达式的then部分将被评估。它读起来像这样(格式化以便阅读):

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

这个表达式是一个乘法,具有*函数的两个参数。

第一个参数是(prefix-numeric-value arg)。当interactive的参数为"P"时,传递给函数的参数是一个原始前缀参数,而不是一个数字(它是一个列表中的数字)。为了进行算术运算,需要进行转换,prefix-numeric-value完成了这个任务。

第二个参数是(/ size 10)。这个表达式将数值除以十—可访问部分缓冲区大小的数值。这产生一个数字,告诉我们十分之一缓冲区大小由多少字符组成。在Lisp中,/用于除法,就像*用于乘法一样。

在整个乘法表达式中,这个数量被乘以前缀参数的值—乘法看起来像这样:

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

例如,如果前缀参数是‘7’,那么十分之一的值将乘以7,以给出在缓冲区大小的70%的位置。

所有这些的结果是,如果可访问部分的缓冲区很大,那么goto-char表达式将如下:

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

这把光标放在我们想要的位置。