let*
expressionforward-paragraph
函数的下一行开始了一个 let*
表达式 (see let*
introduced),在其中 Emacs 绑定了七个变量:opoint
、fill-prefix-regexp
、parstart
、parsep
、sp-parstart
、start
和 found-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*
表达式中的下两个局部变量旨在从 parstart
和 parsep
中删除 ‘^’ 的实例。接下来的表达式再次设置 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
,用于搜索,然后最后两个,start
和 found-start
,被设置为 nil
。
现在我们进入了 let*
的主体。 let*
的主体的第一部分处理函数被给予负参数且因此向后移动的情况。我们将跳过这一部分。