eintr: Complete kill-region

 
 The Complete ‘kill-region’ Definition
 -------------------------------------
 
 We will go through the ‘condition-case’ code in a moment.  First, let us
 look at the definition of ‘kill-region’, with comments added:
 
      (defun kill-region (beg end)
        "Kill (\"cut\") text between point and mark.
      This deletes the text from the buffer and saves it in the kill ring.
      The command \\[yank] can retrieve it from there. ... "
 
        ;; • Since order matters, pass point first.
        (interactive (list (point) (mark)))
        ;; • And tell us if we cannot cut the text.
        ;; 'unless' is an 'if' without a then-part.
        (unless (and beg end)
          (error "The mark is not set now, so there is no region"))
 
        ;; • '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.
        (condition-case nil
 
            ;; • The second argument to 'condition-case' tells the
            ;;    Lisp interpreter what to do when all goes well.
 
            ;;    It starts with a 'let' function that extracts the string
            ;;    and tests whether it exists.  If so (that is what the
            ;;    'when' checks), it calls an 'if' function that determines
            ;;    whether the previous command was another call to
            ;;    'kill-region'; if it was, then the new text is appended to
            ;;    the previous text; if not, then a different function,
            ;;    'kill-new', is called.
 
            ;;    The 'kill-append' function concatenates the new string and
            ;;    the old.  The 'kill-new' function inserts text into a new
            ;;    item in the kill ring.
 
            ;;    'when' is an 'if' without an else-part.  The second 'when'
            ;;    again checks whether the current string exists; in
            ;;    addition, it checks whether the previous command was
            ;;    another call to 'kill-region'.  If one or the other
            ;;    condition is true, then it sets the current command to
            ;;    be 'kill-region'.
            (let ((string (filter-buffer-substring beg end t)))
              (when string                    ;STRING is nil if BEG = END
                ;; Add that string to the kill ring, one way or another.
                (if (eq last-command 'kill-region)
                    ;;    − 'yank-handler' is an optional argument to
                    ;;    'kill-region' that tells the 'kill-append' and
                    ;;    'kill-new' functions how deal with properties
                    ;;    added to the text, such as 'bold' or 'italics'.
                    (kill-append string (< end beg) yank-handler)
                  (kill-new string nil yank-handler)))
              (when (or string (eq last-command 'kill-region))
                (setq this-command 'kill-region))
              nil)
 
          ;;  • 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 are read-only)
          ;;    then the body is executed.
          ;;    The first part of the third argument is the following:
          ((buffer-read-only text-read-only) ;; the if-part
           ;; ...  the then-part
           (copy-region-as-kill beg end)
           ;;    Next, also as part of the then-part, set this-command, so
           ;;    it will be set in an error
           (setq this-command 'kill-region)
           ;;    Finally, in the then-part, send a message if you may copy
           ;;    the text to the kill ring without signaling an error, but
           ;;    don't if you may not.
           (if kill-read-only-ok
               (progn (message "Read only text copied to kill ring") nil)
             (barf-if-buffer-read-only)
             ;; If the buffer isn't read-only, the text is.
             (signal 'text-read-only (list (current-buffer)))))