Copyright (C) 2000-2012 |
GNU Info (emacs-lisp-intro.info)rotate-yk-ptr argPassing 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. |