Go to the previous, next section.

The else-part of  copy-region-as-kill

Now, back to the explanation of  copy-region-as-kill :

If the last command is not  kill-region , then instead of calling  kill-append , it calls the else-part of the following code:

(if true-or-false-test
    what-is-done-if-test-returns-true
  ;; else-part
  (setq kill-ring
        (cons (buffer-substring beg end) kill-ring))
  (if (> (length kill-ring) kill-ring-max)
      (setcdr (nthcdr (1- kill-ring-max) kill-ring) nil)))

The  setq line of the else-part sets the new value of the kill ring to what results from adding the string being killed to the old kill ring.

We can see how this works with a little example:

(setq example-list '("here is a clause" "another clause"))

After evaluating this expression with C-x C-e, you can evaluate  example-list and see what it returns:

example-list
     @result{} ("here is a clause" "another clause")

Now, we can add a new element on to this list by evaluating the following expression:

(setq example-list (cons "a third clause" example-list))

When we evaluate  example-list , we find its value is:

example-list
     @result{} ("a third clause" "here is a clause" "another clause")

Thus, the third clause was added to the list by  cons .

This is exactly similar to what the  setq and  cons do in the function, except that  buffer-substring is used to pull out a copy of a region of text and hand it to the  cons . Here is the line again:

(setq kill-ring (cons (buffer-substring beg end) kill-ring))

The next segment of the else-part of  copy-region-as-kill is another  if clause. This  if clause keeps the kill ring from growing too long. It reads as follows:

(if (> (length kill-ring) kill-ring-max)
    (setcdr (nthcdr (1- kill-ring-max) kill-ring) nil)))

This code checks whether the length of the kill ring is greater than the maximum permitted length. This is the value of  kill-ring-max (which is 30, by default). If the length of the kill ring is too long, then this code sets the last element of the kill ring to  nil . It does this by using two functions,  nthcdr and  setcdr .

We looked at  setcdr earlier (see section  setcdr of a list, just as  setcar sets the CAR of a list. In this case, however,  setcdr will not be setting the  cdr of the whole kill ring; the  nthcdr function is used to cause it to set the  cdr of the next to last element of the kill ring--this means that since the  cdr of the next to last element is the last element of the kill ring, it will set the last element of the kill ring.

The  nthcdr function works by repeatedly taking the CDR of a list--it takes the CDR of the CDR of the CDR @dots{} It does this N times and returns the results.

Thus, if we had a four element list that was supposed to be three elements long, we could set the CDR of the next to last element to  nil , and thereby shorten the list.

You can see this by evaluating the following three expressions in turn. First set the value of  trees to  (maple oak pine birch) , then set the CDR of its second CDR to  nil and then find the value of  trees :

(setq trees '(maple oak pine birch))
     @result{} (maple oak pine birch)

(setcdr (nthcdr 2 trees) nil)
     @result{} nil

trees
     @result{} (maple oak pine)

(The value returned by the  setcdr expression is  nil since that is what the CDR is set to.)

To repeat, in  copy-region-as-kill , the  nthcdr function takes the CDR a number of times that is one less than the maximum permitted size of the kill ring and sets the CDR of that element (which will be the rest of the elements in the kill ring) to  nil . This prevents the kill ring from growing too long.

The next to last line of the  copy-region-as-kill function is

 (setq this-command 'kill-region) 

This line is not part of either the inner or the outer  if expression, so it is evaluated every time  copy-region-as-kill is called. Here we find the place where  this-command is set to  kill-region . As we saw earlier, when the next command is given, the variable  last-command will be given this value.

Finally, the last line of the  copy-region-as-kill function is:

(setq kill-ring-yank-pointer kill-ring)

The  kill-ring-yank-pointer is a global variable that is set to be the  kill-ring .

Even though the  kill-ring-yank-pointer is called a `pointer', it is a variable just like the kill ring. However, the name has been chosen to help humans understand how the variable is used. The variable is used in functions such as  yank and  yank-pop (see section Yanking Text Back).

This leads us to the code for bringing back text that has been cut out of the buffer--the yank commands. However, before discussing the yank commands, it is better to learn how lists are implemented in a computer. This will make clear such mysteries as the use of the term `pointer'.

Go to the previous, next section.