Whenever you cut or clip text out of a buffer with a `kill' command in GNU Emacs, it is stored in a list and you can bring it back with a `yank' command.
(The use of the word `kill' in Emacs for processes which specifically do not destroy the values of the entities is an unfortunate historical accident. A much more appropriate word would be `clip' since that is what the kill commands do; they clip text out of a buffer and put it into storage from which it can be brought back. I have often been tempted to replace globally all occurrences of `kill' in the Emacs sources with `clip' and all occurrences of `killed' with `clipped'.)
When text is cut out of a buffer, it is stored on a list. Successive pieces of text are stored on the list successively, so the list might look like this:
("a piece of text" "last piece")
cons can be used to add a piece of text to the list,
(cons "another piece" '("a piece of text" "last piece"))
If you evaluate this expression, a list of three elements will appear in the echo area:
("another piece" "a piece of text" "last piece")
nthcdr functions, you can retrieve
whichever piece of text you want. For example, in the following code,
nthcdr 1 ... returns the list with the first item removed;
car returns the first element of that remainder--the
second element of the original list:
(car (nthcdr 1 '("another piece" "a piece of text" "last piece"))) => "a piece of text"
The actual functions in Emacs are more complex than this, of course. The code for cutting and retrieving text has to be written so that Emacs can figure out which element in the list you want--the first, second, third, or whatever. In addition, when you get to the end of the list, Emacs should give you the first element of the list, rather than nothing at all.
The list that holds the pieces of text is called the kill ring.
This chapter leads up to a description of the kill ring and how it is
used by first tracing how the
zap-to-char function works. This
function uses (or `calls') a function that invokes a function that
manipulates the kill ring. Thus, before reaching the mountains, we
climb the foothills.
A subsequent chapter describes how text that is cut from the buffer is retrieved. See section Yanking Text Back.
zap-to-char function is written differently in GNU Emacs
version 18 and version 19. The version 19 implementation is simpler,
and works slightly differently. We will first show the function as it
is written for version 19 and then for version 18.
The Emacs version 19 implementation of the interactive
zap-to-char function removes the text in the region between the
location of the cursor (i.e., of point) up to and including the next
occurrence of a specified character. The text that
removes is put in the kill ring; and it can be retrieved from the kill
ring by typing C-y (
yank). If the command is given an
argument, it removes text through that number of occurrences. Thus, if the
cursor were at the beginning of this sentence and the character were
`s', `Thus' would be removed. If the argument were two,
`Thus, if the curs' would be removed, up to and including the
`s' in `cursor'.
The Emacs version 18 implementation removes the text from point up to but not including the specified character. Thus, in the example shown in the previous paragraph, the `s' would not be removed.
In addition, the version 18 implementation will go to the end of the buffer if the specified character is not found; but the version 19 implementation will simply generate an error (and not remove any text).
In order to determine how much text to remove, both versions of
zap-to-char use a search function. Searches are used extensively
in code that manipulates text, and it is worth focusing attention on the
search function as well as on the deletion command.
Here is the complete text of the version 19 implementation of the function:
(defun zap-to-char (arg char) ; version 19 implementation "Kill up to and including ARG'th occurrence of CHAR. Goes backward if ARG is negative; error if CHAR not found." (interactive "*p\ncZap to char: ") (kill-region (point) (progn (search-forward (char-to-string char) nil nil arg) (point))))
The interactive expression in the
zap-to-char command looks like
(interactive "*p\ncZap to char: ")
The part within quotation marks,
"*p\ncZap to char: ", specifies
three different things. First, and most simply, the asterisk, `*',
causes an error to be signalled if the buffer is read-only. This means that
if you try
zap-to-char in a read-only buffer you will not be able to
remove text, and you will receive a message that says "Buffer is
read-only"; your terminal may beep at you as well.
The second part of
"*p\ncZap to char: " is the `p'. This
part is ended by a newline, `\n'. The `p' means that the
first argument to the function will be passed the value of a `processed
prefix'. The prefix argument is passed by typing C-u and a
number, or M- and a number. If the function is called
interactively without a prefix, 1 is passed to this argument.
The third part of
"*p\ncZap to char: " is `cZap to char:
'. In this part, the lower case `c' indicates that
interactive expects a prompt and that the argument will be a
character. The prompt follows the `c' and is the string `Zap
to char: ' (with a space after the colon to make it look good).
What all this does is prepare the arguments to
zap-to-char so they
are of the right type, and give the user a prompt.
The body of the
zap-to-char function contains the code that
kills (that is, removes) the text in the region from the current
position of the cursor up to and including the specified character.
The first part of the code looks like this:
(kill-region (point) ...
(point) is the current position of the cursor.
The next part of the code is an expression using
progn. The body
progn consists of calls to
It is easier to understand how
progn works after learning about
search-forward, so we will look at
search-forward function is used to locate the
zap-to-char. If the search is
search-forward leaves point immediately after the
last character in the target string. (In this case the target string is
just one character long.) If the search is backwards,
search-forward leaves point just before the first character in
the target. Also,
t for true.
(Moving point is therefore a `side effect'.)
search-forward function looks like this:
(search-forward (char-to-string char) nil nil arg)
search-forward function takes four arguments:
zap-to-charis a single character. Because of the way computers are built, the Lisp interpreter treats a single character as being different from a string of characters. Inside the computer, a single character has a different electronic format than a string of one character. (A single character can often be recorded in the computer using exactly one byte; but a string may be longer or shorter, and the computer needs to be ready for this.) Since the
search-forwardfunction searches for a string, the character that the
zap-to-charfunction receives as its argument must be converted inside the computer from one format to the other; otherwise the
search-forwardfunction will fail. The
char-to-stringfunction is used to make this conversion.
nilas the third argument causes the function to signal an error when the search fails.
search-forwardis the repeat count--how many occurrences of the string to look for. This argument is optional and if the function is called without a repeat count, this argument is passed the value 1. If this argument is negative, the search goes backwards.
In template form, a
search-forward expression looks like this:
(search-forward "target-string" limit-of-search what-to-do-if-search-fails repeat-count)
We will look at
progn is a function that causes each of its arguments to be
evaluated in sequence and then returns the value of the last one. The
preceding expressions are evaluated only for the side effects they
perform. The values produced by them are discarded.
The template for a
progn expression is very simple:
progn expression has to do two things:
put point in exactly the right position; and return the location of
point so that
kill-region will know how far to kill to.
The first argument to the
search-forward finds the string, the function leaves point
immediately after the last character in the target string. (In this
case the target string is just one character long.) If the search is
search-forward leaves point just before the first
character in the target. The movement of point is a side effect.
The second and last argument to
progn is the expression
(point). This expression returns the value of point, which in
this case will be the location to which it has been moved by
search-forward. This value is returned by the
expression and is passed to
Now that we have seen how
we can see how the
zap-to-char function works as a whole.
The first argument to
kill-region is the position of the cursor
zap-to-char command is given--the value of point at
that time. Within the
progn, the search function then moves
point to just after the zapped-to-character and
point returns the
value of this location. The
kill-region function puts together
these two values of point, the first one as the beginning of the region
and the second one as the end of the region, and removes the region.
progn function is necessary because the
command takes two arguments; and it would fail if
point expressions were written in sequence as two
additional arguments. The
progn expression is a single argument
kill-region and returns the one value that
needs for its second argument.
The version 18 implementation of
zap-to-char is slightly
different from the version 19 implementation: it zaps the text up to but
not including the zapped-to-character; and zaps to the end of the buffer
if the specified character is not found.
The difference is in the second argument to the
command. Where the version 19 implementation looks like this:
(progn (search-forward (char-to-string char) nil nil arg) (point))
The version 18 implementation looks like this:
(if (search-forward (char-to-string char) nil t arg) (progn (goto-char (if (> arg 0) (1- (point)) (1+ (point)))) (point)) (if (> arg 0) (point-max) (point-min)))
This looks considerably more complicated, but the code can be readily understood if it is looked at part by part.
The first part is:
(if (search-forward (char-to-string char) nil t arg)
This fits into an
if expression that does the following job, as
we shall see:
(if able-to-locate-zapped-for-character-and-move-point-to-it then-move-point-to-the-exact-spot-and-return-this-location else-move-to-end-of-buffer-and-return-that-location)
Evaluation of the
if expression specifies the second argument to
kill-region. Since the first argument is point, this process
makes it possible for
kill-region to remove the text between
point and the zapped-to location.
We have already described how
search-forward moves point as a
side effect. The value that
search-forward returns is
if the search is successful and either
nil or an error message
depending on the value of the third argument to
In this case,
t is the third argument and it causes the function
nil when the search fails. As we will see, it is easy
to write the code for handling the case when the search returns
In the version 18 implementation of
zap-to-char, the search
takes place because the
if causes the search expression to be
evaluated as its true-or-false-test. If the search is successful,
Emacs evaluates the then-part of the
if expression. On the
other hand, if the search fails, Emacs evaluates the else-part of the
if expression, when the search succeeds, a
expression is executed--which is to say, it is run as a program.
As we said earlier,
progn is a function that causes each of its
arguments to be evaluated in sequence and then returns the value of the
last one. The preceding expressions are evaluated only for the side
effects they perform. The values produced by them are discarded.
In this version of
progn expression is
executed when the
search-forward function finds the character for
which it is searching. The
progn expression has to do two
things: put point in exactly the right position; and return the location
of point so that
kill-region will know how far to kill to.
The reason for all the code in the
progn is that when
search-forward finds the string it is looking for, it leaves
point immediately after the last character in the target string. (In
this case the target string is just one character long.) If the search
search-forward leaves point just before the first
character in the target.
However, this version of the
zap-to-char function is designed so
that it does not remove the character being zapped to. For example, if
zap-to-char is to remove all the text up to a `z', this
version will not remove the `z' as well. So point has to be moved
just enough that the zapped-to character is not removed.
The body of the
progn consists of two expressions. Spread out to
delineate the different parts more clearly, and with comments added, the
progn expression looks like this:
(progn (goto-char ; First expression in
progn. (if (> arg 0) ; If
argis positive, (1- (point)) ; move back one character; (1+ (point)))) ; else move forward one character. (point)) ; Second expression in
progn: ; return position of point.
progn expression does this: when the search is forward
arg is positive), Emacs leaves point just after the searched-for
character. By moving point back one position, the character is
uncovered. In this case, the expression in the
progn reads as
(goto-char (1- (point))). This moves point one
character back. (The
1- function subtracts one from its
argument, just as
1+ adds ones to its argument.) On the other
hand, if the argument to
zap-to-character is negative, the search
will be backwards. The
if detects this and the expression reads:
(goto-char (1+ (point))). (The
1+ function adds one to
The second and last argument to
progn is the expression
(point). This expression returns the value of the position to
which point is moved by the first argument to
value is then returned by the
if expression of which it is a
part and is passed to
In brief, the function works like this: the first argument to
kill-region is the position of the cursor when the
zap-to-char command is given--the value of point at that time.
The search function then moves point if the search is successful. The
progn expression moves point just enough so the zapped to
character is not removed, and returns the value of point after all this
is done. The
kill-region function then removes the region.
Finally, the else-part of the
if expression takes care of the
situation in which the zapped-towards character is not found. If the
argument to the
zap-to-char function is positive (or if none is
given) and the zapped-to character is not found, all the text is
removed from the current position of point to the end of the accessible
region of the buffer (the end of the buffer if there is no narrowing).
arg is negative and the zapped-to character is not found,
the operation goes to the beginning of the accessible region. The code
for this is a simple
(if (> arg 0) (point-max) (point-min))
This says that if
arg is a positive number, return the value of
point-max, otherwise, return the value of
For review, here is the code involving
(kill-region (point) ; beginning-of-region (if (search-forward (char-to-string char) ; target nil ; limit-of-search: none t ; Return
nilif fail. arg) ; repeat-count. (progn ; then-part (goto-char (if (> arg 0) (1- (point)) (1+ (point)))) (point)) (if (> arg 0) ; else-part (point-max) (point-min))))
As you can see, the version 19 implementation does slightly less than the version 18 implementation, but is much simpler.
zap-to-char function uses the
This function is very simple; leaving out part of its documentation
string, it looks like this:
(defun kill-region (beg end) "Kill between point and mark. The text is deleted but saved in the kill ring." (interactive "*r") (copy-region-as-kill beg end) (delete-region beg end))
The main point to note is that it uses the
copy-region-as-kill functions which are described in following
delete-region: A Digression into C
zap-to-char command uses the
which in turn uses two other functions,
copy-region-as-kill function will be
described in a following section; it puts a copy of the region in the
kill ring so it can be yanked back. (See section
delete-region function removes the contents of a region and
you cannot get it back.
Unlike the other code discussed here,
delete-region is not written
in Emacs Lisp; it is written in C and is one of the primitives of the GNU
Emacs system. Since it is very simple, I will digress briefly from Lisp
and describe it here.
Like many of the other Emacs primitives,
delete-region is written
as an instance of a C macro, a macro being a template for code. The
first section of the macro looks like this:
DEFUN ("delete-region", Fdelete_region, Sdelete_region, 2, 2, "r", "Delete the text between point and mark.\n\ When called from a program, expects two arguments,\n\ character numbers specifying the stretch to be deleted.")
Without getting into the details of the macro writing process, let me
point out that this macro starts with the word
DEFUN. The word
DEFUN was chosen since the code serves the same purpose as
defun does in Lisp. The word
DEFUN is followed by seven
parts inside of parentheses:
Fdelete_region. By convention, it starts with `F'. Since C does not use hyphens in names, an underscore is used instead.
interactivedeclaration in a function written in Lisp: a letter followed, perhaps, by a prompt. In this case, the letter is
"r"which indicates that the two arguments to the function will be the position of the beginning and end of a region in the buffer. In this code, there isn't any prompt.
The formal parameters come next, with a statement of what kind of object
they are, and then what might be called the `body' of the macro. For
delete-region the `body' consists of the following three lines:
validate_region (&b, &e); del_range (XINT (b), XINT (e)); return Qnil;
The first function,
validate_region checks whether the values
passed as the beginning and end of the region are the proper type and
are within range. The second function,
deletes the text. If the function completes its work without error, the
third line returns
Qnil to indicate this.
del_range is a complex function we will not look into. It
updates the buffer and does other things. However, it is worth
looking at the two arguments passed to
del_range. These are
XINT (b) and
XINT (e). As far as the C language
e are two thirty-two bit integers
that mark the beginning and end of the region to be deleted. But like
other numbers in Emacs Lisp, only twenty-four bits of the thirty-two
bits are used for the number; the remaining eight bits are used for
keeping track of the type of information and other purposes. (On
certain machines, only six bits are so used.) In this case, the eight
bits are used to indicate that these numbers are for buffer positions.
When bits of a number are used this way, they are called a tag.
The use of the eight bit tag on each thirty-two bit integer made it
possible to write Emacs to run much faster than it would otherwise.
On the other hand, with numbers limited to twenty-four bits, Emacs
buffers are limited to approximately eight megabytes. (You can
sharply increase the maximum buffer size by adding defines for
GCTYPEBITS in the `emacs/src/config.h'
file before compiling. See the note in the `emacs/etc/FAQ' file
that is part of the Emacs distribution.)
`XINT' is a C macro that extracts the 24 bit number from the
thirty-two bit Lisp object; the eight bits used for other purposes are
del_range (XINT (b), XINT (e)) deletes the
region between the beginning position,
b, and the ending
From the point of view of the person writing Lisp, Emacs is all very simple; but hidden underneath is a great deal of complexity to make it all work.
delete-region function, the
function is written in Emacs Lisp. It copies a region in a buffer
and saves it in a variable called the
kill-ring. This section
describes how this variable is created and initialized.
(Again we note that the term
kill-ring is a misnomer. The text
that is clipped out of the buffer can be brought back; it is not a ring
of corpses, but a ring of resurrectable text.)
In Emacs Lisp, a variable such as the
kill-ring is created and
given an initial value by using the
defvar special form. The
name comes from "define variable".
defvar special form is similar to
setq in that it sets
the value of a variable. It is unlike
setq in two ways: first,
it only sets the value of the variable if the variable does not already
have a value. If the variable already has a value,
not override the existing value. Second,
defvar has a
You can see the current value of a variable, any variable, by using
describe-variable function, which is usually invoked by
typing C-h v. If you type C-h v and then
(followed by RET) when prompted, you will see what is in your
current kill ring--this may be quite a lot! Conversely, if you have
been doing nothing this Emacs session except read this document, you
may have nothing in it. At the end of the `*Help*' buffer, you
will see the documentation for
Documentation: List of killed text sequences.
The kill ring is defined by a
defvar in the following way:
(defvar kill-ring nil "List of killed text sequences.")
In this variable definition, the variable is given an initial value of
nil, which makes sense, since if you have saved nothing, you want
nothing back if you give a
yank command. The documentation
string is written just like the documentation string of a
As with the documentation string of the
defun, the first line of
the documentation should be a complete sentence, since some commands,
apropos, print only the first line of documentation.
Succeeding lines should not be indented; otherwise they look odd when
you use C-h v (
Most variables are internal to Emacs, but some are intended as options
that you can readily set with the
edit-options command. (These
settings last only for the duration of an editing session; to set a
value permanently, write a `.emacs' file. See section Your `.emacs' File.)
A readily settable variable is distinguished from others in Emacs by an asterisk, `*', in the first column of its documentation string.
(defvar line-number-mode nil "*Non-nil means display line number in mode line.")
This means that you can use the
edit-options command to change
the value of
Of course, you can also change the value of
evaluating it within a
setq expression, like this:
(setq line-number-mode t)
See section Using
copy-region-as-kill function copies a region of text from a
buffer and saves it in a variable called the
If you call
copy-region-as-kill immediately after a
kill-region command, Emacs appends the newly copied text to the
previously copied text. This means that if you yank back the text, you
get it all, from both this and the previous operation. On the other
hand, if some other command precedes the
the function copies the text into a separate entry in the kill ring.
Here is the complete text of the version 18
copy-region-as-kill, formatted for clarity with several
(defun copy-region-as-kill (beg end) "Save the region as if killed, but don't kill it." (interactive "r") (if (eq last-command 'kill-region) ;; then-part: Combine newly copied text ;; with previously copied text. (kill-append (buffer-substring beg end) (< end beg)) ;; else-part: Add newly copied text as a new element ;; to the kill ring and shorten the kill ring if necessary. (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))) (setq this-command 'kill-region) (setq kill-ring-yank-pointer kill-ring))
As usual, this function can be divided into its component parts:
(defun copy-region-as-kill (argument-list) "documentation..." (interactive "r") body...)
The arguments are
end and the function is
"r", so the two arguments must refer to the
beginning and end of the region. If you have been reading though this
document from the beginning, understanding these parts of a function is
almost becoming routine.
The documentation is somewhat confusing unless you remember that the word `kill' has a meaning different from its usual meaning.
The body of the function starts with an
if clause. What this
clause does is distinguish between two different situations: whether
or not this command is executed immediately after a previous
command. In the first case, the new region is appended to the
previously copied text. Otherwise, it is inserted into the beginning
of the kill ring as a separate piece of text from the previous piece.
The last two lines of the function are two
setq expressions. One
of them sets the variable
the other sets the variable
kill-ring-yank-pointer to point to
the kill ring.
The body of
copy-region-as-kill merits discussion in detail.
copy-region-as-kill function is written so that two or more
kills in a row combine their text into a single entry. If you yank back
the text from the kill ring, you get it all in one piece. Moreover,
kills that kill forward from the current position of the cursor are
added to the end of the previously copied text and commands that copy
text backwards add it to the beginning of the previously copied text.
This way, the words in the text stay in the proper order.
The function makes use of two variables that keep track of the current
and previous Emacs command. The two variables are
Normally, whenever a function is executed, Emacs sets the value of
this-command to the function being executed (which in this case
copy-region-as-kill). At the same time, Emacs sets
the value of
last-command to the previous value of
this-command. However, the
is different; it sets the value of
kill-region, which is the name of the function that calls
In the first part of the body of the
if expression determines whether the value of
kill-region. If so, the then-part of
if expression is evaluated; it uses the
function to concatenate the text copied at this call to the function
with the text already in the first element (the CAR) of the kill
ring. On the other hand, if the value of
last-command is not
kill-region, then the
attaches a new element to the kill ring.
if expression reads as follows; it uses
eq, which is
a function we have not yet seen:
(if (eq last-command 'kill-region) ;; then-part (kill-append (buffer-substring beg end) (< end beg))
eq function tests whether its first argument is the same Lisp
object as its second argument. The
eq function is similar to the
equal function in that it is used to test for equality, but
differs in that it determines whether two representations are actually
the same object inside the computer, but with different names.
equal determines whether the structure and contents of two
expressions are the same.
kill-append function looks like this:
(defun kill-append (string before-p) (setcar kill-ring (if before-p (concat string (car kill-ring)) (concat (car kill-ring) string))))
We can look at this function in parts. The
setcar function uses
concat to concatenate the new text to the CAR of the kill
ring. Whether it prepends or appends the text depends on the results of
(if before-p ; if-part (concat string (car kill-ring)) ; then-part (concat (car kill-ring) string)) ; else-part
If the region being killed is before the region that was killed in the
last command, then it should be prepended before the material that was
saved in the previous kill; and conversely, if the killed text follows
what was just killed, it should be appended after the previous text.
if expression depends on the predicate
decide whether the newly saved text should be put before or after the
previously saved text.
before-p is the name of one of the arguments to
kill-append. When the
kill-append function is
evaluated, it is bound to the value returned by evaluating the actual
argument. In this case, this is the expression
(< end beg).
This expression does not directly determine whether the killed text in
this command is located before or after the kill text of the last
command; what is does is determine whether the value of the variable
end is less than the value of the variable
beg. If it
is, it means that the user is most likely heading towards the
beginning of the buffer. Also, the result of evaluating the predicate
(< end beg), will be true and the text will be
prepended before the previous text. On the other hand, if the value of
end is greater than the value of the variable
beg, the text will be appended after the previous text.
When the newly saved text will be prepended, then the string with the new text will be concatenated before the old test:
(concat string (car kill-ring))
But if the text will be appended, it will be concatenated after the old text:
(concat (car kill-ring) string))
To understand how this works, we first need to review the
concat function. The
concat function links together or
unites two strings of text. The result is a string. For example:
(concat "abc" "def") => "abcdef" (concat "new " (car '("first element" "second element"))) => "new first element" (concat (car '("first element" "second element")) " modified") => "first element modified"
We can now make sense of
kill-append: it modifies the contents
of the kill ring. The kill ring is a list, each element of which is
saved text. The
setcar function actually changes the first
element of this list. It does this by using
concat to replace
the old first element of the kill ring (the CAR of the kill ring)
with a new first element made by concatenating together the old saved
text and the newly saved text. The newly saved text is put in front
of the old text or after the old text, depending on whether it is in
front of or after the old text in the buffer from which it is cut.
The whole concatenation becomes the new first element of the kill
Incidentally, this is what the beginning of my current kill ring looks like:
("concatenating together" "saved text" "element" ...
Now, back to the explanation of
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)))
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
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 => ("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 => ("a third clause" "here is a clause" "another clause")
Thus, the third clause was added to the list by
This is exactly similar to what the
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
(setq kill-ring (cons (buffer-substring beg end) kill-ring))
The next segment of the else-part of
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
(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
does this by using two functions,
We looked at
setcdr earlier (see section
It sets the CDR of a list, just as
setcar sets the
CAR of a list. In this case, however,
setcdr will not be
cdr of the whole kill ring; the
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.
nthcdr function works by repeatedly taking the CDR of a
list--it takes the CDR of the CDR of the CDR
... 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
nil, and thereby shorten the list.
You can see this by evaluating the following three expressions in turn.
First set the value of
(maple oak pine birch),
then set the CDR of its second CDR to
nil and then
find the value of
(setq trees '(maple oak pine birch)) => (maple oak pine birch) (setcdr (nthcdr 2 trees) nil) => nil trees => (maple oak pine)
(The value returned by the
setcdr expression is
that is what the CDR is set to.)
To repeat, in
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
expression, so it is evaluated every time
called. Here we find the place where
this-command is set to
kill-region. As we saw earlier, when the next command is given,
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)
kill-ring-yank-pointer is a global variable that is set to be
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-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'.
Here is a brief summary of some recently introduced functions.
carreturns the first element of a list;
cdrreturns the second and subsequent elements of a list. For example:
(car '(1 2 3 4 5 6 7)) => 1 (cdr '(1 2 3 4 5 6 7)) => (2 3 4 5 6 7)
consconstructs a list by prepending its first argument to its second argument. For example:
(cons 1 '(2 3 4)) => (1 2 3 4)
cdr`n' times on a list. The `rest of the rest' as it were. For example:
(nthcdr 3 '(1 2 3 4 5 6 7)) => (4 5 6 7)
setcarchanges the first element of a list;
setcdrchanges the second and subsequent elements of a list. For example:
(setq triple '(1 2 3)) (setcar triple '37) triple => (37 2 3) (setcdr triple '("foo" "bar")) triple => (37 "foo" "bar")
(progn 1 2 3 4) => 4
nilor an error message.
kill-regioncuts the text between point and mark from the buffer and stores that text in the kill ring, so you can get it back by yanking.
delete-regionremoves the text between point and mark from the buffer and throws it away. You cannot get it back.
copy-region-as-killcopies the text between point and mark into the kill ring, from which you can get it by yanking. The function does not cut or remove the text from the buffer.
search-forwardfor the name of this function; if you do, you will overwrite the existing version of
search-forwardthat comes with Emacs. Use a name such as
copy-region-as-killno longer sets
this-command. What are the consequences of this change? What do you suppose motivated it?
Go to the first, previous, next, last section, table of contents.