Go to the first, previous, next, last section, table of contents.


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:

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.