Copyright (C) 2000-2012 |
GNU Info (emacs-lisp-intro.info)rotate-yk-ptr else-partThe else-part of the `if' expression .................................... The else-part of the `if' expression is dedicated to setting the value of `kill-ring-yank-pointer' when the kill ring has something in it. The code looks like this: (setq kill-ring-yank-pointer (nthcdr (% (+ arg (- length (length kill-ring-yank-pointer))) length) kill-ring))))) This needs some examination. Clearly, `kill-ring-yank-pointer' is being set to be equal to some CDR of the kill ring, using the `nthcdr' function that is described in an earlier section. (Note: copy-region-as-kill.) But exactly how does it do this? Before looking at the details of the code let's first consider the purpose of the `rotate-yank-pointer' function. The `rotate-yank-pointer' function changes what `kill-ring-yank-pointer' points to. If `kill-ring-yank-pointer' starts by pointing to the first element of a list, a call to `rotate-yank-pointer' causes it to point to the second element; and if `kill-ring-yank-pointer' points to the second element, a call to `rotate-yank-pointer' causes it to point to the third element. (And if `rotate-yank-pointer' is given an argument greater than 1, it jumps the pointer that many elements.) The `rotate-yank-pointer' function uses `setq' to reset what the `kill-ring-yank-pointer' points to. If `kill-ring-yank-pointer' points to the first element of the kill ring, then, in the simplest case, the `rotate-yank-pointer' function must cause it to point to the second element. Put another way, `kill-ring-yank-pointer' must be reset to have a value equal to the CDR of the kill ring. That is, under these circumstances, (setq kill-ring-yank-pointer ("some text" "a different piece of text" "yet more text")) (setq kill-ring ("some text" "a different piece of text" "yet more text")) the code should do this: (setq kill-ring-yank-pointer (cdr kill-ring)) As a result, the `kill-ring-yank-pointer' will look like this: kill-ring-yank-pointer => ("a different piece of text" "yet more text")) The actual `setq' expression uses the `nthcdr' function to do the job. As we have seen before (Note: nthcdr), the `nthcdr' function works by repeatedly taking the CDR of a list--it takes the CDR of the CDR of the CDR ... The two following expressions produce the same result: (setq kill-ring-yank-pointer (cdr kill-ring)) (setq kill-ring-yank-pointer (nthcdr 1 kill-ring)) In the `rotate-yank-pointer' function, however, the first argument to `nthcdr' is a rather complex looking expression with lots of arithmetic inside of it: (% (+ arg (- length (length kill-ring-yank-pointer))) length) As usual, we need to look at the most deeply embedded expression first and then work our way towards the light. The most deeply embedded expression is `(length kill-ring-yank-pointer)'. This finds the length of the current value of the `kill-ring-yank-pointer'. (Remember that the `kill-ring-yank-pointer' is the name of a variable whose value is a list.) The measurement of the length is inside the expression: (- length (length kill-ring-yank-pointer)) In this expression, the first `length' is the variable that was assigned the length of the kill ring in the `let' statement at the beginning of the function. (One might think this function would be clearer if the variable `length' were named `length-of-kill-ring' instead; but if you look at the text of the whole function, you will see that it is so short that naming this variable `length' is not a bother, unless you are pulling the function apart into very tiny pieces as we are doing here.) So the line `(- length (length kill-ring-yank-pointer))' tells the difference between the length of the kill ring and the length of the list whose name is `kill-ring-yank-pointer'. To see how all this fits into the `rotate-yank-pointer' function, let's begin by analyzing the case where `kill-ring-yank-pointer' points to the first element of the kill ring, just as `kill-ring' does, and see what happens when `rotate-yank-pointer' is called with an argument of 1. The variable `length' and the value of the expression `(length kill-ring-yank-pointer)' will be the same since the variable `length' is the length of the kill ring and the `kill-ring-yank-pointer' is pointing to the whole kill ring. Consequently, the value of (- length (length kill-ring-yank-pointer)) will be zero. Since the value of `arg' will be 1, this will mean that the value of the whole expression (+ arg (- length (length kill-ring-yank-pointer))) will be 1. Consequently, the argument to `nthcdr' will be found as the result of the expression (% 1 length) automatically generated by info2www version 1.2.2.9 |