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.