>From 87ad96cc13ca45eb5c78e3773cfb1458001f9d83 Mon Sep 17 00:00:00 2001 From: Noam Postavsky Date: Sun, 11 Sep 2016 11:09:57 -0400 Subject: [PATCH v2 3/3] Make limit on scroll-margin variable TODO: `scroll-down-command' doesn't stay in the middle of the window. * src/xdisp.c (maximum-scroll-margin): New variable. * etc/NEWS: Mention it. * src/window.c (window_scroll_pixel_based): Use it instead of hardcoding division by 4 (Bug #5718). * test/src/window-tests.el (window-tests-scroll-margin-whole-window): (window-tests--point-in-middle-of-window-p): New test and helper function. --- etc/NEWS | 4 ++++ src/window.c | 19 ++++++++++++++----- src/xdisp.c | 8 ++++++++ test/src/window-tests.el | 27 +++++++++++++++++++++++++++ 4 files changed, 53 insertions(+), 5 deletions(-) diff --git a/etc/NEWS b/etc/NEWS index d91204b..f4fa98a 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -298,6 +298,10 @@ local part of a remote file name. Thus, if you have a directory named "/~" on the remote host "foo", you can prevent it from being substituted by a home directory by writing it as "/foo:/:/~/file". +** The new variable 'maximum-scroll-margin' allows having effective +settings of 'scroll-margin' up to half the window size, instead of +always restricting the margin to a quarter of the window. + * Editing Changes in Emacs 26.1 diff --git a/src/window.c b/src/window.c index b710333..f664597 100644 --- a/src/window.c +++ b/src/window.c @@ -4802,11 +4802,20 @@ window_scroll_margin (struct window *window, enum margin_unit unit) { int frame_line_height = default_line_pixel_height (window); int window_lines = window_box_height (window) / frame_line_height; - int margin = min (scroll_margin, window_lines / 4); - if (unit == MARGIN_IN_PIXELS) - return margin * frame_line_height; - else - return margin; + + double ratio = 0.25; + if (FLOATP (Vmaximum_scroll_margin)) + { + ratio = XFLOAT_DATA (Vmaximum_scroll_margin); + ratio = max (0.0, ratio); + ratio = min (ratio, 0.5); + } + int max_margin = min ((window_lines - 1)/2, + (int) (window_lines * ratio)); + int margin = clip_to_bounds (0, scroll_margin, max_margin); + return (unit == MARGIN_IN_PIXELS) + ? margin * frame_line_height + : margin; } else return 0; diff --git a/src/xdisp.c b/src/xdisp.c index 0fd2a7c..55bb34a 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -31520,6 +31520,14 @@ syms_of_xdisp (void) of the top or bottom of the window. */); scroll_margin = 0; + DEFVAR_LISP ("maximum-scroll-margin", Vmaximum_scroll_margin, + doc: /* Maximum effective value of `scroll-margin'. +Given as a fraction of the current window's lines. The value should +be a floating point number between 0.0 and 0.5. The effective maximum +is limited to (/ (1- window-lines) 2). Non-float values for this +variable are ignored and the default 0.25 is used instead. */); + Vmaximum_scroll_margin = make_float (0.25); + DEFVAR_LISP ("display-pixels-per-inch", Vdisplay_pixels_per_inch, doc: /* Pixels per inch value for non-window system displays. Value is a number or a cons (WIDTH-DPI . HEIGHT-DPI). */); diff --git a/test/src/window-tests.el b/test/src/window-tests.el index f5cca73..1dcebef 100644 --- a/test/src/window-tests.el +++ b/test/src/window-tests.el @@ -81,4 +81,31 @@ window-tests-with-buffer-window (window-tests-scrolling (+ max-margin 1) max-margin) (window-tests-scrolling (+ max-margin 2) max-margin)))) +(defun window-tests--point-in-middle-of-window-p () + (= (count-lines (window-start) (window-point)) + (/ (1- (window-text-height)) 2))) + +(ert-deftest window-tests-scroll-margin-whole-window () + "Test `maximum-scroll-margin' at 0.5. +With a high `scroll-margin', this should keep cursor in the +middle of the window." + (skip-unless (not noninteractive)) + (let ((maximum-scroll-margin 0.5) + (scroll-margin 100)) + (window-tests-with-buffer-window + (set-window-text-height nil 7) + (erase-buffer) + (insert (mapconcat #'number-to-string + (number-sequence 1 200) "\n")) + (goto-char 1) + (sit-for 0) + (call-interactively 'scroll-up-command) + (sit-for 0) + (should (window-tests--point-in-middle-of-window-p)) + (call-interactively 'scroll-up-command) + (sit-for 0) + (should (window-tests--point-in-middle-of-window-p)) + (call-interactively 'scroll-down-command) + (sit-for 0) + (should (window-tests--point-in-middle-of-window-p))))) ;;; window-tests.el ends here -- 2.9.3