forward-sentence
函数定义以下是forward-sentence
的代码:
(defun forward-sentence (&optional arg) "向前移动到下一个句子末尾。带有参数时重复。带有负数参数时,反复向后移动到句子开头。 变量 `sentence-end' 是一个正则表达式,用于匹配句子的末尾。此外,每个段落边界也会终止句子。"
(interactive "p") (or arg (setq arg 1)) (let ((opoint (point)) (sentence-end (sentence-end))) (while (< arg 0) (let ((pos (point)) (par-beg (save-excursion (start-of-paragraph-text) (point)))) (if (and (re-search-backward sentence-end par-beg t) (or (< (match-end 0) pos) (re-search-backward sentence-end par-beg t))) (goto-char (match-end 0)) (goto-char par-beg))) (setq arg (1+ arg)))
(while (> arg 0) (let ((par-end (save-excursion (end-of-paragraph-text) (point)))) (if (re-search-forward sentence-end par-end t) (skip-chars-backward " \t\n") (goto-char par-end))) (setq arg (1- arg))) (constrain-to-field nil opoint t)))
这个函数乍一看似乎很长,最好先看它的骨架,然后再看它的实现。看骨架的方法是查看从最左列开始的表达式:
(defun forward-sentence (&optional arg) "documentation…" (interactive "p") (or arg (setq arg 1)) (let ((opoint (point)) (sentence-end (sentence-end))) (while (< arg 0) (let ((pos (point)) (par-beg (save-excursion (start-of-paragraph-text) (point)))) 向后移动时 while 循环的其余部分的主体 (while (> arg 0) (let ((par-end (save-excursion (end-of-paragraph-text) (point)))) 向前移动时 while 循环的其余部分的主体 处理表单和等价物的表达式
这看起来简单得多!函数定义由文档、一个interactive
表达式、一个or
表达式、一个let
表达式和while
循环组成。
让我们逐个查看这些部分。
我们注意到文档写得很详细且易懂。
函数有一个interactive "p"
声明。这意味着处理过的前缀参数(如果有)将作为函数的参数传递。 (这将是一个数字。)如果函数未以参数形式调用(它是可选的),则参数arg
将绑定为1。
当以非交互方式调用forward-sentence
且没有参数时,arg
绑定为nil
。or
表达式处理这一点。它的作用是仅在arg
绑定到一个值时保持arg
的值不变;或者在arg
绑定到nil
时将arg
的值设置为1。
接下来是一个let
。它指定了两个局部变量opoint
和sentence-end
的值。从搜索之前的点的局部值用于constrain-to-field
函数,该函数处理表单和等价物。sentence-end
变量由sentence-end
函数设置。