forward-sentence 関数定義を完了 ¶forward-sentenceのコードは以下の通りです:
(defun forward-sentence (&optional arg) "Move forward to next end of sentence. With argument, repeat. With negative argument, move backward repeatedly to start of sentence. The variable `sentence-end' is a regular expression that matches ends of sentences. Also, every paragraph boundary terminates sentences as well."
(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
が値にバインドされている場合に限り arg の値をそのまま保持するか、あるいは arg が nil にバインドされている場合に arg の値を 1 に設定します。
次は let です。これは2つのローカル変数、opoint と sentence-end
の値を指定します。検索前の point のローカル値は、フォームと等価物を扱う constrain-to-field 関数で使用されます。sentence-end 変数は sentence-end
関数によって設定されます。