From: Tak Kunihiro <tak.kunihiro@gmail.com>
To: rudalics@gmx.at, Eli Zaretskii <eliz@gnu.org>, Alex <agrambot@gmail.com>
Cc: tak.kunihiro@gmail.com, emacs-devel@gnu.org
Subject: Re: mouse-drag-and-drop-region
Date: Mon, 20 Nov 2017 22:29:37 +0900 (JST) [thread overview]
Message-ID: <20171120.222937.949251858246319152.tak.kunihiro@gmail.com> (raw)
In-Reply-To: <5A0D562D.1010803@gmx.at>
I revised mouse-drag-and-drop-region. I'm sending replay to
https://lists.gnu.org/archive/html/emacs-devel/2017-11/msg00387.html,
ChangeLog, and patch.
* ChangeLog
2017-11-21 Tak Kunihiro <tkk@misasa.okayama-u.ac.jp>
Improve comments and have two new options
* lisp/mouse.el (mouse-drag-and-drop-region): Make tooltip preview to be an option. Have an option to make dragging cut among buffers.
(mouse-drag-and-drop-region-cut-among-buffer): New flag. When t, text is cut instead of copy when dragged among buffers.
(mouse-drag-and-drop-region-show-tooltip): New flag. When t, text is shown by a tooltip in a graphic display.
* Replay
> Did you ever consider using the "r" interactive switch instead of the
> "e" one?
I suppose you suggest something like below. I cannot make this work.
Thus this revision, I do not use "r" interactive switch.
(defun mouse-drag-and-drop-region (event start and)
(interactive "e\nr")
...)
>>> (2) Activating the secondary overlay can be distracting and should
>>> be made optional (facultatively keeping the primary overlay in
>>> place provided (4) below is done).
>>
>> Region on the other window is not visible. Thus original region
>> should be hi-lighted somehow. Since mouse-drag-and-drop-region is
>> located on mouse.el, mouse-secondary-overlay was used.
>
> You mean that you highlight the original region with the secondary
> overlay so that the overlay shows up on the target window as well and
> the user is informed that dropping there might lead to say "dubious"
> results?
I think yes. Also, since value-selection would be inserted before the
point and mark, I thought it is handy to keep track where was the
region by an overlay.
> I mean something like
>
> (defcustom mouse-drag-and-drop-region-show-secondary-overlay t ...)
>
> where setting this to nil means to just not show any overlay. And
> your code would have to accept that there is no secondary overlay at
> the time of the drop.
I found this takes significant time. I skip to get rid of usage of
secondary-overlay on this revision.
>>> (3) Showing tooltips can be distracting and should be optional.
>>> Note also, that usurping tooltips this way may prevent them from
>>> showing interesting properties of the drop area like whether the
>>> text there is read only. OTOH we might consider retaining
>>> properties of the text in (non-GTK) tooltips.
>>
> I would say
>
> (defcustom mouse-drag-and-drop-region-show-tooltip t)
>
> and never show a tooltip on text-only terminals even if this is t.
OK.
>>> (4) The (deactivate-mark) and (mouse-set-point event) trick to allow
>>> showing point the way ‘mouse-drag-track’ does can be distracting
>>> and should be made optional.
>>
>> I think that this is very related to 2, 3, and 5 (as you inferred).
>
> Yes. It's irritating to drag a block cursor with the mouse. Do you
> know of any other applications which do such a thing?
I cannot think of a way to show insert point besides (mouse-set-point
event). Do you suggest overlay-put "|" or change cursor-type to 'bar
during drag? I thought who prefers bar changes the default cursor
anyway. I did not revise code in this respect.
>>> (5) The mouse pointer shape should take care of indicating the exact
>>> position where the drop occurs. We should probably also signal
>>> whenever the current drop position is invalid. This is IIUC
>>> usual practice on most window systems now.
>>
>> I think it is a good idea.
>
> We probably need to define additional cursors for this so it's not for
> Emacs 26.
I did not revise code in this aspect.
>>> (7) IMO either cutting should be the default too when the drop
>>> occurs in a different buffer or copying would be the default and
>>> pressing the modifier should produce a cut instead. The current
>>> behavior wants me to always keep in mind whether the target
>>> buffer is the same as the source buffer. At least, this
>>> behavior should be made optional.
>>
>> Default behavior followed that of file browser on `drag' a file.
>
> Which file browser?
Finder on macOS and File Explorer on Windows 10 behave like that way.
>> Between the same volume (buffer), `drag' does `cut' instead of `copy'.
>> I prefer current behavior as default but have
>> no objection to have option something like
>> (defvar mouse-drag-and-drop-region-cut-hungry t)
>
> I would be more radical with
>
> (defcustom mouse-drag-and-drop-region-cut-or-copy t)
>
> where the values 'cut and 'copy would always categorically cut or copy
> (unless the value of 'mouse-drag-and-drop-region' implies to copy
> instead of cut) and t means your original behavior.
A new option was created. Now `cut' can be default even among
buffers.
(defvar mouse-drag-and-drop-region-cut-among-buffer nil
"When t, text is cut instead of copy when dragged among buffers.")
>>> (8) Read-only text should be handled. An attempt to drop text into
>>> a read-only area should be signalled to the user. An attempt to
>>> cut text from a read-only text/buffer should be signalled as
>>> well.
>>
>>> For the latter, we copy text instead (cf C-w in read-only text). So
>>> I think this feature should behave similarly, at least by default.
>>
>>> I just noticed that the code does use ‘kill-region’ already. This
>>> has the side-effect of putting the text into the kill ring,
>>> something which should be documented at least. But I think the code
>>> should rather use ‘delete-region’ instead with the behavior you
>>> proposed.
>>
>> I suppose that you suggest to tell user more explicitly in echo area
>> how he cannot change the text.
>
> The echo area should be avoided during tracking. Think of users who
> invoke 'mouse-drag-and-drop-region' on a frame without a minibuffer.
OK.
> I think that first of all you should use 'delete-region' instead of
> 'kill-region' to avoid the above-mentioned side effect. Then your
> code should silently swallow any bugs for cutting from read-only
> text provided 'kill-read-only-ok' is t. For that purpose, simply
> peruse the corresponding code from 'kill-region'.
OK. Now `delete-region' is used.
> A final drop into read-only text should always give an error. We
> should be able to redeem that by providing a feedback in form of a
> mouse cursor when the mouse is either over read-only text or no
> buffer text at all.
I revised only to give message. I could not tell how to bring
condition-case to code.
>> On an user perspective, operation `drag-and-drop-region' is a
>> combination of `cut' and `paste'. Thus text was killed instead of
>> deleted. How you think delete is more preferred? I have no
>> objection to document it.
> IMO using 'kill-region' is an unexpected side effect. If people
> think differently, we could add yet another option like
>
> (defucstom mouse-drag-and-drop-region-cut-does-kill-region t)
Now `delete-region' is used instead of `kill-region'.
* Patch
diff --git a/lisp/mouse.el b/lisp/mouse.el
old mode 100644
new mode 100755
index 17d1732..08f70d4
--- a/lisp/mouse.el
+++ b/lisp/mouse.el
@@ -2361,6 +2361,12 @@ text is copied instead of being cut."
:version "26.1"
:group 'mouse)
+(defvar mouse-drag-and-drop-region-cut-among-buffer nil
+ "When t, text is cut instead of copy when dragged among buffers.")
+
+(defvar mouse-drag-and-drop-region-show-tooltip t
+ "When t, text is shown by a tooltip in a graphic display.")
+
(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,64 +2375,98 @@ 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))
+ (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))
- value-selection)
+ no-modifier-on-drop
+ value-selection) ; This remains nil when event was "click".
(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
+ ;; Obtain the text in region. When the loop was skipped,
+ ;; value-selection remains nil.
+ (unless value-selection
(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.
+ (ignore-errors
+ (deactivate-mark) ; Maintain region in other window.
+ (mouse-set-point event)
+ (when mouse-drag-and-drop-region-show-tooltip
+ (tooltip-show value-selection))))
+ ;; Check if modifier was pressed on drop.
+ (setq no-modifier-on-drop
+ (not (member mouse-drag-and-drop-region (event-modifiers event))))
+ (when mouse-drag-and-drop-region-show-tooltip (tooltip-hide)))
+ ;; Do not modify buffer under mouse when event is "click", "drag
+ ;; but negligible", or "drag to read-only". Operation "drag but
+ ;; negligible" is defined as drag-and-drop the text to
+ ;; secondary-selection without modifier pressed. When pressed,
+ ;; the text will be inserted to inside of secondary-selection.
+ (if (or (equal (mouse-posn-property (event-end event) 'face) 'region) ; "click"
+ (and (member 'secondary-selection ; "drag but negligible"
+ (mapcar (lambda (xxx) (overlay-get xxx 'face))
+ (overlays-at (posn-point (event-end event)))))
+ no-modifier-on-drop)
+ buffer-read-only) ; "drag to read-only"
(cond
- ;; "drag negligible" or "drag to read-only", restore region.
+ ;; Set back the original text as region on "drag but negligible"
+ ;; or "drag to read-only".
(value-selection
- (select-window window) ; In case miss drag to other window
+ (if buffer-read-only (message "Buffer is read-only")) ; (barf-if-buffer-read-only)
+ (select-window window) ; Select the source windows back on miss-drag to other window.
(goto-char point)
(setq deactivate-mark nil)
(activate-mark))
- ;; "event was click"
+ ;; Move point within region on "click".
(t
(deactivate-mark)
(mouse-set-point event)))
- ;; Modify buffer under mouse by inserting text.
+ ;; Intert the text to destination buffer under mouse.
(push-mark)
(insert value-selection)
- (when (not (equal (mark) (point))) ; on success insert
+ ;; On success, set the text as region on destination buffer.
+ (when (not (equal (mark) (point)))
(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
+ (activate-mark))
+ ;; Set back the original text as region or delete the original
+ ;; text on source buffer.
+ (if (equal (current-buffer) buffer)
+ ;; When source buffer and destination buffer are the same,
+ ;; remove the original text.
+ (let (deactivate-mark)
+ (if no-modifier-on-drop
+ (delete-region (overlay-start mouse-secondary-overlay)
+ (overlay-end mouse-secondary-overlay))))
+ ;; When source buffer and destination buffer are different,
+ ;; keep (set back the original text as region) or remove the
+ ;; original text.
+ (let ((window1 (selected-window)))
+ (select-window window) ; Select window with source buffer.
+ (goto-char point) ; Move point to the original text on source buffer.
+ (if (or (if no-modifier-on-drop
+ (not mouse-drag-and-drop-region-cut-among-buffer)
+ mouse-drag-and-drop-region-cut-among-buffer)
+ buffer-read-only)
+ ;; Set back the original text as region on source buffer
+ ;; like operation `copy'.
+ (progn
+ (if buffer-read-only (message "Source is read-only")) ; (barf-if-buffer-read-only)
+ (activate-mark))
+ ;; Remove the original text from source buffer like
+ ;; operation `cut'.
+ (delete-region (overlay-start mouse-secondary-overlay)
+ (overlay-end mouse-secondary-overlay)))
(select-window window1))))
(delete-overlay mouse-secondary-overlay)))
\f
next prev parent reply other threads:[~2017-11-20 13:29 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 ` Tak Kunihiro [this message]
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 ` mouse-drag-and-drop-region Tak Kunihiro
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
List information: https://www.gnu.org/software/emacs/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20171120.222937.949251858246319152.tak.kunihiro@gmail.com \
--to=tak.kunihiro@gmail.com \
--cc=agrambot@gmail.com \
--cc=eliz@gnu.org \
--cc=emacs-devel@gnu.org \
--cc=rudalics@gmx.at \
/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 public inbox
https://git.savannah.gnu.org/cgit/emacs.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).