Node:delete-and-extract-region, Previous:condition-case, Up:kill-region



8.2.2 delete-and-extract-region

A condition-case expression has two parts, a part that is evaluated in the expectation that all will go well, but which may generate an error; and a part that is evaluated when there is an error.

First, let us look at the code in kill-region that is run in the expectation that all goes well. This is the core of the function. The code looks like this:

(let ((string (delete-and-extract-region beg end)))
  (when string
    (if (eq last-command 'kill-region)
        (kill-append string (< end beg))
      (kill-new string)))
  (setq this-command 'kill-region))

It looks complicated because we have the new functions delete-and-extract-region, kill-append, and kill-new as well as the new variables, last-command and this-command.

The delete-and-extract-region function is straightforward. It is a built-in function that deletes the text in a region (a side effect) and also returns that text. This is the function that actually removes the text. (And if it cannot do that, it signals the error.)

In this let expression, the text that delete-and-extract-region returns is placed in the local variable called string. This is the text that is removed from the buffer. (To be more precise, the variable is set to point to the address of the extracted text; to say it is `placed in' the variable is simply a shorthand.)

If the variable string does point to text, that text is added to the kill ring. The variable will have a nil value if no text was removed.

The code uses when to determine whether the variable string points to text. A when statement is simply a programmers' convenience. A when statement is an if statement without the possibility of an else clause. In your mind, you can replace when with if and understand what goes on. That is what the Lisp interpreter does.

Technically speaking, when is a Lisp macro. A Lisp macro enables you to define new control constructs and other language features. It tells the interpreter how to compute another Lisp expression which will in turn compute the value. In this case, the `other expression' is an if expression. For more about Lisp macros, see Macros. The C programming language also provides macros. These are different, but also useful. We will briefly look at C macros in delete-and-extract-region: Digressing into C.

If the string has content, then another conditional expression is executed. This is an if with both a then-part and an else-part.

(if (eq last-command 'kill-region)
    (kill-append string (< end beg))
  (kill-new string)))

The then-part is evaluated if the previous command was another call to kill-region; if not, the else-part is evaluated.

last-command is a variable that comes with Emacs that we have not seen before. Normally, whenever a function is executed, Emacs sets the value of last-command to the previous command.

In this segment of the definition, the if expression checks whether the previous command was kill-region. If it was,

(kill-append string (< end beg))

concatenates a copy of the newly clipped text to the just previously clipped text in the kill ring. (If the (< end beg)) expression is true, kill-append prepends the string to the just previously clipped text. For a detailed discussion, see The kill-append function.)

If you then yank back the text, i.e., `paste' it, you get both pieces of text at once. That way, if you delete two words in a row, and then yank them back, you get both words, in their proper order, with one yank. (The (< end beg)) expression makes sure the order is correct.)

On the other hand, if the previous command is not kill-region, then the kill-new function is called, which adds the text to the kill ring as the latest item, and sets the kill-ring-yank-pointer variable to point to it.