Subject: bug#26725: closed (Re: bug#26725: patch for mouse.el)

From: [email-masked] (GNU bug Tracking System)
Date: Sat, 27 May 2017 12:01:02 +0000

Your bug report

#26725: patch for mouse.el

which was filed against the emacs package, has been closed.

The explanation is attached below, along with your original report.
If you require more details, please reply to [email-masked].

-- 
26725: http://debbugs.gnu.org/cgi/bugreport.cgi?bug=26725
GNU Bug Tracking System
Contact [email-masked] with problems

Subject: Re: bug#26725: patch for mouse.el
From: Eli Zaretskii <[email-masked]>
To: Tak Kunihiro <[email-masked]>
Cc: [email-masked]
Date: Sat, 27 May 2017 15:00:39 +0300
List-Id: <debbugs-submit.debbugs.gnu.org>

> Date: Fri, 19 May 2017 11:07:43 +0900 (JST)
> Cc: [email-masked], [email-masked],
>  [email-masked]
> From: Tak Kunihiro <[email-masked]>
> 
> Thank you for the comments.
> 
> * English
> 
> I revised English as suggested.
> 
> 
> * Algorithm in detection of clicking region
> 
> >> +(defun mouse-on-region-p (position &optional start end)
> >> +  "Return if POSITION is in between START and END in the current buffer.
> >> +When START and END are nil but there is active region, those of
> >> +active region is fed."
> >> +  (when (region-active-p)
> >> +    (setq start (or start (region-beginning)))
> >> +    (setq end (or end (region-end))))
> >> +  (let ((point (posn-point position)))
> >> +    (and
> >> +     (numberp start)
> >> +     (numberp end)
> >> +     (numberp point)
> >> +     (<= start point)
> >> +     (<= point end))))
> >
> > This algorithm will fail with bidirectional text, where buffer
> > positions don't increase monotonically with screen coordinates.  How
> > about testing the face of the character under mouse instead?
> 
> I revised the code using following statements.  Accordingly,
> `mouse-on-region-p' is deleted.
> 
> (equal (mouse-posn-property (event-end event) 'face) 'region)
> (member 'secondary-selection(mapcar (lambda (xxx) (overlay-get xxx 'face))
>                             (overlays-at (posn-point (event-end event)))))
> 
> 
> * Name of function
> 
> >> +(defun mouse-drag-region-pasting (event)
> >
> > The function's name is confusing.  Why not name it like the defcustom?
> 
> I changed the name from `mouse-drag-region-pasting' to
> `mouse-drag-and-drop-region'.  As a consequence, variable and function
> have the same name.  I suppose it is OK.
> 
> 
> * NEWS, ChangeLog, and Info
> 
> > Please add a NEWS entry and some minimal documentation in the user
> > manual.
> 
> I add ChangeLog, NEWS, and Info as shown below.
> 
> 
> * Copy on Drag and Drop with meta key pressed
> 
> I found that sometimes I want to copy on drop (instead of cut) even
> when source buffer and destination buffer are the same.
> 
> I added a logic to let me do so.  When modifier key is pressed on
> drop, the function does not delete the original region.
> 
> The modifier key is specified by the variable
> `mouse-drag-and-drop-region' that is used as flag.  I did not create a
> new variable.

Thanks, pushed to master.

Subject: patch for mouse.el
From: Tak Kunihiro <[email-masked]>
To: [email-masked]
Cc: [email-masked]
Date: Mon, 01 May 2017 14:43:08 +0900 (JST)
List-Id: <debbugs-submit.debbugs.gnu.org>

Drag and drop a file is already supported by Emacs.  This patch
extends drag and drop to region (text).

In other word, this patch lets you `cut and paste' in a buffer only
using mouse.  When destination is other windows, drag and drop a
region will be `copy and paste'.
--- mouse.252.el	2017-05-01 13:45:39.735936700 +0900
+++ mouse.el	2017-05-01 13:59:11.102725500 +0900
@@ -688,12 +688,19 @@
 Highlight the drag area as you move the mouse.
 This must be bound to a button-down mouse event.
 In Transient Mark mode, the highlighting remains as long as the mark
-remains active.  Otherwise, it remains until the next input event."
-  (interactive "e")
-  ;; Give temporary modes such as isearch a chance to turn off.
-  (run-hooks 'mouse-leave-buffer-hook)
-  (mouse-drag-track start-event))
+remains active.  Otherwise, it remains until the next input event.
 
+When the region already exists and `mouse-drag-and-drop-region'
+is non-nil, this moves text on a region to point where mouse is
+dragged over to."
+  (interactive "e")
+  (if (and mouse-drag-and-drop-region
+           (not (member 'triple (event-modifiers start-event)))
+           (mouse-on-region-p (event-start start-event)))
+      (mouse-drag-region-pasting start-event)
+    ;; Give temporary modes such as isearch a chance to turn off.
+    (run-hooks 'mouse-leave-buffer-hook)
+    (mouse-drag-track start-event)))
 
 (defun mouse-posn-property (pos property)
   "Look for a property at click position.
@@ -1911,6 +1918,94 @@
 		  t (called-interactively-p 'interactive)))))))))
 
 
+;; Drag and drop support.
+(defcustom mouse-drag-and-drop-region nil
+  "If non-nil, dragging mouse of the region moves text."
+  :type 'boolean
+  :version "26.1"
+  :group 'mouse)
+
+(defun mouse-on-region-p (position &optional start end)
+  "Return if POSITION is in between START and END in the current buffer.
+When START and END are nil but there is active region, those of
+active region is fed."
+  (when (region-active-p)
+    (setq start (or start (region-beginning)))
+    (setq end (or end (region-end))))
+  (let ((point (posn-point position)))
+    (and
+     (numberp start)
+     (numberp end)
+     (numberp point)
+     (<= start point)
+     (<= point end))))
+
+(defun mouse-drag-region-pasting (event)
+  "Move text on a region to point where mouse is dragged over to.
+The transportation of text is also referred as `drag and drop'.
+When text is dragged over to different buffer, the text is copied
+instead of cut.  This works similar to
+`mouse-drag-secondary-moving' but expects region on launch and
+specifies point later, by mouse.
+
+To try this function, evaluate the following line.
+	(global-set-key [down-mouse-3] \\='mouse-drag-region-pasting)
+Then have a region and grab-and-drag it by mouse to point to move
+to."
+  (interactive "e")
+  (require 'tooltip)
+  (let ((start (region-beginning))
+        (end (region-end))
+        (point (point))
+        (buffer (current-buffer))
+        (window (selected-window))
+        value-selection)
+    (track-mouse
+      ;; when event was click instead of drag, skip loop
+      (while (progn
+               (setq event (read-event))
+               (mouse-movement-p event))
+        (unless value-selection ; initialization
+          (delete-overlay mouse-secondary-overlay)
+          (setq value-selection (buffer-substring start end))
+          (move-overlay mouse-secondary-overlay start end)) ; (deactivate-mark)
+        (ignore-errors (deactivate-mark) ; care existing region in other window
+                       (mouse-set-point event)
+                       (tooltip-show value-selection)))
+      (tooltip-hide))
+    ;; Do not modify buffer when "event was click",
+    ;; "drag negligible", or "drag to read-only".
+    (if (or (mouse-on-region-p (event-end event) start end)
+            buffer-read-only)
+        (cond
+         ;; drag negligible or drag to read-only, restore region
+         (value-selection
+          (select-window window) ; case miss drag to other window
+          (goto-char point)
+          (setq deactivate-mark nil)
+          (activate-mark))
+         ;; event was click
+         (t
+          (deactivate-mark)
+          (mouse-set-point event)))
+      ;; insert text
+      (push-mark)
+      (insert value-selection) ; revise buffer
+      (when (not (equal (mark) (point))) ; on success
+        (setq deactivate-mark nil)
+        (activate-mark)) ; activate region on new place
+      ;; take out initial region
+      (if (equal (current-buffer) buffer) ; same buffer
+          (let (deactivate-mark)
+            (kill-region (overlay-start mouse-secondary-overlay)
+                         (overlay-end mouse-secondary-overlay)))
+        (let ((window1 (selected-window))) ; beyond buffer
+          (select-window window)
+          (goto-char point) ; restore point to where it was
+          (select-window window1))))
+    (delete-overlay mouse-secondary-overlay)))
+
+
 ;;; Bindings for mouse commands.
 
 (global-set-key [down-mouse-1]	'mouse-drag-region)