Node:rotate-yk-ptr arg, Next:, Previous:yank, Up:yank



Passing the argument

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.