>From 0697341a9cdc1f9962a7b984e2a8ffe5150831f5 Mon Sep 17 00:00:00 2001 From: Noam Postavsky Date: Sun, 11 Sep 2016 11:09:57 -0400 Subject: [PATCH v1 3/3] [BROKEN] Make limit on scroll-margin variable [BROKEN]: The `scroll-down-command' doesn't stay in the middle of the window. * src/xdisp.c (maximum-scroll-margin): New variable. * src/window.c (window_scroll_pixel_based): Use it instead of hardcoding division by 4 (Bug #5718). * test/src/window-tests.el (window-test-scroll-margin-whole-window): Test it. --- src/window.c | 13 ++++++++++++- src/xdisp.c | 5 +++++ test/src/window-tests.el | 30 ++++++++++++++++++++++++++++++ 3 files changed, 47 insertions(+), 1 deletion(-) diff --git a/src/window.c b/src/window.c index dbda435..20a7f3a 100644 --- a/src/window.c +++ b/src/window.c @@ -4803,7 +4803,18 @@ window_scroll_margin (struct window *window, enum margin_unit unit) = (window->total_lines * WINDOW_FRAME_LINE_HEIGHT (window) - WINDOW_MODE_LINE_HEIGHT (window)) / frame_line_height; - int margin = min (scroll_margin, window_total_lines / 4); + + int margin, max_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); + } + max_margin = (int) (window_total_lines * ratio); + margin = max (0, scroll_margin); + margin = min (scroll_margin, max_margin); if (unit == MARGIN_IN_PIXELS) return margin * frame_line_height; else diff --git a/src/xdisp.c b/src/xdisp.c index 3602025..b22242a 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -31451,6 +31451,11 @@ Recenter the window whenever point gets within this many lines 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. */); + 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 88ded18..c6152c8 100644 --- a/test/src/window-tests.el +++ b/test/src/window-tests.el @@ -50,6 +50,7 @@ window-test-scrolling (should (= 1 (window-start))))) (defmacro window-with-test-buffer-window (&rest body) + (declare (debug t)) (let ((bufvar (make-symbol "buf"))) `(let ((,bufvar (get-buffer-create "*test*"))) (with-selected-window (display-buffer ,bufvar) @@ -84,3 +85,32 @@ window-with-test-buffer-window (max-margin (/ (- (window-height) mode-lines) 4))) (window-test-scrolling (+ max-margin 1) max-margin) (window-test-scrolling (+ max-margin 2) max-margin)))) + +(defun window-test--point-in-middle-of-window-p () + (= (count-lines (window-start) (window-point)) + (- (count-lines (window-point) (window-end)) 1 + (if (pos-visible-in-window-p (window-end)) 0 1)))) + +(ert-deftest window-test-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-with-test-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-test--point-in-middle-of-window-p)) + (call-interactively 'scroll-up-command) + (sit-for 0) + (should (window-test--point-in-middle-of-window-p)) + (call-interactively 'scroll-down-command) + (sit-for 0) + (should (window-test--point-in-middle-of-window-p))))) -- 2.9.3