changeset 20279:69a6030e443a

(kill-region): Detect read-only text by getting an error trying to delete it. Handle the cases where we can, and can't, get the killed text from the undo list with much the same code.
author Karl Heuer <kwzh@gnu.org>
date Wed, 19 Nov 1997 21:36:56 +0000
parents 17c72edb5980
children 7916c0d8f2ae
files lisp/simple.el
diffstat 1 files changed, 40 insertions(+), 42 deletions(-) [+]
line wrap: on
line diff
--- a/lisp/simple.el	Wed Nov 19 04:25:20 1997 +0000
+++ b/lisp/simple.el	Wed Nov 19 21:36:56 1997 +0000
@@ -1423,48 +1423,46 @@
 the text killed this time appends to the text killed last time
 to make one entry in the kill ring."
   (interactive "r")
-  (cond
-
-   ;; If the buffer is read-only, we should beep, in case the person
-   ;; just isn't aware of this.  However, there's no harm in putting
-   ;; the region's text in the kill ring, anyway.
-   ((and (not inhibit-read-only)
-	 (or buffer-read-only
-	     (text-property-not-all beg end 'read-only nil)))
-    (copy-region-as-kill beg end)
-    ;; This should always barf, and give us the correct error.
-    (if kill-read-only-ok
-	(message "Read only text copied to kill ring")
-      (setq this-command 'kill-region)
-      ;; Signal an error if the buffer is read-only.
-      (barf-if-buffer-read-only)
-      ;; If the buffer isn't read-only, the text is.
-      (signal 'text-read-only (list (current-buffer)))))
-
-   ;; In certain cases, we can arrange for the undo list and the kill
-   ;; ring to share the same string object.  This code does that.
-   ((not (or (eq buffer-undo-list t)
-	     (eq last-command 'kill-region)
-	     ;; Use = since positions may be numbers or markers.
-	     (= beg end)))
-    ;; Don't let the undo list be truncated before we can even access it.
-    (let ((undo-strong-limit (+ (- (max beg end) (min beg end)) 100))
-	  (old-list buffer-undo-list)
-	  tail)
-      (delete-region beg end)
-      ;; Search back in buffer-undo-list for this string,
-      ;; in case a change hook made property changes.
-      (setq tail buffer-undo-list)
-      (while (not (stringp (car (car tail))))
-	(setq tail (cdr tail)))
-      ;; Take the same string recorded for undo
-      ;; and put it in the kill-ring.
-      (kill-new (car (car tail)))))
-
-   (t
-    (copy-region-as-kill beg end)
-    (delete-region beg end)))
-  (setq this-command 'kill-region))
+  (condition-case nil
+      ;; Don't let the undo list be truncated before we can even access it.
+      (let ((undo-strong-limit (+ (- (max beg end) (min beg end)) 100))
+	    (old-list buffer-undo-list)
+	    tail
+	    ;; If we can't rely on finding the killed text
+	    ;; in the undo list, save it now as a string.
+	    (string (if (or (eq buffer-undo-list t)
+			    (= beg end))
+			(buffer-substring beg end))))
+	(delete-region beg end)
+	;; Search back in buffer-undo-list for this string,
+	;; in case a change hook made property changes.
+	(setq tail buffer-undo-list)
+	(unless string
+	  (while (not (stringp (car (car tail))))
+	    (setq tail (cdr tail)))
+	  ;; If we did not already make the string to use,
+	  ;; use the same one that undo made for us.
+	  (setq string (car (car tail))))
+	;; Add that string to the kill ring, one way or another.
+	(if (eq last-command 'kill-region)
+	    (kill-append string (< end beg))
+	  (kill-new string))
+	(setq this-command 'kill-region))
+    ((buffer-read-only text-read-only)
+     ;; The code above failed because the buffer, or some of the characters
+     ;; in the region, are read-only.
+     ;; We should beep, in case the user just isn't aware of this.
+     ;; However, there's no harm in putting
+     ;; the region's text in the kill ring, anyway.
+     (copy-region-as-kill beg end)
+     ;; This should always barf, and give us the correct error.
+     (if kill-read-only-ok
+	 (message "Read only text copied to kill ring")
+       (setq this-command 'kill-region)
+       ;; Signal an error if the buffer is read-only.
+       (barf-if-buffer-read-only)
+       ;; If the buffer isn't read-only, the text is.
+       (signal 'text-read-only (list (current-buffer)))))))
 
 ;; copy-region-as-kill no longer sets this-command, because it's confusing
 ;; to get two copies of the text when the user accidentally types M-w and