diff options
| author | Tak Kunihiro | 2017-05-27 14:57:11 +0300 |
|---|---|---|
| committer | Eli Zaretskii | 2017-05-27 14:57:11 +0300 |
| commit | c0f2c298772fbb1dcaa1da3e9c2760e09147e115 (patch) | |
| tree | 17d694e3cedd4a3f756c6e0deae131fafb8e0e62 | |
| parent | 6f63c7cb6a02d913d195410e4df85fad5832db06 (diff) | |
| download | emacs-c0f2c298772fbb1dcaa1da3e9c2760e09147e115.tar.gz emacs-c0f2c298772fbb1dcaa1da3e9c2760e09147e115.zip | |
Support drag and drop of region by mouse (Bug#26725)
* doc/emacs/frames.texi (Drag and Drop): Document support of drag
and drop region by mouse.
* lisp/mouse.el (mouse-drag-region): Call mouse-drag-and-drop-region
when start-event is on region.
(mouse-drag-and-drop-region): New function, moves the region by
(mouse-drag-and-drop-region): New defcustom.
* etc/NEWS: Mention mouse-drag-and-drop-region.
| -rw-r--r-- | doc/emacs/frames.texi | 12 | ||||
| -rw-r--r-- | etc/NEWS | 4 | ||||
| -rw-r--r-- | lisp/mouse.el | 95 |
3 files changed, 106 insertions, 5 deletions
diff --git a/doc/emacs/frames.texi b/doc/emacs/frames.texi index 68c12d272f8..8984555066b 100644 --- a/doc/emacs/frames.texi +++ b/doc/emacs/frames.texi | |||
| @@ -1074,6 +1074,18 @@ file on a Dired buffer moves or copies the file (according to the | |||
| 1074 | conventions of the application it came from) into the directory | 1074 | conventions of the application it came from) into the directory |
| 1075 | displayed in that buffer. | 1075 | displayed in that buffer. |
| 1076 | 1076 | ||
| 1077 | @vindex mouse-drag-and-drop-region | ||
| 1078 | Emacs can also optionally drag the region of text by mouse into | ||
| 1079 | another portion of this or another buffer. To enable that, customize | ||
| 1080 | the variable @code{mouse-drag-and-drop-region} to a non-nil value. | ||
| 1081 | Normally, the text is moved, i.e. cut and pasted, when the destination | ||
| 1082 | is the same buffer as the origin; dropping the region on another | ||
| 1083 | buffer copies the text instead. If the value of this variable names a | ||
| 1084 | modifier key, such as @samp{shift} or @samp{control} or @samp{alt}, | ||
| 1085 | then pressing that modifier key when dropping the text will copy it | ||
| 1086 | instead of cutting it, even if you drop on the same buffer as the one | ||
| 1087 | from which the text came. | ||
| 1088 | |||
| 1077 | @vindex dnd-open-file-other-window | 1089 | @vindex dnd-open-file-other-window |
| 1078 | Dropping a file normally visits it in the window you drop it on. If | 1090 | Dropping a file normally visits it in the window you drop it on. If |
| 1079 | you prefer to visit the file in a new window in such cases, customize | 1091 | you prefer to visit the file in a new window in such cases, customize |
| @@ -169,6 +169,10 @@ keeps point at the end of the region, setting it to non-nil moves | |||
| 169 | point to the beginning of the region. | 169 | point to the beginning of the region. |
| 170 | 170 | ||
| 171 | +++ | 171 | +++ |
| 172 | ** The new user option 'mouse-drag-and-drop-region' allows to drag the | ||
| 173 | entire region of text to another place or another buffer. | ||
| 174 | |||
| 175 | +++ | ||
| 172 | ** The new user option 'confirm-kill-processes' allows the user to | 176 | ** The new user option 'confirm-kill-processes' allows the user to |
| 173 | skip a confirmation prompt for killing subprocesses when exiting | 177 | skip a confirmation prompt for killing subprocesses when exiting |
| 174 | Emacs. When set to t (the default), Emacs will prompt for | 178 | Emacs. When set to t (the default), Emacs will prompt for |
diff --git a/lisp/mouse.el b/lisp/mouse.el index 0520fd1ab93..9b6b169e568 100644 --- a/lisp/mouse.el +++ b/lisp/mouse.el | |||
| @@ -714,12 +714,19 @@ Upon exit, point is at the far edge of the newly visible text." | |||
| 714 | Highlight the drag area as you move the mouse. | 714 | Highlight the drag area as you move the mouse. |
| 715 | This must be bound to a button-down mouse event. | 715 | This must be bound to a button-down mouse event. |
| 716 | In Transient Mark mode, the highlighting remains as long as the mark | 716 | In Transient Mark mode, the highlighting remains as long as the mark |
| 717 | remains active. Otherwise, it remains until the next input event." | 717 | remains active. Otherwise, it remains until the next input event. |
| 718 | (interactive "e") | ||
| 719 | ;; Give temporary modes such as isearch a chance to turn off. | ||
| 720 | (run-hooks 'mouse-leave-buffer-hook) | ||
| 721 | (mouse-drag-track start-event)) | ||
| 722 | 718 | ||
| 719 | When the region already exists and `mouse-drag-and-drop-region' | ||
| 720 | is non-nil, this moves the entire region of text to where mouse | ||
| 721 | is dragged over to." | ||
| 722 | (interactive "e") | ||
| 723 | (if (and mouse-drag-and-drop-region | ||
| 724 | (not (member 'triple (event-modifiers start-event))) | ||
| 725 | (equal (mouse-posn-property (event-start start-event) 'face) 'region)) | ||
| 726 | (mouse-drag-and-drop-region start-event) | ||
| 727 | ;; Give temporary modes such as isearch a chance to turn off. | ||
| 728 | (run-hooks 'mouse-leave-buffer-hook) | ||
| 729 | (mouse-drag-track start-event))) | ||
| 723 | 730 | ||
| 724 | (defun mouse-posn-property (pos property) | 731 | (defun mouse-posn-property (pos property) |
| 725 | "Look for a property at click position. | 732 | "Look for a property at click position. |
| @@ -1937,6 +1944,84 @@ choose a font." | |||
| 1937 | t (called-interactively-p 'interactive))))))))) | 1944 | t (called-interactively-p 'interactive))))))))) |
| 1938 | 1945 | ||
| 1939 | 1946 | ||
| 1947 | ;; Drag and drop support. | ||
| 1948 | (defcustom mouse-drag-and-drop-region nil | ||
| 1949 | "If non-nil, dragging the mouse drags the region, if that exists. | ||
| 1950 | If the value is a modifier, such as `control' or `shift' or `meta', | ||
| 1951 | then if that modifier key is pressed when dropping the region, region | ||
| 1952 | text is copied instead of being cut." | ||
| 1953 | :type 'symbol | ||
| 1954 | :version "26.1" | ||
| 1955 | :group 'mouse) | ||
| 1956 | |||
| 1957 | (defun mouse-drag-and-drop-region (event) | ||
| 1958 | "Move text in the region to point where mouse is dragged to. | ||
| 1959 | The transportation of text is also referred as `drag and drop'. | ||
| 1960 | When text is dragged over to a different buffer, or if a | ||
| 1961 | modifier key was pressed when dropping, and the value of the | ||
| 1962 | variable `mouse-drag-and-drop-region' is that modifier, the text | ||
| 1963 | is copied instead of being cut." | ||
| 1964 | (interactive "e") | ||
| 1965 | (require 'tooltip) | ||
| 1966 | (let ((start (region-beginning)) | ||
| 1967 | (end (region-end)) | ||
| 1968 | (point (point)) | ||
| 1969 | (buffer (current-buffer)) | ||
| 1970 | (window (selected-window)) | ||
| 1971 | value-selection) | ||
| 1972 | (track-mouse | ||
| 1973 | ;; When event was click instead of drag, skip loop | ||
| 1974 | (while (progn | ||
| 1975 | (setq event (read-event)) | ||
| 1976 | (mouse-movement-p event)) | ||
| 1977 | (unless value-selection ; initialization | ||
| 1978 | (delete-overlay mouse-secondary-overlay) | ||
| 1979 | (setq value-selection (buffer-substring start end)) | ||
| 1980 | (move-overlay mouse-secondary-overlay start end)) ; (deactivate-mark) | ||
| 1981 | (ignore-errors (deactivate-mark) ; care existing region in other window | ||
| 1982 | (mouse-set-point event) | ||
| 1983 | (tooltip-show value-selection))) | ||
| 1984 | (tooltip-hide)) | ||
| 1985 | ;; Do not modify buffer under mouse when "event was click", | ||
| 1986 | ;; "drag negligible", or | ||
| 1987 | ;; "drag to read-only". | ||
| 1988 | (if (or (equal (mouse-posn-property (event-end event) 'face) 'region) ; "event was click" | ||
| 1989 | (member 'secondary-selection ; "drag negligible" | ||
| 1990 | (mapcar (lambda (xxx) (overlay-get xxx 'face)) | ||
| 1991 | (overlays-at (posn-point (event-end event))))) | ||
| 1992 | buffer-read-only) | ||
| 1993 | ;; Do not modify buffer under mouse. | ||
| 1994 | (cond | ||
| 1995 | ;; "drag negligible" or "drag to read-only", restore region. | ||
| 1996 | (value-selection | ||
| 1997 | (select-window window) ; In case miss drag to other window | ||
| 1998 | (goto-char point) | ||
| 1999 | (setq deactivate-mark nil) | ||
| 2000 | (activate-mark)) | ||
| 2001 | ;; "event was click" | ||
| 2002 | (t | ||
| 2003 | (deactivate-mark) | ||
| 2004 | (mouse-set-point event))) | ||
| 2005 | ;; Modify buffer under mouse by inserting text. | ||
| 2006 | (push-mark) | ||
| 2007 | (insert value-selection) | ||
| 2008 | (when (not (equal (mark) (point))) ; on success insert | ||
| 2009 | (setq deactivate-mark nil) | ||
| 2010 | (activate-mark)) ; have region on destination | ||
| 2011 | ;; Take care of initial region on source. | ||
| 2012 | (if (equal (current-buffer) buffer) ; when same buffer | ||
| 2013 | (let (deactivate-mark) ; remove text | ||
| 2014 | (unless (member mouse-drag-and-drop-region (event-modifiers event)) | ||
| 2015 | (kill-region (overlay-start mouse-secondary-overlay) | ||
| 2016 | (overlay-end mouse-secondary-overlay)))) | ||
| 2017 | (let ((window1 (selected-window))) ; when beyond buffer | ||
| 2018 | (select-window window) | ||
| 2019 | (goto-char point) ; restore point on source window | ||
| 2020 | (activate-mark) ; restore region | ||
| 2021 | (select-window window1)))) | ||
| 2022 | (delete-overlay mouse-secondary-overlay))) | ||
| 2023 | |||
| 2024 | |||
| 1940 | ;;; Bindings for mouse commands. | 2025 | ;;; Bindings for mouse commands. |
| 1941 | 2026 | ||
| 1942 | (global-set-key [down-mouse-1] 'mouse-drag-region) | 2027 | (global-set-key [down-mouse-1] 'mouse-drag-region) |