summaryrefslogtreecommitdiff
path: root/lisp/smooth-scrolling.el
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/smooth-scrolling.el')
-rw-r--r--lisp/smooth-scrolling.el327
1 files changed, 0 insertions, 327 deletions
diff --git a/lisp/smooth-scrolling.el b/lisp/smooth-scrolling.el
deleted file mode 100644
index 98df30e..0000000
--- a/lisp/smooth-scrolling.el
+++ /dev/null
@@ -1,327 +0,0 @@
-;;; smooth-scrolling.el --- Make emacs scroll smoothly
-;;
-;; Copyright (c) 2007-2016 Adam Spiers
-;;
-;; Filename: smooth-scrolling.el
-;; Description: Make emacs scroll smoothly
-;; Author: Adam Spiers <emacs-ss@adamspiers.org>
-;; Jeremy Bondeson <jbondeson@gmail.com>
-;; Ryan C. Thompson <rct+github@thompsonclan.org>
-;; Maintainer: Adam Spiers <emacs-ss@adamspiers.org>
-;; Homepage: http://github.com/aspiers/smooth-scrolling/
-;; Version: 2.0.0
-;; Keywords: convenience
-;; GitHub: http://github.com/aspiers/smooth-scrolling/
-
-;; This file is not part of GNU Emacs
-
-;;; License:
-;;
-;; This program 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 2
-;; of the License, or (at your option) any later version.
-;;
-;; This program 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 this program; if not, write to the Free Software
-;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-
-;;; Commentary:
-
-;; To interactively toggle the mode on / off:
-;;
-;; M-x smooth-scrolling-mode
-;;
-;; To make the mode permanent, put this in your .emacs:
-;;
-;; (require 'smooth-scrolling)
-;; (smooth-scrolling-mode 1)
-;;
-;; This package offers a global minor mode which make emacs scroll
-;; smoothly. It keeps the point away from the top and bottom of the
-;; current buffer's window in order to keep lines of context around
-;; the point visible as much as possible, whilst minimising the
-;; frequency of sudden scroll jumps which are visually confusing.
-;;
-;; This is a nice alternative to all the native `scroll-*` custom
-;; variables, which unfortunately cannot provide this functionality
-;; perfectly. For example, when using the built-in variables, clicking
-;; with the mouse in the margin will immediately scroll the window to
-;; maintain the margin, so the text that you clicked on will no longer be
-;; under the mouse. This can be disorienting. In contrast, this mode
-;; will not do any scrolling until you actually move up or down a line.
-;;
-;; Also, the built-in margin code does not interact well with small
-;; windows. If the margin is more than half the window height, you get
-;; some weird behavior, because the point is always hitting both the top
-;; and bottom margins. This package auto-adjusts the margin in each
-;; buffer to never exceed half the window height, so the top and bottom
-;; margins never overlap.
-
-;; See the README.md for more details.
-
-;;; Change Log:
-;; 27 Feb 2016 -- v2.0.0
-;; * Converted to global minor mode "smooth-scrolling-mode". This
-;; means that simply loading the file no longer enables smooth
-;; scrolling; you must also enable the mode.
-;; * Internal code restructuring that should improve some edge
-;; cases, but otherwise have no user-visible effects.
-;; 19 Dec 2013 -- v1.0.4
-;; * Disabled scrolling while a keyboard macro is executing in
-;; order to prevent a premature termination of the macro by
-;; the mode throwing an error such as "End of Buffer"
-;; 02 Jun 2013 -- v1.0.3
-;; * Fixed Issue #3 where bounds checking was not being performed
-;; prior to calls to 'count-lines' and 'count-screen-lines'
-;; functions.
-;; 14 Apr 2013 -- v1.0.2
-;; * Adam Spiers GitHub account now houses the canonical
-;; repository.
-;; 06 Dec 2011 -- v1.0.1
-;; * Altered structure to conform to package.el standards.
-;; * Restructured code to group settings changes
-;; * Set "redisplay-dont-pause" to true.
-;; ?? ??? 2007 -- v1.0.0
-;; * Original version from Adam Spiers
-
-;;; Code:
-
-;;;_ + internal variables
-(defvar smooth-scroll-orig-scroll-margin nil)
-
-;;;_ + defcustoms
-
-(defgroup smooth-scrolling nil
- "Make emacs scroll smoothly"
- :group 'convenience)
-
-;;;###autoload
-(define-minor-mode smooth-scrolling-mode
- "Make emacs scroll smoothly"
- :init-value nil
- :global t
- :group 'smooth-scrolling
- (if smooth-scrolling-mode
- (setq smooth-scroll-orig-scroll-margin scroll-margin
- scroll-margin 0)
- (setq scroll-margin smooth-scroll-orig-scroll-margin
- smooth-scroll-orig-scroll-margin nil)))
-
-;;;###autoload
-(defcustom smooth-scroll-margin 10
- "Number of lines of visible margin at the top and bottom of a window.
-If the point is within these margins, then scrolling will occur
-smoothly for `previous-line' at the top of the window, and for
-`next-line' at the bottom.
-
-This is very similar in its goal to `scroll-margin'. However, it
-is implemented by activating `smooth-scroll-down' and
-`smooth-scroll-up' advise via `defadvice' for `previous-line' and
-`next-line' respectively. As a result it avoids problems
-afflicting `scroll-margin', such as a sudden jump and unexpected
-highlighting of a region when the mouse is clicked in the margin.
-
-Scrolling only occurs when the point is closer to the window
-boundary it is heading for (top or bottom) than the middle of the
-window. This is to intelligently handle the case where the
-margins cover the whole buffer (e.g. `smooth-scroll-margin' set
-to 5 and `window-height' returning 10 or less).
-
-See also `smooth-scroll-strict-margins'."
- :type 'integer
- :group 'smooth-scrolling)
-
-;;;###autoload
-(defcustom smooth-scroll-strict-margins t
- "If true, the advice code supporting `smooth-scroll-margin'
-will use `count-screen-lines' to determine the number of
-*visible* lines between the point and the window top/bottom,
-rather than `count-lines' which obtains the number of actual
-newlines. This is because there might be extra newlines hidden
-by a mode such as folding-mode, outline-mode, org-mode etc., or
-fewer due to very long lines being displayed wrapped when
-`truncate-lines' is nil.
-
-However, using `count-screen-lines' can supposedly cause
-performance issues in buffers with extremely long lines. Setting
-`cache-long-line-scans' may be able to address this;
-alternatively you can set this variable to nil so that the advice
-code uses `count-lines', and put up with the fact that sometimes
-the point will be allowed to stray into the margin."
- :type 'boolean
- :group 'smooth-scrolling)
-
-;;;_ + helper functions
-(defmacro smooth-scroll-ignore-scroll-errors (&rest body)
- "Like `progn', but ignores beginning/end of line errors.
-
-If BODY encounters such an error, further evaluation is stopped
-and this form returns nil. Any other error is raised as normal."
- (declare (indent 0))
- `(condition-case err
- (progn ,@body)
- (end-of-buffer nil)
- (beginning-of-buffer nil)
- (error (signal (car err) (cdr err)))))
-
-(defun smooth-scroll-line-beginning-position ()
- "Return position at beginning of (logical/visual) line.
-
-If `smooth-scroll-strict-margins' is non-nil, this looks to the
-beginning of the visual line. Otherwise it uses the beginning of
-the logical line."
- (save-excursion
- ;; Cannot use `line-beginning-position' here because there is no
- ;; visual-line equivalent.
- (funcall (if smooth-scroll-strict-margins
- #'beginning-of-visual-line
- #'beginning-of-line))
- (point)))
-
-(defun smooth-scroll-count-lines (start end)
- "Return number of (logical/visual) lines between START and END.
-
-If `smooth-scroll-strict-margins' is non-nil, this counts visual
-lines. Otherwise it counts logical lines.
-
-If END is less than START, this returns zero, so it is important
-to pass them in order."
- (if (< end start)
- 0
- (funcall (if smooth-scroll-strict-margins
- #'count-screen-lines
- #'count-lines)
- start end)))
-
-(defun smooth-scroll-lines-above-point ()
- "Return the number of lines in window above point.
-
-This does not include the line that point is on."
- (smooth-scroll-count-lines (window-start)
- (smooth-scroll-line-beginning-position)))
-
-(defun smooth-scroll-lines-below-point ()
- "Return the number of lines in window above point.
-
-This does not include the line that point is on."
- ;; We don't rely on `window-end' because if we are scrolled near the
- ;; end of the buffer, it will only give the number of lines
- ;; remaining in the file, not the number of lines to the bottom of
- ;; the window.
- (- (window-height) 2 (smooth-scroll-lines-above-point)))
-
-(defun smooth-scroll-window-allowed-margin ()
- "Return the maximum allowed margin above or below point.
-
-This only matters for windows whose height is
-`smooth-scroll-margin' * 2 lines or less."
- ;; We subtract 1 for the modeline, which is counted in
- ;; `window-height', and one more for the line that point is on. Then
- ;; we divide by 2, rouding down.
- (/ (- (window-height) 2) 2))
-
-(defsubst window-is-at-bob-p ()
- "Returns non-nil if `(window-start)' is 1 (or less)."
- (<= (window-start) 1))
-
-;;;_ + main function
-(defun do-smooth-scroll ()
- "Ensure that point is not to close to window edges.
-
-This function scrolls the window until there are at least
-`smooth-scroll-margin' lines between the point and both the top
-and bottom of the window. If this is not possible because the
-window is too small, th window is scrolled such that the point is
-roughly centered within the window."
- (interactive)
- (when smooth-scrolling-mode
- (let* ((desired-margin
- ;; For short windows, we reduce `smooth-scroll-margin' to
- ;; half the window height minus 1.
- (min (smooth-scroll-window-allowed-margin)
- smooth-scroll-margin))
- (upper-margin (smooth-scroll-lines-above-point))
- (lower-margin (smooth-scroll-lines-below-point)))
- (smooth-scroll-ignore-scroll-errors
- (cond
- ((< upper-margin desired-margin)
- (save-excursion
- (dotimes (i (- desired-margin upper-margin))
- (scroll-down 1))))
- ((< lower-margin desired-margin)
- (save-excursion
- (dotimes (i (- desired-margin lower-margin))
- (scroll-up 1)))))))))
-
-;;;_ + advice setup
-
-;;;###autoload
-(defmacro enable-smooth-scroll-for-function (func)
- "Define advice on FUNC to do smooth scrolling.
-
-This adds after advice with name `smooth-scroll' to FUNC.
-
-Note that the advice will not have an effect unless
-`smooth-scrolling-mode' is enabled."
- `(defadvice ,func (after smooth-scroll activate)
- "Do smooth scrolling after command finishes.
-
-This advice only has an effect when `smooth-scrolling-mode' is
-enabled. See `smooth-scrolling-mode' for details. To remove this
-advice, use `disable-smooth-scroll-for-function'."
- (do-smooth-scroll)))
-
-(defmacro enable-smooth-scroll-for-function-conditionally (func cond)
- "Define advice on FUNC to do smooth scrolling conditionally.
-
-This adds after advice with name `smooth-scroll' to FUNC. The
-advice runs smooth scrolling if expression COND evaluates to
-true. COND is included within the advice and therefore has access
-to all of FUNC's arguments.
-
-Note that the advice will not have an effect unless
-`smooth-scrolling-mode' is enabled."
- (declare (indent 1))
- `(defadvice ,func (after smooth-scroll activate)
- ,(format "Do smooth scrolling conditionally after command finishes.
-
-Smooth sccrolling will only be performed if the following
-expression evaluates to true after the function has run:
-
-%s
-This advice only has an effect when `smooth-scrolling-mode' is
-enabled. See `smooth-scrolling-mode' for details. To remove this
-advice, use `disable-smooth-scroll-for-function'."
- (pp-to-string cond))
- (when ,cond
- (do-smooth-scroll))))
-
-(defmacro disable-smooth-scroll-for-function (func)
- "Delete smooth-scroll advice for FUNC."
- ;; This doesn't actually need to be a macro, but it is one for
- ;; consistency with the enabling macro. Errors are ignored in case
- ;; the advice has already been removed.
- `(ignore-errors
- (ad-remove-advice ',func 'after 'smooth-scroll)
- (ad-activate ',func)))
-
-(progn
- (enable-smooth-scroll-for-function previous-line)
- (enable-smooth-scroll-for-function next-line)
- (enable-smooth-scroll-for-function dired-previous-line)
- (enable-smooth-scroll-for-function dired-next-line)
- (enable-smooth-scroll-for-function isearch-repeat)
- (enable-smooth-scroll-for-function-conditionally scroll-up-command
- (not (window-is-at-bob-p)))
- (enable-smooth-scroll-for-function-conditionally scroll-down-command
- (not (window-is-at-bob-p))))
-
-;;;_ + provide
-(provide 'smooth-scrolling)
-;;; smooth-scrolling.el ends here