emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

master e351e9037c: Add new option `mouse-drag-and-drop-region-scroll-mar


From: Po Lu
Subject: master e351e9037c: Add new option `mouse-drag-and-drop-region-scroll-margin'
Date: Sat, 2 Apr 2022 03:45:55 -0400 (EDT)

branch: master
commit e351e9037cbb7c63d7a022256bb87baa9990570d
Author: Po Lu <luangruo@yahoo.com>
Commit: Po Lu <luangruo@yahoo.com>

    Add new option `mouse-drag-and-drop-region-scroll-margin'
    
    * etc/NEWS: Announce new user option.
    * lisp/mouse.el (mouse-drag-and-drop-region-scroll-margin): New
    user option.
    (mouse-drag-and-drop-region): Implement "scroll margin" like
    behavior during mouse movement.
---
 etc/NEWS      |  5 +++++
 lisp/mouse.el | 36 ++++++++++++++++++++++++++++++++++++
 2 files changed, 41 insertions(+)

diff --git a/etc/NEWS b/etc/NEWS
index 3df326aa5b..9196e9fb90 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -190,6 +190,11 @@ methods instead.
 If non-nil, this option allows dragging text in the region from Emacs
 to another program.
 
+---
+** New user option 'mouse-drag-and-drop-region-scroll-margin'.
+If non-nil, this option allows scrolling a window while dragging text
+around without a scroll wheel.
+
 +++
 ** New function 'command-query'.
 This function makes its argument command prompt the user for
diff --git a/lisp/mouse.el b/lisp/mouse.el
index 4d6acf0d92..5e56a9e972 100644
--- a/lisp/mouse.el
+++ b/lisp/mouse.el
@@ -97,6 +97,14 @@ point at the click position."
   :type 'boolean
   :version "22.1")
 
+(defcustom mouse-drag-and-drop-region-scroll-margin nil
+  "If non-nil, the scroll margin inside a window when dragging text.
+If the mouse moves this many lines close to the top or bottom of
+a window while dragging text, then that window will be scrolled
+down and up respectively."
+  :type 'integer
+  :version "29.1")
+
 (defvar mouse--last-down nil)
 
 (defun mouse--down-1-maybe-follows-link (&optional _prompt)
@@ -3084,6 +3092,34 @@ is copied instead of being cut."
                        ;; Handle `mouse-autoselect-window'.
                        (memq (car event) '(select-window switch-frame))))
             (catch 'drag-again
+              ;; If the mouse is in the drag scroll margin, scroll
+              ;; either up or down depending on which margin it is in.
+              (when mouse-drag-and-drop-region-scroll-margin
+                (let* ((row (cdr (posn-col-row (event-end event))))
+                       (window (posn-window (event-end event)))
+                       (text-height (window-text-height window))
+                       ;; Make sure it's possible to scroll both up
+                       ;; and down if the margin is too large for the
+                       ;; window.
+                       (margin (min (/ text-height 3)
+                                    mouse-drag-and-drop-region-scroll-margin)))
+                  ;; At 2 lines, the window becomes too small for any
+                  ;; meaningful scrolling.
+                  (unless (<= text-height 2)
+                    ;; We could end up at the beginning or end of the
+                    ;; buffer.
+                    (ignore-errors
+                      (when (windowp window)
+                        (cond
+                         ;; Inside the bottom scroll margin, scroll up.
+                         ((> row (- text-height margin))
+                          (with-selected-window window
+                            (scroll-up 1)))
+                         ;; Inside the top scroll margin, scroll down.
+                         ((< row margin)
+                          (with-selected-window window
+                            (scroll-down 1)))))))))
+
               ;; Obtain the dragged text in region.  When the loop was
               ;; skipped, value-selection remains nil.
               (unless value-selection



reply via email to

[Prev in Thread] Current Thread [Next in Thread]