Node:rotate-yk-ptr arg, Next:rotate-yk-ptr negative arg, Previous:yank, Up:yank
The hard part of yank
is understanding the computation that
determines the value of the argument passed to
rotate-yank-pointer
. Fortunately, it is not so difficult as it
looks at first sight.
What happens is that the result of evaluating one or both of the
if
expressions will be a number and that number will be the
argument passed to rotate-yank-pointer
.
Laid out with comments, the code looks like this:
(if (listp arg) ; if-part 0 ; then-part (if (eq arg '-) ; else-part, inner if -1 ; inner if's then-part (1- arg)))) ; inner if's else-part
This code consists of two if
expression, one the else-part of
the other.
The first or outer if
expression tests whether the argument
passed to yank
is a list. Oddly enough, this will be true if
yank
is called without an argument--because then it will be
passed the value of nil
for the optional argument and an
evaluation of (listp nil)
returns true! So, if no argument is
passed to yank
, the argument passed to
rotate-yank-pointer
inside of yank
is zero. This means
the pointer is not moved and the first element to which
kill-ring-yank-pointer
points is inserted, as we expect.
Similarly, if the argument for yank
is C-u, this will be
read as a list, so again, a zero will be passed to
rotate-yank-pointer
. (C-u produces an unprocessed prefix
argument of (4)
, which is a list of one element.) At the same
time, later in the function, this argument will be read as a
cons
so point will be put in the front and mark at the end of
the insertion. (The P
argument to interactive
is
designed to provide these values for the case when an optional
argument is not provided or when it is C-u.)
The then-part of the outer if
expression handles the case when
there is no argument or when it is C-u. The else-part handles the
other situations. The else-part is itself another if
expression.
The inner if
expression tests whether the argument is a minus
sign. (This is done by pressing the <META> and - keys at the
same time, or the <ESC> key and then the - key). In this
case, the rotate-yank-pointer
function is passed -1 as an
argument. This moves the kill-ring-yank-pointer
backwards, which
is what is desired.
If the true-or-false-test of the inner if
expression is false
(that is, if the argument is not a minus sign), the else-part of the
expression is evaluated. This is the expression (1- arg)
.
Because of the two if
expressions, it will only occur when the
argument is a positive number or when it is a negative number (not
just a minus sign on its own). What (1- arg)
does is decrement
the number and return it. (The 1-
function subtracts one from
its argument.) This means that if the argument to
rotate-yank-pointer
is 1, it is reduced to zero, which means
the first element to which kill-ring-yank-pointer
points is
yanked back, as you would expect.