unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
* bug#38013: [PATCH] Rectangular region selection with mouse
@ 2019-10-31 21:55 Mattias Engdegård
  2019-11-01  0:12 ` Drew Adams
  2019-11-01  7:51 ` Eli Zaretskii
  0 siblings, 2 replies; 55+ messages in thread
From: Mattias Engdegård @ 2019-10-31 21:55 UTC (permalink / raw)
  To: 38013

[-- Attachment #1: Type: text/plain, Size: 761 bytes --]

This is a proposal to add mouse-selection of rectangular regions. It turns out to be useful; Emacs should come with the facility built-in.

The main problem is what to bind it to. The common modifiers (shift, control, meta) are already taken. Platforms have different "standard" modifiers: Option on macOS, Alt on Windows, Control in Gnome (?).

Assuming that the secondary selection is somewhat of an anachronism which is likely to be less used today than the rectangular one would be, the patch uses Meta as default modifier. Both secondary and rectangular mouse selection have defcustoms permitting easy change.

The defaults could be different, for example if secondary mouse selection turns out to be very popular.
There is no documentation yet.


[-- Attachment #2: 0001-Mouse-rectangular-region-selection.patch --]
[-- Type: application/octet-stream, Size: 7307 bytes --]

From e8d781baf8ffd0cd911505a50ffefa0f54d2d185 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Mattias=20Engdeg=C3=A5rd?= <mattiase@acm.org>
Date: Fri, 25 Oct 2019 11:16:39 +0200
Subject: [PATCH] Mouse rectangular region selection

Make it possible to select a rectangular region using the mouse.
The modifier is customisable and defaults to meta.
The modifier for mouse secondary selection is now also customisable and
defaults to nil (disabled).

* lisp/mouse.el (mouse-scroll-subr): Add COLUMN argument.
(mouse-drag-region-rectangle): New.
(mouse--global-with-modifier)
(mouse--set-secondary-selection-bindings, mouse-secondary-selection-modifier)
(mouse--set-rectangular-region-selection-bindings)
(mouse-region-rectangle-modifier): New defcustoms with helper functions.
---
 lisp/mouse.el | 110 +++++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 104 insertions(+), 6 deletions(-)

diff --git a/lisp/mouse.el b/lisp/mouse.el
index 4a351f7be2..48ea109daa 100644
--- a/lisp/mouse.el
+++ b/lisp/mouse.el
@@ -1045,10 +1045,11 @@ mouse-scroll-min-lines
 of lines specified by this variable."
   :type 'integer)
 
-(defun mouse-scroll-subr (window jump &optional overlay start)
+(defun mouse-scroll-subr (window jump &optional overlay start column)
   "Scroll the window WINDOW, JUMP lines at a time, until new input arrives.
 If OVERLAY is an overlay, let it stretch from START to the far edge of
 the newly visible text.
+If COLUMN is non-nil, try to keep point in that column when scrolling.
 Upon exit, point is at the far edge of the newly visible text."
   (cond
    ((and (> jump 0) (< jump mouse-scroll-min-lines))
@@ -1077,6 +1078,8 @@ mouse-scroll-subr
 		   ;; so that we don't mess up the selected window.
 		   (or (eq window (selected-window))
 		       (goto-char opoint))
+                   (when column
+                     (move-to-column column))
 		   (sit-for mouse-scroll-delay)))))
     (or (eq window (selected-window))
 	(goto-char opoint))))
@@ -1666,11 +1669,43 @@ mouse-save-then-kill
       (setq mouse-save-then-kill-posn click-pt)))))
 
 \f
-(global-set-key [M-mouse-1] 'mouse-start-secondary)
-(global-set-key [M-drag-mouse-1] 'mouse-set-secondary)
-(global-set-key [M-down-mouse-1] 'mouse-drag-secondary)
-(global-set-key [M-mouse-3] 'mouse-secondary-save-then-kill)
-(global-set-key [M-mouse-2] 'mouse-yank-secondary)
+(defun mouse--global-with-modifier (base modifier command)
+  "Globally bind BASE + MODIFIER to COMMAND."
+  (global-set-key (vector (event-convert-list (list modifier base))) command))
+
+(defun mouse--set-secondary-selection-bindings (mod activate)
+  "Set global mouse bindings using MOD for secondary selection.
+If ACTIVATE is nil, remove those bindings."
+  (when mod
+    (mouse--global-with-modifier 'mouse-1 mod
+                                 (and activate 'mouse-start-secondary))
+    (mouse--global-with-modifier 'drag-mouse-1 mod
+                                 (and activate 'mouse-set-secondary))
+    (mouse--global-with-modifier 'down-mouse-1 mod
+                                 (and activate 'mouse-drag-secondary))
+    (mouse--global-with-modifier 'mouse-3 mod
+                                 (and activate 'mouse-secondary-save-then-kill))
+    (mouse--global-with-modifier 'mouse-2 mod
+                                 (and activate 'mouse-yank-secondary))))
+
+(defcustom mouse-secondary-selection-modifier nil
+  "The modifier key for secondary selection using the mouse.
+If nil, mouse secondary selection is disabled."
+  :group 'mouse
+  :type '(choice (const :tag "None (disabled)" nil)
+                 (const meta)
+                 (const control)
+                 (const shift)
+                 (const super)
+                 (const hyper))
+  :version "27.1"
+  :set (lambda (variable new-value)
+         (when (boundp 'mouse-secondary-selection-modifier)
+           (mouse--set-secondary-selection-bindings
+            mouse-secondary-selection-modifier nil))
+         (set-default variable new-value)
+         (mouse--set-secondary-selection-bindings
+          mouse-secondary-selection-modifier t)))
 
 (defconst mouse-secondary-overlay
   (let ((ol (make-overlay (point-min) (point-min))))
@@ -1960,6 +1995,69 @@ secondary-selection-from-region
     (move-overlay mouse-secondary-overlay (region-beginning) (region-end))))
 
 \f
+(defun mouse-drag-region-rectangle (start-event)
+  "Set the region to the rectangle that the mouse is dragged over.
+This must be bound to a button-down mouse event."
+  (interactive "e")
+  (deactivate-mark)
+  (mouse-set-point start-event)
+  (rectangle-mark-mode)
+  (let* ((scroll-margin 0)
+         (start-posn (event-start start-event))
+         (start-point (posn-point start-posn))
+         (start-window (posn-window start-posn))
+         (bounds (window-edges start-window))
+         (top (nth 1 bounds))
+         (bottom (if (window-minibuffer-p start-window)
+                     (nth 3 bounds)
+                   (1- (nth 3 bounds))))
+         event)
+    (track-mouse
+      (while (progn
+               (setq event (read-event))
+               (mouse-movement-p event))
+        (let ((window (posn-window (event-end event)))
+              (mouse-row (cddr (mouse-position))))
+          (if (and (eq window start-window)
+                   mouse-row
+                   (<= top mouse-row (1- bottom)))
+              (mouse-set-point event)
+            (cond
+             ((null mouse-row))
+             ((< mouse-row top)
+              (mouse-scroll-subr start-window (- mouse-row top)
+                                 nil start-point (current-column)))
+             ((>= mouse-row bottom)
+              (mouse-scroll-subr start-window (1+ (- mouse-row bottom))
+                                 nil start-point (current-column))))))))))
+
+(defun mouse--set-rectangular-region-selection-bindings (mod activate)
+  "Set global mouse bindings using MOD for rectangular selection.
+If ACTIVATE is nil, remove those bindings."
+  (when mod
+    (mouse--global-with-modifier 'down-mouse-1 mod
+                                 (and activate 'mouse-drag-region-rectangle))))
+
+(defcustom mouse-region-rectangle-modifier 'meta
+  "The modifier key for rectangular region selection using the mouse.
+If nil, mouse rectangular region selection is disabled."
+  :group 'mouse
+  :type '(choice (const :tag "None (disabled)" nil)
+                 (const meta)
+                 (const control)
+                 (const shift)
+                 (const super)
+                 (const hyper))
+  :version "27.1"
+  :set (lambda (variable new-value)
+         (when (boundp 'mouse-region-rectangle-modifier)
+           (mouse--set-rectangular-region-selection-bindings
+            mouse-region-rectangle-modifier nil))
+         (set-default variable new-value)
+         (mouse--set-rectangular-region-selection-bindings
+          mouse-region-rectangle-modifier t)))
+
+\f
 (defcustom mouse-buffer-menu-maxlen 20
   "Number of buffers in one pane (submenu) of the buffer menu.
 If we have lots of buffers, divide them into groups of
-- 
2.21.0 (Apple Git-122)


^ permalink raw reply related	[flat|nested] 55+ messages in thread
[parent not found: <<C2CEADBB-4388-45A5-9D4D-8963314B2913@acm.org>]
[parent not found: <<<C2CEADBB-4388-45A5-9D4D-8963314B2913@acm.org>]

end of thread, other threads:[~2019-11-27 14:04 UTC | newest]

Thread overview: 55+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2019-10-31 21:55 bug#38013: [PATCH] Rectangular region selection with mouse Mattias Engdegård
2019-11-01  0:12 ` Drew Adams
2019-11-01  7:51 ` Eli Zaretskii
2019-11-01 11:53   ` Mattias Engdegård
2019-11-01 13:17     ` Eli Zaretskii
2019-11-01 13:30       ` Eli Zaretskii
2019-11-03 21:12         ` Mattias Engdegård
2019-11-03 21:51           ` Drew Adams
2019-11-04  9:07           ` martin rudalics
2019-11-04 11:33             ` Mattias Engdegård
2019-11-04 15:25               ` Drew Adams
2019-11-04 18:27               ` martin rudalics
2019-11-04 20:18                 ` Mattias Engdegård
2019-11-05  9:35                   ` martin rudalics
2019-11-07 17:48                     ` Mattias Engdegård
2019-11-07 17:53                       ` Drew Adams
2019-11-07 18:27                         ` Mattias Engdegård
2019-11-07 19:08                       ` martin rudalics
2019-11-07 20:46                         ` Drew Adams
2019-11-08 17:33                         ` Mattias Engdegård
2019-11-08 18:28                           ` martin rudalics
2019-11-09 15:35                             ` Mattias Engdegård
2019-11-09 17:54                               ` Eli Zaretskii
2019-11-09 19:32                                 ` Mattias Engdegård
2019-11-09 20:04                                   ` Eli Zaretskii
2019-11-10 13:49                                     ` Mattias Engdegård
2019-11-12 14:26                                       ` Mattias Engdegård
2019-11-12 15:39                                         ` Drew Adams
2019-11-14 13:56                                         ` Mattias Engdegård
2019-11-16 12:35                                       ` Eli Zaretskii
2019-11-17 12:11                                         ` Mattias Engdegård
2019-11-18 18:08                                           ` Mattias Engdegård
2019-11-18 19:22                                             ` Drew Adams
2019-11-18 21:29                                               ` Juri Linkov
2019-11-19  7:57                                                 ` martin rudalics
2019-11-19 13:57                                                   ` Mattias Engdegård
2019-11-19 15:09                                                     ` Drew Adams
2019-11-19 15:37                                                       ` Mattias Engdegård
2019-11-19 16:08                                                         ` Drew Adams
2019-11-19 16:26                                                           ` Mattias Engdegård
2019-11-19 17:30                                                           ` Eli Zaretskii
2019-11-20 22:38                                                             ` Juri Linkov
2019-11-19 23:07                                                   ` Juri Linkov
2019-11-20  7:57                                                     ` martin rudalics
2019-11-23 11:57                                             ` Eli Zaretskii
2019-11-23 12:46                                               ` Mattias Engdegård
2019-11-23 14:53                                                 ` Eli Zaretskii
2019-11-23 15:17                                                   ` Mattias Engdegård
2019-11-27 14:04                                                   ` Mattias Engdegård
2019-11-10  3:48                               ` Richard Stallman
2019-11-01 13:23     ` martin rudalics
     [not found] <<C2CEADBB-4388-45A5-9D4D-8963314B2913@acm.org>
     [not found] ` <<83v9s3lo5f.fsf@gnu.org>
     [not found]   ` <<75EC4FBC-F636-4D75-BAC4-982D85188794@acm.org>
     [not found]     ` <<9b9222ad-ead7-d0a0-0602-780d0680f070@gmx.at>
     [not found]       ` <<DEA04CF5-72AC-4251-B10B-06291BDAECC2@acm.org>
     [not found]         ` <<6bf229f4-c22f-c3c2-5158-5235f908de3c@gmx.at>
     [not found]           ` <<A13CC15C-D255-4A38-B8EA-5FE818BB45D5@acm.org>
     [not found]             ` <<8ec84837-172c-1ce5-cab0-b4c96a86274e@gmx.at>
     [not found]               ` <<411EAB4E-B666-4263-8514-5F47391268B1@acm.org>
     [not found]                 ` <<2df02c1f-fea4-f764-eba6-fd67de581755@gmx.at>
     [not found]                   ` <<B6A6755E-2981-4369-9A6B-A0E752C69A77@acm.org>
     [not found]                     ` <<3b74a108-28e3-fd01-64a5-7c4302e3d979@gmx.at>
     [not found]                       ` <<9A9D13F2-1F4F-4DD4-B92F-96FC4D91DFBD@acm.org>
     [not found]                         ` <<83pni17x5b.fsf@gnu.org>
     [not found]                           ` <<8B95D2D3-8E00-45BF-B57D-EFD49D79EB6A@acm.org>
     [not found]                             ` <<83bltk95p7.fsf@gnu.org>
     [not found]                               ` <<60DD9D65-C3F0-470E-8489-B333E1889D32@acm.org>
     [not found]                                 ` <<83ftio6lsy.fsf@gnu.org>
     [not found]                                   ` <<290E5E66-964B-4E29-B141-166447AD5556@acm.org>
     [not found]                                     ` <<175E5B2E-2256-4FCD-AA8E-9E5BC6DE7907@acm.org>
     [not found]                                       ` <<7d94fa94-94e4-46dc-8df0-c40ccf052ee9@default>
     [not found]                                         ` <<87imngub40.fsf@mail.linkov.net>
     [not found]                                           ` <<60fa6496-c057-b69d-21c1-3b1de85b4b9f@gmx.at>
     [not found]                                             ` <<DE4EC019-FA36-434E-882C-D80192512DDB@acm.org>
     [not found]                                               ` <<9302a9ac-e64c-41ed-898b-24d59465fba4@default>
     [not found]                                                 ` <<EACDBDF2-FB23-475A-BCE9-3447DECBABC8@acm.org>
     [not found]                                                   ` <<ba3f1c42-91a9-4985-9376-6a84196167e8@default>
     [not found]                                                     ` <<83lfsb22pb.fsf@gnu.org>
2019-11-19 18:32                                                       ` Drew Adams
2019-11-19 19:24                                                         ` Eli Zaretskii
     [not found] <<<C2CEADBB-4388-45A5-9D4D-8963314B2913@acm.org>
     [not found] ` <<<83v9s3lo5f.fsf@gnu.org>
     [not found]   ` <<<75EC4FBC-F636-4D75-BAC4-982D85188794@acm.org>
     [not found]     ` <<<9b9222ad-ead7-d0a0-0602-780d0680f070@gmx.at>
     [not found]       ` <<<DEA04CF5-72AC-4251-B10B-06291BDAECC2@acm.org>
     [not found]         ` <<<6bf229f4-c22f-c3c2-5158-5235f908de3c@gmx.at>
     [not found]           ` <<<A13CC15C-D255-4A38-B8EA-5FE818BB45D5@acm.org>
     [not found]             ` <<<8ec84837-172c-1ce5-cab0-b4c96a86274e@gmx.at>
     [not found]               ` <<<411EAB4E-B666-4263-8514-5F47391268B1@acm.org>
     [not found]                 ` <<<2df02c1f-fea4-f764-eba6-fd67de581755@gmx.at>
     [not found]                   ` <<<B6A6755E-2981-4369-9A6B-A0E752C69A77@acm.org>
     [not found]                     ` <<<3b74a108-28e3-fd01-64a5-7c4302e3d979@gmx.at>
     [not found]                       ` <<<9A9D13F2-1F4F-4DD4-B92F-96FC4D91DFBD@acm.org>
     [not found]                         ` <<<83pni17x5b.fsf@gnu.org>
     [not found]                           ` <<<8B95D2D3-8E00-45BF-B57D-EFD49D79EB6A@acm.org>
     [not found]                             ` <<<83bltk95p7.fsf@gnu.org>
     [not found]                               ` <<<60DD9D65-C3F0-470E-8489-B333E1889D32@acm.org>
     [not found]                                 ` <<<83ftio6lsy.fsf@gnu.org>
     [not found]                                   ` <<<290E5E66-964B-4E29-B141-166447AD5556@acm.org>
     [not found]                                     ` <<<175E5B2E-2256-4FCD-AA8E-9E5BC6DE7907@acm.org>
     [not found]                                       ` <<<7d94fa94-94e4-46dc-8df0-c40ccf052ee9@default>
     [not found]                                         ` <<<87imngub40.fsf@mail.linkov.net>
     [not found]                                           ` <<<60fa6496-c057-b69d-21c1-3b1de85b4b9f@gmx.at>
     [not found]                                             ` <<<DE4EC019-FA36-434E-882C-D80192512DDB@acm.org>
     [not found]                                               ` <<<9302a9ac-e64c-41ed-898b-24d59465fba4@default>
     [not found]                                                 ` <<<EACDBDF2-FB23-475A-BCE9-3447DECBABC8@acm.org>
     [not found]                                                   ` <<<ba3f1c42-91a9-4985-9376-6a84196167e8@default>
     [not found]                                                     ` <<<83lfsb22pb.fsf@gnu.org>
     [not found]                                                       ` <<dc319e8e-42b3-4db8-b8d4-1580e6397174@default>
     [not found]                                                         ` <<83d0dn1xfd.fsf@gnu.org>
2019-11-19 19:34                                                           ` Drew Adams
2019-11-19 19:48                                                             ` Eli Zaretskii

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).