Subject: bug#56530: 29.0.50; mouse-2 cut selected text when cua-mode is enabled

From: Juri Linkov <[email-masked]>
Date: Fri, 15 Jul 2022 21:53:33 +0300

>> There is already the minor mode: delete-selection-mode
>> that is configured by symbol properties.
>> Supporting a descriptive symbol name would allow to easily
>> configure the desired behavior with just:
>>
>>   (put 'mouse-yank-at-click 'delete-selection 'yank-on-region)
>
> The problem is that you have to `put' on three symbols, which isn't
> optimal.  (My proposed mode does just that.)

The default settings should be suitable for all users,
but modes for groups of settings could be added too.

This patch works well but only like Visuwesh pointed out
when mouse-yank-at-point is set to t.  This is because
mouse-yank-primary has such line:

  (or mouse-yank-at-point (mouse-set-point event))

When delete-selection deletes the region where the mouse is clicked,
mouse-set-point loses track and sets point to a random position,
because the event contains fixed positions, not markers.
I wonder why?

diff --git a/lisp/delsel.el b/lisp/delsel.el
index 5310328e5f..d9e0141d90 100644
--- a/lisp/delsel.el
+++ b/lisp/delsel.el
@@ -39,6 +39,8 @@
 ;;      For commands which do a yank; ensures the region about to be
 ;;      deleted isn't immediately yanked back, which would make the
 ;;      command a no-op.
+;;  `yank-on-region'
+;;      Like `yank' but applied only when clicked on the region.
 ;;  `supersede'
 ;;      Delete the active region and ignore the current command,
 ;;      i.e. the command will just delete the region.  This is for
@@ -176,6 +178,8 @@ delete-selection-helper
      For commands which do a yank; ensures the region about to be
      deleted isn't immediately yanked back, which would make the
      command a no-op.
+ `yank-on-region'
+     Like `yank' but applied only when clicked on the region.
  `supersede'
      Delete the active region and ignore the current command,
      i.e. the command will just delete the region.  This is for
@@ -220,6 +224,11 @@ delete-selection-helper
                ;; If the region was, say, rectangular, make sure we yank
                ;; from the top, to "replace".
                (goto-char pos)))
+            ((eq type 'yank-on-region)
+             (let ((pos (posn-point (event-end last-nonmenu-event))))
+               (when (and (>= pos (region-beginning))
+                          (<= pos (region-end)))
+                 (delete-selection-helper 'yank))))
 	    ((eq type 'supersede)
 	     (let ((empty-region (= (point) (mark))))
 	       (delete-active-region)
@@ -300,6 +309,12 @@ delete-selection-uses-region-p
 (put 'yank-pop 'delete-selection 'yank)
 (put 'yank-from-kill-ring 'delete-selection 'yank)
 (put 'clipboard-yank 'delete-selection 'yank)
+
+(put 'mouse-yank-primary 'delete-selection 'yank-on-region)
+(put 'mouse-yank-secondary 'delete-selection 'yank-on-region)
+(put 'mouse-yank-at-click 'delete-selection 'yank-on-region)
+(put 'menu-bar-select-yank 'delete-selection 'yank-on-region)
+
 (put 'insert-register 'delete-selection t)
 ;; delete-backward-char and delete-forward-char already delete the selection by
 ;; default, but not delete-char.