]> git.eshelyaron.com Git - emacs.git/commitdiff
(mouse-save-then-kill-delete-region):
authorRichard M. Stallman <rms@gnu.org>
Wed, 24 Nov 1993 06:35:03 +0000 (06:35 +0000)
committerRichard M. Stallman <rms@gnu.org>
Wed, 24 Nov 1993 06:35:03 +0000 (06:35 +0000)
Call undo-boundary at the beginning and at the end.

(mouse-start-end): Use MODE mod 3.
(mouse-save-then-kill): Test mouse-selection-click-count mod 3.
(mouse-drag-secondary, mouse-secondary-save-then-kill): Likewise.

(mouse-kill-secondary): Do the kill in proper buffer.
Give error if in the wrong buffer.
(mouse-secondary-save-then-kill): Give error if click is not in
the buffer already used for secondary selection.
Don't switch windows; always temporarily switch buffers.

lisp/mouse.el

index 302e2cf18bc2e3e4df5185a24d9d2a16ec2d6c6b..7c6648df3028db767f6c232b2390e49dbb461bc9 100644 (file)
@@ -281,6 +281,7 @@ If DIR is positive skip forward; if negative, skip backward."
       (let ((temp start))
         (setq start end
               end temp)))
+  (setq mode (mod mode 3))
   (cond ((= mode 0)
         (list start end))
         ((and (= mode 1)
@@ -378,6 +379,9 @@ This does not delete the region; it acts like \\[kill-ring-save]."
 (defvar mouse-save-then-kill-posn nil)
 
 (defun mouse-save-then-kill-delete-region (beg end)
+  ;; We must make our own undo boundaries
+  ;; because they happen automatically only for the current buffer.
+  (undo-boundary)
   (if (or (= beg end) (eq buffer-undo-list t))
       ;; If we have no undo list in this buffer,
       ;; just delete.
@@ -393,6 +397,8 @@ This does not delete the region; it acts like \\[kill-ring-save]."
       ;; Now delete the rest of the specified region,
       ;; but don't record it.
       (setq buffer-undo-list t)
+      (if (/= (length (car kill-ring)) (- (max end beg) (min end beg)))
+         (error "Lossage in mouse-save-then-kill-delete-region"))
       (delete-region beg end))
     (let ((tail buffer-undo-list))
       ;; Search back in buffer-undo-list for the string
@@ -401,7 +407,8 @@ This does not delete the region; it acts like \\[kill-ring-save]."
        (setq tail (cdr tail)))
       ;; Replace it with an entry for the entire deleted text.
       (and tail
-          (setcar tail (cons (car kill-ring) (min beg end)))))))
+          (setcar tail (cons (car kill-ring) (min beg end))))))
+  (undo-boundary))
 
 (defun mouse-save-then-kill (click)
   "Save text to point in kill ring; the second time, kill the text.
@@ -419,7 +426,7 @@ If you do this twice in the same position, the selection is killed."
        ;; Don't let a subsequent kill command append to this one:
        ;; prevent setting this-command to kill-region.
        (this-command this-command))
-    (if (> mouse-selection-click-count 0)
+    (if (> (mod mouse-selection-click-count 3) 0)
        (if (not (and (eq last-command 'mouse-save-then-kill)
                      (equal click-posn
                             (car (cdr-safe (cdr-safe mouse-save-then-kill-posn))))))
@@ -490,7 +497,7 @@ If you do this twice in the same position, the selection is killed."
 (global-set-key [M-drag-mouse-1] 'mouse-set-secondary)
 (global-set-key [M-down-mouse-1] 'mouse-drag-secondary)
 (global-set-key [M-mouse-3] 'mouse-secondary-save-then-kill)
-(global-set-key [M-mouse-2] 'mouse-kill-secondary)
+(global-set-key [M-mouse-2] 'mouse-yank-secondary)
 
 ;; An overlay which records the current secondary selection
 ;; or else is deleted when there is no secondary selection.
@@ -557,7 +564,7 @@ This must be bound to a button-down mouse event."
          (setq mouse-secondary-overlay
                (make-overlay (point) (point))))
       (overlay-put mouse-secondary-overlay 'face 'secondary-selection)
-      (if (> click-count 0)
+      (if (> (mod click-count 3) 0)
          ;; Double or triple press: make an initial selection
          ;; of one word or line.
          (let ((range (mouse-start-end start-point start-point click-count)))
@@ -629,19 +636,45 @@ This must be bound to a button-down mouse event."
            (if (marker-position mouse-secondary-start)
                (save-window-excursion
                  (delete-overlay mouse-secondary-overlay)
+                 (x-set-selection 'SECONDARY nil)
                  (select-window start-window)
                  (save-excursion
                    (goto-char mouse-secondary-start)
                    (sit-for 1)))
-             (kill-ring-save (overlay-start mouse-secondary-overlay)
-                             (overlay-end mouse-secondary-overlay))))))))
+             (x-set-selection
+              'SECONDARY
+              (buffer-substring (overlay-start mouse-secondary-overlay)
+                                (overlay-end mouse-secondary-overlay)))))))))
 
-(defun mouse-kill-secondary ()
-  "Kill the text in the secondary selection."
-  (interactive "*")
-  (kill-region (overlay-start mouse-secondary-overlay)
-              (overlay-end mouse-secondary-overlay))
+(defun mouse-yank-secondary (click)
+  "Insert the last stretch of killed text at the position clicked on.
+Prefix arguments are interpreted as with \\[yank]."
+  (interactive "e")
+  (save-excursion
+    (set-buffer (window-buffer (posn-window (event-start click))))
+    (goto-char (posn-point (event-start click)))
+    (insert (x-get-selection 'SECONDARY))))
+
+(defun mouse-kill-secondary (click)
+  "Kill the text in the secondary selection.
+This is intended more as a keyboard command than as a mouse command
+but it can work as either one.
+
+The current buffer (in case of keyboard use), or the buffer clicked on,
+must be the one that the secondary selection is in.  This requirement
+is to prevent accidents."
+  (interactive "e")
+  (or (eq (overlay-buffer mouse-secondary-overlay)
+         (if (listp click)
+             (window-buffer (posn-window (event-start click)))
+           (current-buffer)))
+      (error "Select or click on the buffer where the secondary selection is"))
+  (save-excursion
+    (set-buffer (overlay-buffer mouse-secondary-overlay))
+    (kill-region (overlay-start mouse-secondary-overlay)
+                (overlay-end mouse-secondary-overlay)))
   (delete-overlay mouse-secondary-overlay)
+  (x-set-selection 'SECONDARY nil)
   (setq mouse-secondary-overlay nil))
 
 (defun mouse-secondary-save-then-kill (click)
@@ -661,88 +694,99 @@ If you do this twice in the same position, the selection is killed."
        ;; Don't let a subsequent kill command append to this one:
        ;; prevent setting this-command to kill-region.
        (this-command this-command))
-    (if (> mouse-selection-click-count 0)
-       (if (not (and (eq last-command 'mouse-secondary-save-then-kill)
-                     (equal click-posn
-                            (car (cdr-safe (cdr-safe mouse-save-then-kill-posn))))))
-           ;; Find both ends of the object selected by this click.
-           (let* ((range
-                   (mouse-start-end click-posn click-posn
-                                    mouse-selection-click-count)))
-             ;; Move whichever end is closer to the click.
-             ;; That's what xterm does, and it seems reasonable.
-             (if (< (abs (- click-posn (overlay-start mouse-secondary-overlay)))
-                    (abs (- click-posn (overlay-end mouse-secondary-overlay))))
-                 (move-overlay mouse-secondary-overlay (car range)
-                               (overlay-end mouse-secondary-overlay))
+    (or (eq (window-buffer (posn-window posn))
+           (or (and mouse-secondary-overlay
+                    (overlay-buffer mouse-secondary-overlay))
+               (if mouse-secondary-start
+                   (marker-buffer mouse-secondary-start))))
+       (error "Wrong buffer"))
+    (save-excursion
+      (set-buffer (window-buffer (posn-window posn)))
+      (if (> (mod mouse-selection-click-count 3) 0)
+         (if (not (and (eq last-command 'mouse-secondary-save-then-kill)
+                       (equal click-posn
+                              (car (cdr-safe (cdr-safe mouse-save-then-kill-posn))))))
+             ;; Find both ends of the object selected by this click.
+             (let* ((range
+                     (mouse-start-end click-posn click-posn
+                                      mouse-selection-click-count)))
+               ;; Move whichever end is closer to the click.
+               ;; That's what xterm does, and it seems reasonable.
+               (if (< (abs (- click-posn (overlay-start mouse-secondary-overlay)))
+                      (abs (- click-posn (overlay-end mouse-secondary-overlay))))
+                   (move-overlay mouse-secondary-overlay (car range)
+                                 (overlay-end mouse-secondary-overlay))
                  (move-overlay mouse-secondary-overlay
                                (overlay-start mouse-secondary-overlay)
                                (nth 1 range)))
-             ;; We have already put the old region in the kill ring.
-             ;; Replace it with the extended region.
-             ;; (It would be annoying to make a separate entry.)
-             (setcar kill-ring (buffer-substring
-                                (overlay-start mouse-secondary-overlay)
-                                (overlay-end mouse-secondary-overlay)))
-             (if interprogram-cut-function
-                 (funcall interprogram-cut-function (car kill-ring)))
-             ;; Arrange for a repeated mouse-3 to kill this region.
-             (setq mouse-save-then-kill-posn
-                   (list (car kill-ring) (point) click-posn)))
-         ;; If we click this button again without moving it,
-         ;; that time kill.
-         (progn
-           (mouse-save-then-kill-delete-region
-            (overlay-start mouse-secondary-overlay)
-            (overlay-end mouse-secondary-overlay))
-           (setq mouse-save-then-kill-posn nil)
-           (setq mouse-selection-click-count 0)
-           (delete-overlay mouse-secondary-overlay)))
-      (if (and (eq last-command 'mouse-secondary-save-then-kill)
-              mouse-save-then-kill-posn
-              (eq (car mouse-save-then-kill-posn) (car kill-ring))
-              (equal (cdr mouse-save-then-kill-posn) (list (point) click-posn)))
-         ;; If this is the second time we've called
-         ;; mouse-secondary-save-then-kill, delete the text from the buffer.
-         (progn
-           (mouse-save-then-kill-delete-region
-            (overlay-start mouse-secondary-overlay)
-            (overlay-end mouse-secondary-overlay))
-           (setq mouse-save-then-kill-posn nil)
-           (delete-overlay mouse-secondary-overlay))
-       (if (overlay-start mouse-secondary-overlay)
-           ;; We have a selection, so adjust it.
+               ;; We have already put the old region in the kill ring.
+               ;; Replace it with the extended region.
+               ;; (It would be annoying to make a separate entry.)
+               (setcar kill-ring (buffer-substring
+                                  (overlay-start mouse-secondary-overlay)
+                                  (overlay-end mouse-secondary-overlay)))
+               (if interprogram-cut-function
+                   (funcall interprogram-cut-function (car kill-ring)))
+               ;; Arrange for a repeated mouse-3 to kill this region.
+               (setq mouse-save-then-kill-posn
+                     (list (car kill-ring) (point) click-posn)))
+           ;; If we click this button again without moving it,
+           ;; that time kill.
            (progn
-             (select-window (posn-window posn))
-             (if (numberp click-posn)
-                 (progn
-                   ;; Move whichever end of the region is closer to the click.
-                   ;; That is what xterm does, and it seems reasonable.
-                   (if (< (abs (- click-posn (overlay-start mouse-secondary-overlay)))
-                          (abs (- click-posn (overlay-end mouse-secondary-overlay))))
-                       (move-overlay mouse-secondary-overlay click-posn
-                                     (overlay-end mouse-secondary-overlay))
+             (mouse-save-then-kill-delete-region
+              (overlay-start mouse-secondary-overlay)
+              (overlay-end mouse-secondary-overlay))
+             (setq mouse-save-then-kill-posn nil)
+             (setq mouse-selection-click-count 0)
+             (delete-overlay mouse-secondary-overlay)))
+       (if (and (eq last-command 'mouse-secondary-save-then-kill)
+                mouse-save-then-kill-posn
+                (eq (car mouse-save-then-kill-posn) (car kill-ring))
+                (equal (cdr mouse-save-then-kill-posn) (list (point) click-posn)))
+           ;; If this is the second time we've called
+           ;; mouse-secondary-save-then-kill, delete the text from the buffer.
+           (progn
+             (mouse-save-then-kill-delete-region
+              (overlay-start mouse-secondary-overlay)
+              (overlay-end mouse-secondary-overlay))
+             (setq mouse-save-then-kill-posn nil)
+             (delete-overlay mouse-secondary-overlay))
+         (if (overlay-start mouse-secondary-overlay)
+             ;; We have a selection, so adjust it.
+             (progn
+               (if (numberp click-posn)
+                   (progn
+                     ;; Move whichever end of the region is closer to the click.
+                     ;; That is what xterm does, and it seems reasonable.
+                     (if (< (abs (- click-posn (overlay-start mouse-secondary-overlay)))
+                            (abs (- click-posn (overlay-end mouse-secondary-overlay))))
+                         (move-overlay mouse-secondary-overlay click-posn
+                                       (overlay-end mouse-secondary-overlay))
                        (move-overlay mouse-secondary-overlay
                                      (overlay-start mouse-secondary-overlay)
                                      click-posn))
-                   (setq deactivate-mark nil)))
-             (setcar kill-ring (buffer-substring
-                                (overlay-start mouse-secondary-overlay)
-                                (overlay-end mouse-secondary-overlay)))
-             (if interprogram-cut-function
-                 (funcall interprogram-cut-function (car kill-ring))))
-         (if mouse-secondary-start
-             ;; All we have is one end of a selection,
-             ;; so put the other end here.
-             (let ((start (+ 0 mouse-secondary-start)))
-               (set-buffer (window-buffer (posn-window (event-start click))))
-               (kill-ring-save start click-posn)
-               (if mouse-secondary-overlay
-                   (move-overlay mouse-secondary-overlay start click-posn)
-                 (setq mouse-secondary-overlay (make-overlay start click-posn)))
-               (overlay-put mouse-secondary-overlay 'face 'secondary-selection))))
-       (setq mouse-save-then-kill-posn
-             (list (car kill-ring) (point) click-posn))))))
+                     (setq deactivate-mark nil)))
+               (setcar kill-ring (buffer-substring
+                                  (overlay-start mouse-secondary-overlay)
+                                  (overlay-end mouse-secondary-overlay)))
+               (if interprogram-cut-function
+                   (funcall interprogram-cut-function (car kill-ring))))
+           (if mouse-secondary-start
+               ;; All we have is one end of a selection,
+               ;; so put the other end here.
+               (let ((start (+ 0 mouse-secondary-start)))
+                 (kill-ring-save start click-posn)
+                 (if mouse-secondary-overlay
+                     (move-overlay mouse-secondary-overlay start click-posn)
+                   (setq mouse-secondary-overlay (make-overlay start click-posn)))
+                 (overlay-put mouse-secondary-overlay 'face 'secondary-selection))))
+         (setq mouse-save-then-kill-posn
+               (list (car kill-ring) (point) click-posn))))
+      (x-set-selection 'SECONDARY
+                      (if (overlay-buffer mouse-secondary-overlay)
+                          (buffer-substring
+                           (overlay-start mouse-secondary-overlay)
+                           (overlay-end mouse-secondary-overlay)))))))
 \f
 (defun mouse-buffer-menu (event)
   "Pop up a menu of buffers for selection with the mouse.