delete-region
: A Digression into C
The zap-to-char
command uses the kill-region
function,
which in turn uses two other functions, copy-region-as-kill
and
delete-region
. The 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 copy-region-as-kill
.)
The 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:
delete-region
.
Fdelete_region
.
By convention, it starts with `F'. Since C does not use hyphens
in names, an underscore is used instead.
interactive
declaration 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, del_range
, actually
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
is concerned, b
and 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
VALBITS
and 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
discarded. So del_range (XINT (b), XINT (e))
deletes the
region between the beginning position, b
, and the ending
position, e
.
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.
Go to the first, previous, next, last section, table of contents.