The let* expression

forward-paragraph 函数的下一行开始了一个 let* 表达式 (see let* introduced),在其中 Emacs 绑定了七个变量:opointfill-prefix-regexpparstartparsepsp-parstartstartfound-start

变量 parsep 出现两次,首先是为了去除 ‘^’ 的实例,其次是为了处理填充前缀。

变量 opoint 只是 point 的值。正如你可以猜到的,它在一个 constrain-to-field 表达式中使用,就像在 forward-sentence 中一样。

变量 fill-prefix-regexp 被设置为通过评估以下列表返回的值:

(and fill-prefix
     (not (equal fill-prefix ""))
     (not paragraph-ignore-fill-prefix)
     (regexp-quote fill-prefix))

这是一个表达式,其第一个元素是 and 特殊形式。

正如我们之前学到的(see kill-new 函数),and 特殊形式评估其每个参数,直到其中一个参数返回 nil 的值,此时 and 表达式返回 nil;然而,如果没有任何参数返回 nil 的值,则评估最后一个参数产生的值将被返回。 (由于这样的值不是 nil,在 Lisp 中被视为真值。) 换句话说,只有当 and 表达式的所有参数都为真时,它才返回真值。

在这种情况下,只有当以下四个表达式在评估时产生真值(即非 nil 值)时,变量 fill-prefix-regexp 才绑定到非 nil 值;否则,fill-prefix-regexp 被绑定到 nil

fill-prefix

评估此变量时,返回填充前缀的值(如果有的话)。如果没有填充前缀,则此变量返回 nil

(not (equal fill-prefix ""))

此表达式检查现有填充前缀是否为空字符串,即不包含任何字符的字符串。空字符串不是有用的填充前缀。

(not paragraph-ignore-fill-prefix)

如果变量 paragraph-ignore-fill-prefix 被设置为真值,如 t,则此表达式返回 nil

(regexp-quote fill-prefix)

这是 and 特殊形式的最后一个参数。如果 and 的所有参数都为真,则通过评估此表达式产生的值将被 and 表达式返回,并绑定到变量 fill-prefix-regexp

成功评估此 and 表达式的结果是,fill-prefix-regexp 将绑定到由 regexp-quote 函数修改的 fill-prefix 的值。 regexp-quote 做的是读取一个字符串并返回一个正则表达式,该正则表达式将精确匹配该字符串且不匹配其他任何内容。这意味着如果存在填充前缀,fill-prefix-regexp 将被设置为一个精确匹配填充前缀的值。否则,该变量将被设置为 nil

let* 表达式中的下两个局部变量旨在从 parstartparsep 中删除 ‘^’ 的实例。接下来的表达式再次设置 parsep。这是为了处理填充前缀。

这是定义调用 let* 而不是 let 的设置。 if 表达式的真假测试取决于变量 fill-prefix-regexp 是否评估为 nil 或其他值。

如果 fill-prefix-regexp 没有值,Emacs 评估 if 表达式的 else-部分,并将 parsep 绑定到其局部值。 (parsep 是一个匹配段落之间分隔符的正则表达式。)

但是,如果 fill-prefix-regexp 有值,Emacs 将评估 if 表达式的 then-部分,并将 parsep 绑定到一个正则表达式,该正则表达式包含 fill-prefix-regexp 作为模式的一部分。

具体而言,parsep 被设置为段落分隔正则表达式的原始值,后面跟着一个可选的空白到行尾的替代表达式,由 "[ \t]*$" 定义。) ‘\\|’ 定义了正则表达式的这一部分作为 parsep 的替代项。

根据代码中的注释,接下来的局部变量,sp-parstart,用于搜索,然后最后两个,startfound-start,被设置为 nil

现在我们进入了 let* 的主体。 let* 的主体的第一部分处理函数被给予负参数且因此向后移动的情况。我们将跳过这一部分。