Go to the previous, next section.

The  while loops

Two  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 section 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.

Go to the previous, next section.