Copyright (C) 2000-2012 |
GNU Info (emacs-lisp-intro.info)fwd-sentence while loopsThe `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 |