Node:fwd-para let, Next:fwd-para while, Previous:forward-paragraph in brief, Up:forward-paragraph
let* expressionThe next line of the forward-paragraph function begins a
let* expression. This is a different kind of expression than
we have seen so far. The symbol is let* not let.
The let* special form is like let except that Emacs sets
each variable in sequence, one after another, and variables in the
latter part of the varlist can make use of the values to which Emacs
set variables in the earlier part of the varlist.
In the let* expression in this function, Emacs binds two
variables: fill-prefix-regexp and paragraph-separate.
The value to which paragraph-separate is bound depends on the
value of fill-prefix-regexp.
Let's look at each in turn. The symbol fill-prefix-regexp is
set to the value returned by evaluating the following list:
(and fill-prefix
(not (equal fill-prefix ""))
(not paragraph-ignore-fill-prefix)
(regexp-quote fill-prefix))
This is an expression whose first element is the and special form.
As we learned earlier (see The kill-new function), the and special form evaluates each of its
arguments until one of the arguments returns a value of nil, in
which case the and expression returns nil; however, if
none of the arguments returns a value of nil, the value
resulting from evaluating the last argument is returned. (Since such
a value is not nil, it is considered true in Lisp.) In other
words, an and expression returns a true value only if all its
arguments are true.
In this case, the variable fill-prefix-regexp is bound to a
non-nil value only if the following four expressions produce a
true (i.e., a non-nil) value when they are evaluated; otherwise,
fill-prefix-regexp is bound to nil.
fill-prefix
nil.
(not (equal fill-prefix "")
(not paragraph-ignore-fill-prefix)
nil if the variable
paragraph-ignore-fill-prefix has been turned on by being set to a
true value such as t.
(regexp-quote fill-prefix)
and special form. If all the
arguments to the and are true, the value resulting from
evaluating this expression will be returned by the and expression
and bound to the variable fill-prefix-regexp,
The result of evaluating this and expression successfully is that
fill-prefix-regexp will be bound to the value of
fill-prefix as modified by the regexp-quote function.
What regexp-quote does is read a string and return a regular
expression that will exactly match the string and match nothing else.
This means that fill-prefix-regexp will be set to a value that
will exactly match the fill prefix if the fill prefix exists.
Otherwise, the variable will be set to nil.
The second local variable in the let* expression is
paragraph-separate. It is bound to the value returned by
evaluating the expression:
(if fill-prefix-regexp
(concat paragraph-separate
"\\|^" fill-prefix-regexp "[ \t]*$")
paragraph-separate)))
This expression shows why let* rather than let was used.
The true-or-false-test for the if depends on whether the variable
fill-prefix-regexp evaluates to nil or some other value.
If fill-prefix-regexp does not have a value, Emacs evaluates
the else-part of the if expression and binds
paragraph-separate to its local value.
(paragraph-separate is a regular expression that matches what
separates paragraphs.)
But if fill-prefix-regexp does have a value, Emacs evaluates
the then-part of the if expression and binds
paragraph-separate to a regular expression that includes the
fill-prefix-regexp as part of the pattern.
Specifically, paragraph-separate is set to the original value
of the paragraph separate regular expression concatenated with an
alternative expression that consists of the fill-prefix-regexp
followed by a blank line. The ^ indicates that the
fill-prefix-regexp must begin a line, and the optional
whitespace to the end of the line is defined by "[ \t]*$".)
The \\| defines this portion of the regexp as an alternative to
paragraph-separate.
Now we get into the body of the let*. The first part of the body
of the let* deals with the case when the function is given a
negative argument and is therefore moving backwards. We will skip this
section.