Node:fwd-sentence while loops, Next:fwd-sentence re-search, Previous:Complete forward-sentence, Up:forward-sentence
while loopsTwo while loops follow the or expression. The first
while has a true-or-false-test that tests true if the prefix
argument for forward-sentence is a negative number. This is for
going backwards. The body of this loop is similar to the body of the
second while clause, but it is not exactly the same. We will
skip this while loop and concentrate on the second while
loop.
The second while loop is for moving point forward. Its skeleton
looks like this:
(while (> arg 0) ; true-or-false-test
(let varlist
(if (true-or-false-test)
then-part
else-part
(setq arg (1- arg)))) ; while loop decrementer
The while loop is of the decrementing kind.
(See A Loop with a Decrementing Counter.) It
has a true-or-false-test that tests true so long as the counter (in
this case, the variable arg) is greater than zero; and it has a
decrementer that subtracts 1 from the value of the counter every time
the loop repeats.
If no prefix argument is given to forward-sentence, which is
the most common way the command is used, this while loop will
run once, since the value of arg will be 1.
The body of the while loop consists of a let expression,
which creates and binds a local variable, and has, as its body, an
if expression.
The body of the while loop looks like this:
(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)))
The let expression creates and binds the local variable
par-end. As we shall see, this local variable is designed to
provide a bound or limit to the regular expression search. If the
search fails to find a proper sentence ending in the paragraph, it will
stop on reaching the end of the paragraph.
But first, let us examine how par-end is bound to the value of
the end of the paragraph. What happens is that the let sets the
value of par-end to the value returned when the Lisp interpreter
evaluates the expression
(save-excursion (end-of-paragraph-text) (point))
In this expression, (end-of-paragraph-text) moves point to the
end of the paragraph, (point) returns the value of point, and then
save-excursion restores point to its original position. Thus,
the let binds par-end to the value returned by the
save-excursion expression, which is the position of the end of
the paragraph. (The (end-of-paragraph-text) function uses
forward-paragraph, which we will discuss shortly.)
Emacs next evaluates the body of the let, which is an if
expression that looks like this:
(if (re-search-forward sentence-end par-end t) ; if-part
(skip-chars-backward " \t\n") ; then-part
(goto-char par-end))) ; else-part
The if tests whether its first argument is true and if so,
evaluates its then-part; otherwise, the Emacs Lisp interpreter
evaluates the else-part. The true-or-false-test of the if
expression is the regular expression search.
It may seem odd to have what looks like the `real work' of
the forward-sentence function buried here, but this is a common
way this kind of operation is carried out in Lisp.