GNU Info

Info Node: (emacs-lisp-intro.info)fwd-sentence while loops

(emacs-lisp-intro.info)fwd-sentence while loops


Next: fwd-sentence re-search Prev: Complete forward-sentence Up: forward-sentence
Enter node , (file) or (file)node

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.  (Note: 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.


automatically generated by info2www version 1.2.2.9