Programming in Emacs Lisp
We will go through the
condition-case code in a moment. First,
let us look at the complete definition of
(defun kill-region (beg end)
"Kill between point and mark.
The text is deleted but saved in the kill ring."
;; 1. `condition-case' takes three arguments.
;; If the first argument is nil, as it is here,
;; information about the error signal is not
;; stored for use by another function.
;; 2. The second argument to `condition-case'
;; tells the Lisp interpreter what to do when all goes well.
;; The `delete-and-extract-region' function usually does the
;; work. If the beginning and ending of the region are both
;; the same, then the variable `string' will be empty, or nil
(let ((string (delete-and-extract-region beg end)))
;; `when' is an `if' clause that cannot take an `else-part'.
;; Emacs normally sets the value of `last-command' to the
;; previous command.
;; `kill-append' concatenates the new string and the old.
;; `kill-new' inserts text into a new item in the kill ring.
(if (eq last-command 'kill-region)
;; if true, prepend string
(kill-append string (< end beg))
(setq this-command 'kill-region))
;; 3. The third argument to `condition-case' tells the interpreter
;; what to do with an error.
;; The third argument has a conditions part and a body part.
;; If the conditions are met (in this case,
;; if text or buffer is read-only)
;; then the body is executed.
((buffer-read-only text-read-only) ;; this is the if-part
(copy-region-as-kill beg end)
(if kill-read-only-ok ;; usually this variable is nil
(message "Read only text copied to kill ring")
;; or else, signal an error if the buffer is read-only;
;; and, in any case, signal that the text is read-only.
(signal 'text-read-only (list (current-buffer)))))))