GNU bug report logs - #26725
patch for mouse.el

Previous Next

Package: emacs;

Reported by: Tak Kunihiro <tkk <at> misasa.okayama-u.ac.jp>

Date: Mon, 1 May 2017 05:44:01 UTC

Severity: wishlist

Tags: patch

Done: Eli Zaretskii <eliz <at> gnu.org>

Bug is archived. No further changes may be made.

To add a comment to this bug, you must first unarchive it, by sending
a message to control AT debbugs.gnu.org, with unarchive 26725 in the body.
You can then email your comments to 26725 AT debbugs.gnu.org in the normal way.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to bug-gnu-emacs <at> gnu.org:
bug#26725; Package emacs. (Mon, 01 May 2017 05:44:02 GMT) Full text and rfc822 format available.

Acknowledgement sent to Tak Kunihiro <tkk <at> misasa.okayama-u.ac.jp>:
New bug report received and forwarded. Copy sent to bug-gnu-emacs <at> gnu.org. (Mon, 01 May 2017 05:44:02 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Tak Kunihiro <tkk <at> misasa.okayama-u.ac.jp>
To: bug-gnu-emacs <at> gnu.org
Cc: tkk <at> misasa.okayama-u.ac.jp
Subject: patch for mouse.el
Date: Mon, 01 May 2017 14:43:08 +0900 (JST)
[Message part 1 (text/plain, inline)]
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.el.patch (text/x-patch, inline)]
--- 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)

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#26725; Package emacs. (Sat, 06 May 2017 22:07:01 GMT) Full text and rfc822 format available.

Message #8 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Tak Kunihiro <tkk <at> misasa.okayama-u.ac.jp>
To: bug-gnu-emacs <at> gnu.org, 26725 <at> debbugs.gnu.org
Cc: tkk <at> misasa.okayama-u.ac.jp
Subject: Re: bug#26725 patch for mouse.el
Date: Sun, 07 May 2017 07:06:21 +0900 (JST)
Is this patch NG?

I think `drag-and-drop text' using mouse gives modern flavor to Emacs,
and idea should be good.

Would you tell me how this patch is NG, if so?




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#26725; Package emacs. (Sat, 06 May 2017 22:07:02 GMT) Full text and rfc822 format available.

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#26725; Package emacs. (Sun, 07 May 2017 17:09:02 GMT) Full text and rfc822 format available.

Message #14 received at 26725 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Tak Kunihiro <tkk <at> misasa.okayama-u.ac.jp>
Cc: 26725 <at> debbugs.gnu.org
Subject: Re: bug#26725: patch for mouse.el
Date: Sun, 07 May 2017 20:08:03 +0300
> Date: Sun, 07 May 2017 07:06:21 +0900 (JST)
> From: Tak Kunihiro <tkk <at> misasa.okayama-u.ac.jp>
> Cc: tkk <at> misasa.okayama-u.ac.jp
> 
> Is this patch NG?
> 
> I think `drag-and-drop text' using mouse gives modern flavor to Emacs,
> and idea should be good.
> 
> Would you tell me how this patch is NG, if so?

Sorry, I didn't yet have time to look into your patch (and hoped
someone else might, meanwhile...)




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#26725; Package emacs. (Sun, 07 May 2017 22:47:02 GMT) Full text and rfc822 format available.

Message #17 received at 26725 <at> debbugs.gnu.org (full text, mbox):

From: Tak Kunihiro <tkk <at> misasa.okayama-u.ac.jp>
To: eliz <at> gnu.org
Cc: tkk <at> misasa.okayama-u.ac.jp, 26725 <at> debbugs.gnu.org
Subject: Re: bug#26725: patch for mouse.el
Date: Mon, 08 May 2017 07:46:02 +0900 (JST)
>> Is this patch NG?
>> 
>> I think `drag-and-drop text' using mouse gives modern flavor to Emacs,
>> and idea should be good.
>> 
>> Would you tell me how this patch is NG, if so?
> 
> Sorry, I didn't yet have time to look into your patch (and hoped
> someone else might, meanwhile...)

I see.  No problem.  Please take you time, and eventually give me
response.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#26725; Package emacs. (Sat, 13 May 2017 17:40:02 GMT) Full text and rfc822 format available.

Message #20 received at 26725 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Tak Kunihiro <tkk <at> misasa.okayama-u.ac.jp>
Cc: 26725 <at> debbugs.gnu.org
Subject: Re: bug#26725: patch for mouse.el
Date: Sat, 13 May 2017 20:38:37 +0300
> Date: Mon, 01 May 2017 14:43:08 +0900 (JST)
> From: Tak Kunihiro <tkk <at> misasa.okayama-u.ac.jp>
> Cc: tkk <at> misasa.okayama-u.ac.jp
> 
> Drag and drop a file is already supported by Emacs.  This patch
> extends drag and drop to region (text).

Thanks.  Some comments below.

> +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
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^
"this moves the entire region of text"

> +(defcustom mouse-drag-and-drop-region nil
> +  "If non-nil, dragging mouse of the region moves text."

"If non-nil, dragging the mouse drags the region, when that exists.

> +(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?

> +(defun mouse-drag-region-pasting (event)

The function's name is confusing.  Why not name it like the defcustom?

> +  "Move text on a region to point where mouse is dragged over to.
                ^^
"in"

> +The transportation of text is also referred as `drag and drop'.
> +When text is dragged over to different buffer, the text is copied
                               ^
"a" is missing here.

> +instead of cut.

"instead of being cur".

>                      This works similar to
> +`mouse-drag-secondary-moving' but expects region on launch and
> +specifies point later, by mouse.

I'd lose this sentence, it doesn't add anything to the doc string.

> +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."

I think this is inappropriate for a doc string.

Please add a NEWS entry and some minimal documentation in the user
manual.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#26725; Package emacs. (Mon, 15 May 2017 04:03:01 GMT) Full text and rfc822 format available.

Message #23 received at 26725 <at> debbugs.gnu.org (full text, mbox):

From: Tak Kunihiro <tkk <at> misasa.okayama-u.ac.jp>
To: eliz <at> gnu.org
Cc: tkk <at> misasa.okayama-u.ac.jp, 26725 <at> debbugs.gnu.org
Subject: Re: bug#26725: patch for mouse.el
Date: Mon, 15 May 2017 13:01:31 +0900 (JST)
[Message part 1 (text/plain, inline)]
Thank you for the comments.  I revised English as suggested.

>> +(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 not necessary anymore.

(equal (mouse-posn-property (event-start start-event) 'face) 'region)
(equal (mouse-posn-property (event-start start-event) 'face) 'secondary-selecton)

>> +(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'.

> Please add a NEWS entry and some minimal documentation in the user
> manual.

I add ChangeLog, NEWS, and Info as shown below.  I think that all
concerns were resolved for now.


# ChangeLog

2017-05-16  Tak Kunihiro  <tkk <at> misasa.okayama-u.ac.jp>

	Support drag and drop region by the mouse (Bug#26725)

	* doc/emacs/frames.texi (Drag and Drop): Document support of drag
    and drop region by the mouse.
	* lisp/mouse.el (mouse-drag-region): Call mouse-drag-and-drop-region
    when start-event is against region.
    (mouse-drag-and-drop-region): Move the region by dragging the mouse.

# NEWS

** Support drag and drop text by the mouse.
You can start drag-and-drop text by customizing 'mouse-drag-and-drop-region'.

# Info

diff --git a/site-lisp/frames.252.texi b/site-lisp/frames.texi
index 1611bd1..da140a6 100755
--- a/site-lisp/frames.252.texi
+++ b/site-lisp/frames.texi
@@ -1046,12 +1046,17 @@ Window Dividers, elisp, The Emacs Lisp Reference Manual}.
 @cindex drag and drop

   In most graphical desktop environments, Emacs has basic support for
-@dfn{drag and drop} operations.  For instance, dropping text onto an
-Emacs frame inserts the text where it is dropped.  Dropping a file
-onto an Emacs frame visits that file.  As a special case, dropping the
-file on a Dired buffer moves or copies the file (according to the
-conventions of the application it came from) into the directory
-displayed in that buffer.
+@dfn{drag and drop} operations.  For instance, dragging region can move
+the entire region of text to point where mouse is dragged over to.
+Dropping text onto an Emacs frame inserts the text where it is dropped.
+Dropping a file onto an Emacs frame visits that file.  As a special
+case, dropping the file on a Dired buffer moves or copies the file
+(according to the conventions of the application it came from) into the
+directory displayed in that buffer.
+
+@vindex mouse-drag-and-drop-region
+  If you prefer to move the entire region of text by mouse, customize
+the variable @code{mouse-drag-and-drop-region}.

 @vindex dnd-open-file-other-window
   Dropping a file normally visits it in the window you drop it on.  If
[mouse.el.patch (text/x-patch, inline)]
diff --git a/mouse.252.el b/mouse.el
index 3336e2b..b8cc92c 100755
--- a/mouse.252.el
+++ b/mouse.el
@@ -688,12 +688,19 @@ Upon exit, point is at the far edge of the newly visible text."
 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 the entire region of text to point where
+mouse is dragged over to."
+  (interactive "e")
+  (if (and mouse-drag-and-drop-region
+           (not (member 'triple (event-modifiers start-event)))
+           (equal (mouse-posn-property (event-start start-event) 'face) 'region))
+      (mouse-drag-and-drop-region 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,76 @@ choose a font."
 		  t (called-interactively-p 'interactive)))))))))
 
 
+;; Drag and drop support.
+(defcustom mouse-drag-and-drop-region nil
+  "If non-nil, dragging the mouse drags the region, when that exists."
+  :type 'boolean
+  :version "26.1"
+  :group 'mouse)
+
+(defun mouse-drag-and-drop-region (event)
+  "Move text in 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 a different buffer, the text is
+copied instead of being cut."
+  (interactive "e")
+  (require 'tooltip)
+  (let ((start (region-beginning))
+        (end (region-end))
+        (point (point))
+        (buffer (current-buffer))
+        (window (selected-window))
+        value-selection
+        face-under-mouse)
+    (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".
+    (setq face-under-mouse (mouse-posn-property (event-end event) 'face))
+    (if (or (equal face-under-mouse 'region)
+            (equal face-under-mouse 'secondary-selecton)
+            buffer-read-only)
+        ;; Do not modify buffer under mouse
+        (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)))
+      ;; Modify buffer under mouse by inserting text
+      (push-mark)
+      (insert value-selection)
+      (when (not (equal (mark) (point))) ; on success
+        (setq deactivate-mark nil)
+        (activate-mark)) ; activate region on new place
+      ;; Take care initial region
+      (if (equal (current-buffer) buffer) ; same buffer
+          (let (deactivate-mark) ; remove text
+            (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)

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#26725; Package emacs. (Mon, 15 May 2017 09:55:01 GMT) Full text and rfc822 format available.

Message #26 received at 26725 <at> debbugs.gnu.org (full text, mbox):

From: Tak Kunihiro <tkk <at> misasa.okayama-u.ac.jp>
To: eliz <at> gnu.org
Cc: Kunihiro Tak <tkk <at> misasa.okayama-u.ac.jp>, 26725 <at> debbugs.gnu.org
Subject: Re: bug#26725: patch for mouse.el
Date: Mon, 15 May 2017 18:53:03 +0900
Let me withdraw the last patch.
I found a problem with following statement.

(equal (mouse-posn-property (event-end event) 'face) 'secondary-selecton)





Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#26725; Package emacs. (Fri, 19 May 2017 02:09:02 GMT) Full text and rfc822 format available.

Message #29 received at 26725 <at> debbugs.gnu.org (full text, mbox):

From: Tak Kunihiro <tkk <at> misasa.okayama-u.ac.jp>
To: eliz <at> gnu.org
Cc: tkk <at> misasa.okayama-u.ac.jp, 26725 <at> debbugs.gnu.org
Subject: Re: bug#26725: patch for mouse.el
Date: Fri, 19 May 2017 11:07:43 +0900 (JST)
[Message part 1 (text/plain, inline)]
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.




# ChangeLog

2017-05-20  Tak Kunihiro  <tkk <at> misasa.okayama-u.ac.jp>

	Support drag and drop region by the mouse (Bug#26725)

	* doc/emacs/frames.texi (Drag and Drop): Document support of drag
    and drop region by the mouse.
	* lisp/mouse.el (mouse-drag-region): Call mouse-drag-and-drop-region
    when start-event is against region.
    (mouse-drag-and-drop-region): Move the region by dragging the mouse.

# NEWS

** Support drag and drop text by the mouse.
You can start drag-and-drop text by customizing 'mouse-drag-and-drop-region'.

# Info

diff --git a/site-lisp/frames.252.texi b/site-lisp/frames.texi
index 1611bd1..da140a6 100755
--- a/site-lisp/frames.252.texi
+++ b/site-lisp/frames.texi
@@ -1046,12 +1046,17 @@ Window Dividers, elisp, The Emacs Lisp Reference Manual}.
 @cindex drag and drop

   In most graphical desktop environments, Emacs has basic support for
-@dfn{drag and drop} operations.  For instance, dropping text onto an
-Emacs frame inserts the text where it is dropped.  Dropping a file
-onto an Emacs frame visits that file.  As a special case, dropping the
-file on a Dired buffer moves or copies the file (according to the
-conventions of the application it came from) into the directory
-displayed in that buffer.
+@dfn{drag and drop} operations.  For instance, dragging region can move
+the entire region of text to point where mouse is dragged over to.
+Dropping text onto an Emacs frame inserts the text where it is dropped.
+Dropping a file onto an Emacs frame visits that file.  As a special
+case, dropping the file on a Dired buffer moves or copies the file
+(according to the conventions of the application it came from) into the
+directory displayed in that buffer.
+
+@vindex mouse-drag-and-drop-region
+  If you prefer to move the entire region of text by mouse, customize
+the variable @code{mouse-drag-and-drop-region}.

 @vindex dnd-open-file-other-window
   Dropping a file normally visits it in the window you drop it on.  If


[mouse.el.patch (text/x-patch, inline)]
diff --git a/mouse.252.el b/mouse.el
index 3336e2b..66142f4 100755
--- a/mouse.252.el
+++ b/mouse.el
@@ -688,12 +688,19 @@ Upon exit, point is at the far edge of the newly visible text."
 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 the variable
+`mouse-drag-and-drop-region' is non-nil, this moves the entire
+region of text to point where mouse is dragged over to."
+  (interactive "e")
+  (if (and mouse-drag-and-drop-region
+           (not (member 'triple (event-modifiers start-event)))
+           (equal (mouse-posn-property (event-start start-event) 'face) 'region))
+      (mouse-drag-and-drop-region 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,81 @@ choose a font."
 		  t (called-interactively-p 'interactive)))))))))
 
 
+;; Drag and drop support.
+(defcustom mouse-drag-and-drop-region nil
+  "If non-nil, dragging the mouse drags the region, when that exists.
+When the modifier key is specified, dropping with the modifier
+key pressed copies the text instead of cuts."
+  :type 'symbol
+  :version "26.1"
+  :group 'mouse)
+
+(defun mouse-drag-and-drop-region (event)
+  "Move text in 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 a different buffer, the text is
+copied instead of being cut."
+  (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 under mouse when "event was click",
+    ;;                                       "drag negligible", or
+    ;;                                       "drag to read-only".
+    (if (or (equal (mouse-posn-property (event-end event) 'face) 'region) ; "event was click"
+            (member 'secondary-selection ; "drag negligible"
+                    (mapcar (lambda (xxx) (overlay-get xxx 'face))
+                            (overlays-at (posn-point (event-end event)))))
+            buffer-read-only)
+        ;; Do not modify buffer under mouse
+        (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)))
+      ;; Modify buffer under mouse by inserting text
+      (push-mark)
+      (insert value-selection)
+      (when (not (equal (mark) (point))) ; on success insert
+        (setq deactivate-mark nil)
+        (activate-mark)) ; have region on destination
+      ;; Take care initial region on source
+      (if (equal (current-buffer) buffer) ; when same buffer
+          (let (deactivate-mark) ; remove text
+            (unless (member mouse-drag-and-drop-region (event-modifiers event))
+              (kill-region (overlay-start mouse-secondary-overlay)
+                           (overlay-end mouse-secondary-overlay))))
+        (let ((window1 (selected-window))) ; when beyond buffer
+          (select-window window)
+          (goto-char point) ; restore point on source window
+          (activate-mark) ; restore region
+          (select-window window1))))
+    (delete-overlay mouse-secondary-overlay)))
+
+
 ;;; Bindings for mouse commands.
 
 (global-set-key [down-mouse-1]	'mouse-drag-region)

Reply sent to Eli Zaretskii <eliz <at> gnu.org>:
You have taken responsibility. (Sat, 27 May 2017 12:01:02 GMT) Full text and rfc822 format available.

Notification sent to Tak Kunihiro <tkk <at> misasa.okayama-u.ac.jp>:
bug acknowledged by developer. (Sat, 27 May 2017 12:01:02 GMT) Full text and rfc822 format available.

Message #34 received at 26725-done <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Tak Kunihiro <tkk <at> misasa.okayama-u.ac.jp>
Cc: 26725-done <at> debbugs.gnu.org
Subject: Re: bug#26725: patch for mouse.el
Date: Sat, 27 May 2017 15:00:39 +0300
> Date: Fri, 19 May 2017 11:07:43 +0900 (JST)
> Cc: 26725 <at> debbugs.gnu.org, tkk <at> misasa.okayama-u.ac.jp,
>  tkk <at> misasa.okayama-u.ac.jp
> From: Tak Kunihiro <tkk <at> misasa.okayama-u.ac.jp>
> 
> 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.




bug archived. Request was from Debbugs Internal Request <help-debbugs <at> gnu.org> to internal_control <at> debbugs.gnu.org. (Sun, 25 Jun 2017 11:24:04 GMT) Full text and rfc822 format available.

This bug report was last modified 8 years and 54 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.