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))))
rest-of-body-of-while-loop-when-going-backwards
(while (> arg 0)
(let ((par-end (save-excursion (end-of-paragraph-text) (point))))
rest-of-body-of-while-loop-when-going-forwards
handle-forms-and-equivalent
这样看起来清晰很多!函数定义包含文档字符串、interactive 表达式、or 表达式、let 表达式与 while 循环。
下面逐一分析这些部分。
可以看到文档字符串详尽且清晰。
该函数使用 interactive "p" 声明。这意味着处理后的前缀参数(若有)会作为参数传递给函数。(该参数为数字。)若函数未接收参数(可选),则参数 arg 会绑定到 1。
当以非交互方式无参数调用 forward-sentence 时,arg 会绑定到 nil。or 表达式用于处理这种情况:若 arg 已有绑定值则保持不变,若为 nil 则将其设为 1。
接下来是 let 表达式,定义了两个局部变量 opoint 与 sentence-end。搜索前的光标局部值用于 constrain-to-field 函数,该函数用于处理格式与等价内容。sentence-end 变量由 sentence-end 函数设置。