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.