From: Tak Kunihiro <tkk@misasa.okayama-u.ac.jp>
To: rudalics@gmx.at
Cc: eliz@gnu.org, tak.kunihiro@gmail.com, agrambot@gmail.com,
emacs-devel@gnu.org
Subject: Re: mouse-drag-and-drop-region
Date: Mon, 27 Nov 2017 22:11:26 +0900 (JST) [thread overview]
Message-ID: <20171127.221126.1551780406743300719.tkk@misasa.okayama-u.ac.jp> (raw)
In-Reply-To: <5A17E03C.4000304@gmx.at>
I re-revised mouse-drag-and-drop-region. I'm sending replay to
https://lists.gnu.org/archive/html/emacs-devel/2017-11/msg00589.html,
ChangeLog, and patch.
* ChangeLog
2017-11-27 Tak Kunihiro <tkk@misasa.okayama-u.ac.jp>
Improve comments and have three new options
* lisp/mouse.el (mouse-drag-and-drop-region): Make usage of tooltip option. Have option to make dragging cut among buffers.
(mouse-drag-and-drop-region-cut-when-buffers-differ): New variable. If non-nil, text is cut instead of copied when dragged among buffers.
(mouse-drag-and-drop-region-show-tooltip): New variable. If non-nil, text is shown by tooltip in a graphic display.
(mouse-drag-and-drop-region-face): New variable for face. The face is used to highlight the original text.
* Replay
> instead of perusing the secondary overlay, you don't use your own
> overlay to indicate start and end of the text you cut or copy. When
> done with the operation or when an error occurs during dragging, you
> simply remove that overlay. In addition, you can define a face the
> user can customize in order to highlight that overlay.
OK. That is a good idea. I got rid of usage of secondary-overlay. I
define a new variable mouse-drag-and-drop-region-face.
>> How to show insert point?
>
> I think that by default the insert point should be shown by the
> mouse cursor alone. Optionally, I see no problem showing the normal
> cursor just as `mouse-drag-region' does, maybe with some
> customizable cursor type (I think "bar" would give a better feeling
> than "box").
OK. Only set point by mouse-set-point when
mouse-drag-and-drop-region-show-tooltip is non-nil with changing
cursor type. I also changed the default of
mouse-drag-and-drop-region-show-tooltip to nil to be more stable
against accident during dragging.
> More precisely, you should wrap 'track-mouse' and whatever you do
> after it terminates in a 'condition-case' form and in the error part
> restore everything to the saved values. Like so:
>
> (... ; save the state here
> (condition-case nil
> (progn
> (track-mouse
> )
> )
> (error ... ; restore the state here
> )))
>
> If you have any problems coding that, please ask.
Even track-mouse is sandwiched by condition-case, I cannot catch a
error typing during dragging. However, as inferred already, when
mouse-drag-and-drop-region-show-tooltip is nil, it is more stable even
typing key during dragging.
* Patch
diff --git a/lisp/mouse.el b/lisp/mouse.el
old mode 100644
new mode 100755
index 17d1732..b81d56e
--- a/lisp/mouse.el
+++ b/lisp/mouse.el
@@ -2361,6 +2361,29 @@ text is copied instead of being cut."
:version "26.1"
:group 'mouse)
+(defcustom mouse-drag-and-drop-region-cut-when-buffers-differ nil
+ "If non-nil, cut text also when source and destination buffers differ.
+If this option is nil, `mouse-drag-and-drop-region' will leave
+the text in the source buffer alone when dropping it in a
+different buffer. If this is non-nil, it will cut the text just
+as it does when dropping text in the source buffer."
+ :type 'boolean
+ :version "26.1"
+ :group 'mouse)
+
+(defcustom mouse-drag-and-drop-region-show-tooltip nil
+ "If non-nil, text is shown by a tooltip in a graphic display.
+If this option is non-nil, point is set to where the mouse cursor
+is during dragging and the original text is highlighted by face
+`mouse-drag-and-drop-region-face'."
+ :type 'boolean
+ :version "26.1"
+ :group 'mouse)
+
+(defvar mouse-drag-and-drop-region-face 'region
+ "Face to highlight the original text during dragging.
+See also `mouse-drag-and-drop-region-show-tooltip'.")
+
(defun mouse-drag-and-drop-region (event)
"Move text in the region to point where mouse is dragged to.
The transportation of text is also referred as `drag and drop'.
@@ -2369,66 +2392,171 @@ modifier key was pressed when dropping, and the value of the
variable `mouse-drag-and-drop-region' is that modifier, 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)
+ (let* ((mouse-drag-and-drop-region-show-tooltip
+ (and mouse-drag-and-drop-region-show-tooltip
+ (display-multi-frame-p)
+ (require 'tooltip)))
+ (start (region-beginning))
+ (end (region-end))
+ (point (point))
+ (buffer (current-buffer))
+ (window (selected-window))
+ (cursor-type cursor-type)
+ (text-from-read-only buffer-read-only)
+ (mouse-drag-and-drop-overlay
+ (make-overlay start end))
+ point-to-paste
+ point-to-paste-read-only
+ window-to-paste
+ no-modifier-on-drop
+ drag-but-negligible
+ clicked
+ value-selection) ; This remains nil when event was "click".
+
+ ;; FIXME: Handle error such as hitting C-g while dragging. See
+ ;; https://lists.gnu.org/archive/html/emacs-devel/2017-11/msg00486.html
(track-mouse
- ;; When event was click instead of drag, skip loop
+ ;; When event was "click" instead of "drag", skip loop.
(while (progn
(setq event (read-event))
(or (mouse-movement-p event)
;; Handle `mouse-autoselect-window'.
(eq (car-safe event) 'select-window)))
- (unless value-selection ; initialization
- (delete-overlay mouse-secondary-overlay)
+ ;; Obtain the dragged text in region. When the loop was
+ ;; skipped, value-selection remains nil.
+ (unless value-selection
(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) ; In case miss drag to other window
- (goto-char point)
+
+ ;; Check if selected text is read-only.
+ (dolist (index (number-sequence start end))
+ ;; (add-text-properties (region-beginning) (region-end) '(read-only t))
+ (setq text-from-read-only (or text-from-read-only
+ (get-text-property index 'read-only)))))
+ (ignore-errors
+ (setq window-to-paste (posn-window (event-end event)))
+ (setq point-to-paste (posn-point (event-end event)))
+
+ ;; Check if point under mouse is read-only.
+ (save-window-excursion
+ (select-window window-to-paste)
+ ;; (add-text-properties (region-beginning) (region-end) '(read-only t))
+ (setq point-to-paste-read-only
+ (or buffer-read-only
+ (get-text-property point-to-paste 'read-only))))
+
+ ;; Check if "drag but negligible". Operation "drag but
+ ;; negligible" is defined as drag-and-drop the text to
+ ;; the original region. When modifier is pressed, the
+ ;; text will be inserted to inside of the original
+ ;; region.
+ (setq drag-but-negligible
+ (member mouse-drag-and-drop-region-face
+ (mapcar (lambda (xxx) (overlay-get xxx 'face))
+ (overlays-at point-to-paste))))
+
+ ;; Show tooltip.
+ (when mouse-drag-and-drop-region-show-tooltip
+ (overlay-put mouse-drag-and-drop-overlay
+ 'face mouse-drag-and-drop-region-face)
+ (deactivate-mark) ; Maintain region in other window.
+ (mouse-set-point event)
+ (setq cursor-type (if (or point-to-paste-read-only
+ drag-but-negligible)
+ 'hollow
+ 'bar))
+ (if (and (not drag-but-negligible)
+ (not point-to-paste-read-only))
+ (tooltip-show value-selection)
+ (tooltip-hide)))))
+ ;; Hide a tooltip.
+ (when mouse-drag-and-drop-region-show-tooltip (tooltip-hide)))
+
+
+ ;; Check if modifier was pressed on drop.
+ (setq no-modifier-on-drop
+ (not (member mouse-drag-and-drop-region (event-modifiers event))))
+
+ ;; Check if event was "click".
+ ;; (setq clicked (equal (mouse-posn-property (event-end event) 'face) 'region))
+ (setq clicked (not value-selection))
+
+ ;; Do not modify any buffers when event is "click",
+ ;; "drag but negligible", or "drag to read-only".
+ (let* ((mouse-drag-and-drop-region-cut-when-buffers-differ
+ (if no-modifier-on-drop
+ mouse-drag-and-drop-region-cut-when-buffers-differ
+ (not mouse-drag-and-drop-region-cut-when-buffers-differ)))
+ (wanna-paste-to-same-buffer (equal (window-buffer window-to-paste) buffer))
+ (wanna-cut-on-same-buffer (and wanna-paste-to-same-buffer
+ no-modifier-on-drop))
+ (wanna-cut-on-other-buffer (and (not wanna-paste-to-same-buffer)
+ mouse-drag-and-drop-region-cut-when-buffers-differ))
+ (cannot-paste (or point-to-paste-read-only
+ (when (or wanna-cut-on-same-buffer
+ wanna-cut-on-other-buffer)
+ text-from-read-only))))
+
+ (cond
+ ;; Move point within region.
+ (clicked
+ (deactivate-mark)
+ (mouse-set-point event))
+ ;; Undo operation. Set back the original text as region.
+ ((or (and drag-but-negligible
+ no-modifier-on-drop)
+ cannot-paste)
+ ;; Inform user either source or destination buffer cannot be modified.
+ (when (and (not drag-but-negligible)
+ cannot-paste)
+ (message "Buffer is read-only"))
+
+ ;; Select source window back and restore region.
+ ;; (set-window-point window point)
+ (select-window window)
+ (goto-char point)
+ (setq deactivate-mark nil)
+ (activate-mark))
+ ;; Modify buffers.
+ (t
+ ;; * DESTINATION BUFFER::
+ ;; Insert the text to destination buffer under mouse.
+ (select-window window-to-paste)
+ (goto-char point-to-paste)
+ (push-mark)
+ (insert value-selection)
+ ;; On success, set the text as region on destination buffer.
+ (when (not (equal (mark) (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 of 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)))
+
+ ;; * SOURCE BUFFER::
+ ;; Set back the original text as region or delete the original
+ ;; text, on source buffer.
+ (if wanna-paste-to-same-buffer
+ ;; When source buffer and destination buffer are the same,
+ ;; remove the original text.
+ (when no-modifier-on-drop
+ (let (deactivate-mark)
+ (delete-region (overlay-start mouse-drag-and-drop-overlay)
+ (overlay-end mouse-drag-and-drop-overlay))))
+ ;; When source buffer and destination buffer are different,
+ ;; keep (set back the original text as region) or remove the
+ ;; original text.
+ (select-window window) ; Select window with source buffer.
+ (goto-char point) ; Move point to the original text on source buffer.
+
+ (if mouse-drag-and-drop-region-cut-when-buffers-differ
+ ;; Remove the dragged text from source buffer like
+ ;; operation `cut'.
+ (delete-region (overlay-start mouse-drag-and-drop-overlay)
+ (overlay-end mouse-drag-and-drop-overlay))
+ ;; Set back the dragged text as region on source buffer
+ ;; like operation `copy'.
+ (activate-mark))
+ (select-window window-to-paste)))))
+
+ ;; Clean up.
+ (delete-overlay mouse-drag-and-drop-overlay)))
\f
;;; Bindings for mouse commands.
next prev parent reply other threads:[~2017-11-27 13:11 UTC|newest]
Thread overview: 89+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-11-14 9:54 mouse-drag-and-drop-region martin rudalics
2017-11-14 17:01 ` mouse-drag-and-drop-region Eli Zaretskii
2017-11-14 18:29 ` mouse-drag-and-drop-region martin rudalics
2017-11-14 20:17 ` mouse-drag-and-drop-region Alex
2017-11-15 9:22 ` mouse-drag-and-drop-region martin rudalics
2017-11-15 18:22 ` mouse-drag-and-drop-region Eli Zaretskii
2017-11-15 18:50 ` mouse-drag-and-drop-region martin rudalics
2017-11-15 20:01 ` mouse-drag-and-drop-region Eli Zaretskii
2017-11-16 9:04 ` mouse-drag-and-drop-region martin rudalics
2017-11-15 19:46 ` mouse-drag-and-drop-region Alex
2017-11-15 20:15 ` mouse-drag-and-drop-region Eli Zaretskii
2017-11-15 22:03 ` mouse-drag-and-drop-region Alex
2017-11-16 15:54 ` mouse-drag-and-drop-region Eli Zaretskii
2017-11-17 6:33 ` mouse-drag-and-drop-region Alex
2017-11-17 7:33 ` mouse-drag-and-drop-region Eli Zaretskii
2017-11-17 15:58 ` mouse-drag-and-drop-region Stefan Monnier
2017-11-17 16:39 ` mouse-drag-and-drop-region Eli Zaretskii
2017-11-17 22:44 ` mouse-drag-and-drop-region Stefan Monnier
2017-11-18 7:54 ` mouse-drag-and-drop-region Eli Zaretskii
2017-11-18 14:36 ` mouse-drag-and-drop-region Stefan Monnier
2017-11-18 15:04 ` mouse-drag-and-drop-region Eli Zaretskii
2017-11-18 15:49 ` mouse-drag-and-drop-region Stefan Monnier
2017-11-18 6:48 ` mouse-drag-and-drop-region Alex
2017-11-18 9:07 ` mouse-drag-and-drop-region Eli Zaretskii
2017-11-18 21:58 ` mouse-drag-and-drop-region Alex
2017-11-19 15:27 ` mouse-drag-and-drop-region Eli Zaretskii
2017-11-17 8:53 ` mouse-drag-and-drop-region martin rudalics
2017-11-18 6:49 ` mouse-drag-and-drop-region Alex
2017-11-16 9:04 ` mouse-drag-and-drop-region martin rudalics
2017-11-17 6:02 ` mouse-drag-and-drop-region Alex
2017-11-17 8:53 ` mouse-drag-and-drop-region martin rudalics
2017-11-15 20:22 ` mouse-drag-and-drop-region Eli Zaretskii
2017-11-16 0:28 ` mouse-drag-and-drop-region Tak Kunihiro
2017-11-16 9:11 ` mouse-drag-and-drop-region martin rudalics
2017-11-20 13:29 ` mouse-drag-and-drop-region Tak Kunihiro
2017-11-20 16:03 ` mouse-drag-and-drop-region Drew Adams
2017-11-20 16:09 ` mouse-drag-and-drop-region Alan Schmitt
2017-11-20 17:34 ` mouse-drag-and-drop-region Eli Zaretskii
2017-11-20 18:17 ` mouse-drag-and-drop-region Paul Eggert
2017-11-21 9:24 ` mouse-drag-and-drop-region martin rudalics
2017-11-21 13:09 ` mouse-drag-and-drop-region Stefan Monnier
2017-11-21 14:05 ` mouse-drag-and-drop-region martin rudalics
2017-11-21 19:07 ` mouse-drag-and-drop-region Stefan Monnier
2017-11-22 8:26 ` mouse-drag-and-drop-region martin rudalics
2017-11-22 21:20 ` mouse-drag-and-drop-region Stefan Monnier
2017-11-23 7:46 ` mouse-drag-and-drop-region martin rudalics
2017-11-23 14:00 ` mouse-drag-and-drop-region Stefan Monnier
2017-11-23 16:09 ` mouse-drag-and-drop-region Eli Zaretskii
2017-11-24 9:02 ` mouse-drag-and-drop-region martin rudalics
2017-11-24 9:19 ` mouse-drag-and-drop-region Eli Zaretskii
2017-11-24 9:41 ` mouse-drag-and-drop-region martin rudalics
2017-11-24 13:25 ` mouse-drag-and-drop-region Stefan Monnier
2017-11-26 10:24 ` mouse-drag-and-drop-region martin rudalics
2017-11-24 13:45 ` mouse-drag-and-drop-region Eli Zaretskii
2017-11-26 10:24 ` mouse-drag-and-drop-region martin rudalics
2017-11-26 15:54 ` mouse-drag-and-drop-region Eli Zaretskii
2017-11-27 8:48 ` mouse-drag-and-drop-region martin rudalics
2017-11-27 15:59 ` mouse-drag-and-drop-region Eli Zaretskii
2017-11-21 15:45 ` mouse-drag-and-drop-region Eli Zaretskii
2017-11-22 8:22 ` mouse-drag-and-drop-region martin rudalics
2017-11-21 18:52 ` mouse-drag-and-drop-region Robert Weiner
2017-11-22 8:22 ` mouse-drag-and-drop-region martin rudalics
2017-11-23 23:28 ` mouse-drag-and-drop-region Tak Kunihiro
2017-11-24 9:02 ` mouse-drag-and-drop-region martin rudalics
2017-11-27 13:11 ` Tak Kunihiro [this message]
2017-11-28 8:50 ` mouse-drag-and-drop-region martin rudalics
2017-12-01 14:16 ` mouse-drag-and-drop-region Tak Kunihiro
2017-12-02 10:16 ` mouse-drag-and-drop-region martin rudalics
2017-12-03 10:06 ` mouse-drag-and-drop-region martin rudalics
2017-12-03 13:36 ` mouse-drag-and-drop-region martin rudalics
2017-12-05 4:57 ` mouse-drag-and-drop-region Tak Kunihiro
2017-12-05 8:53 ` mouse-drag-and-drop-region martin rudalics
2017-12-06 9:29 ` mouse-drag-and-drop-region Tak Kunihiro
2017-12-07 9:26 ` mouse-drag-and-drop-region martin rudalics
2017-12-07 21:45 ` mouse-drag-and-drop-region Tak Kunihiro
2017-12-08 10:12 ` mouse-drag-and-drop-region martin rudalics
2017-12-08 16:14 ` mouse-drag-and-drop-region Robert Weiner
2017-12-09 10:35 ` mouse-drag-and-drop-region martin rudalics
2017-12-14 23:14 ` mouse-drag-and-drop-region Tak Kunihiro
2017-12-15 8:50 ` mouse-drag-and-drop-region martin rudalics
2017-12-15 13:25 ` mouse-drag-and-drop-region martin rudalics
2017-12-16 2:07 ` mouse-drag-and-drop-region Tak Kunihiro
2017-12-16 9:42 ` mouse-drag-and-drop-region martin rudalics
2017-12-17 4:40 ` mouse-drag-and-drop-region Tak Kunihiro
2017-12-17 10:44 ` mouse-drag-and-drop-region martin rudalics
2017-12-21 1:36 ` mouse-drag-and-drop-region Tak Kunihiro
2017-12-22 8:43 ` mouse-drag-and-drop-region martin rudalics
2017-12-22 9:25 ` mouse-drag-and-drop-region Eli Zaretskii
2017-12-22 17:57 ` mouse-drag-and-drop-region martin rudalics
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20171127.221126.1551780406743300719.tkk@misasa.okayama-u.ac.jp \
--to=tkk@misasa.okayama-u.ac.jp \
--cc=agrambot@gmail.com \
--cc=eliz@gnu.org \
--cc=emacs-devel@gnu.org \
--cc=rudalics@gmx.at \
--cc=tak.kunihiro@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this external index
https://git.savannah.gnu.org/cgit/emacs.git
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.