Function: mouse-drag-safe-scroll
mouse-drag-safe-scroll is a byte-compiled function defined in
mouse-drag.el.gz.
Signature
(mouse-drag-safe-scroll ROW-DELTA &optional COL-DELTA)
Documentation
Scroll down ROW-DELTA lines and right COL-DELTA, ignoring buffer edge errors.
Keep the cursor on the screen as needed.
Source Code
;; Defined in /usr/src/emacs/lisp/mouse-drag.el.gz
;;; mouse-drag.el --- use mouse-2 to do a new style of scrolling -*- lexical-binding: t -*-
;; Copyright (C) 1996-1997, 2001-2026 Free Software Foundation, Inc.
;; Author: John Heidemann <johnh@ISI.EDU>
;; Keywords: mouse
;; This file is part of GNU Emacs.
;; GNU Emacs is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;; GNU Emacs is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
;;; Commentary:
;; What is ``mouse-drag.el''?
;;
;; Doesn't that scroll bar seem far away when you want to scroll?
;; This module overloads mouse-2 to do ``throw'' scrolling. You
;; click and drag. The distance you move from your original click
;; turns into a scroll amount. The scroll amount is scaled
;; exponentially to make both large moves and short adjustments easy.
;; What this boils down to is that you can easily scroll around the
;; buffer without much mouse movement. Finally, clicks which aren't
;; drags are passed off to the old mouse-2 binding, so old mouse-2
;; operations (find-file in dired-mode, yanking in most other modes)
;; still work.
;;
;; There is an alternative way to scroll, ``drag'' scrolling. You
;; can click on a character and then drag it around, scrolling the
;; buffer with you. The character always stays under the mouse.
;; Compared to throw-scrolling, this approach provides direct
;; manipulation (nice) but requires more mouse movement
;; (unfortunate). It is offered as an alternative for those who
;; prefer it.
;;
;; If you like mouse-drag, you should also check out mouse-copy
;; for ``one-click text copy and move''.
;;
;; To use mouse-drag, place the following in your init file:
;; -either-
;; (keymap-global-set "<down-mouse-2>" #'mouse-drag-throw)
;; -or-
;; (keymap-global-set "<down-mouse-2>" #'mouse-drag-drag)
;;
;;
;;
;; Options:
;;
;; - reverse the throw-scroll direction with \\[mouse-throw-with-scroll-bar]
;; - work around a bug with \\[mouse-extras-work-around-drag-bug]
;; - auto-enable horizontal scrolling with
;; \\[mouse-drag-electric-col-scrolling]
;;
;;
;; History and related work:
;;
;; One-click copying and moving was inspired by lemacs-19.8.
;; Throw-scrolling was inspired by MacPaint's ``hand'' and by Tk's
;; mouse-2 scrolling. The package mouse-scroll.el by Tom Wurgler
;; <twurgler@goodyear.com> is similar to mouse-drag-throw, but
;; doesn't pass clicks through.
;;
;; Originally mouse-drag was part of a larger package.
;; As of 11 July 96 the scrolling functions were split out
;; in preparation for incorporation into (the future) emacs-19.32.
;;
;; Thanks:
;;
;; Thanks to Kai Grossjohann
;; <grossjoh@dusty.informatik.uni-dortmund.de> for reporting bugs, to
;; Tom Wurgler <twurgler@goodyear.com> for reporting bugs and
;; suggesting fixes, and to Joel Graber <jgraber@ti.com> for
;; prompting me to do drag-scrolling and for an initial
;; implementation of horizontal drag-scrolling.
;;
;; -johnh@isi.edu, 11-Jul-96
;;
;;
;; What's new with mouse-drag 2.24?
;;
;; - mouse-drag-electric-col-scrolling (default: on)
;; auto-enables horizontal scrolling when clicks on wrapped
;; lines occur
;; TODO:
;; - For mouse-drag-throw, we should try and place some visual indicator
;; of the original mouse position (like Firefox does).
;;; Code:
;;
;; scrolling code
;;
(defun mouse-drag-safe-scroll (row-delta &optional col-delta)
"Scroll down ROW-DELTA lines and right COL-DELTA, ignoring buffer edge errors.
Keep the cursor on the screen as needed."
(let ((scroll-preserve-screen-position nil))
(if (and row-delta
(/= 0 row-delta))
(condition-case nil ;; catch and ignore movement errors
(scroll-down row-delta)
(beginning-of-buffer (message "Beginning of buffer"))
(end-of-buffer (message "End of buffer"))))
(if (and col-delta
(/= 0 col-delta))
(progn
(scroll-right col-delta)
;; Make sure that the point stays on the visible screen
;; (if truncation-lines in set).
;; This code mimics the behavior we automatically get
;; when doing vertical scrolling.
;; Problem identified and a fix suggested by Tom Wurgler.
(cond
((< (current-column) (window-hscroll))
(move-to-column (window-hscroll))) ; make on left column
((> (- (current-column) (window-hscroll) (window-width) -2) 0)
(move-to-column (+ (window-width) (window-hscroll) -3))))))))