From e27a91cddc1a66c25e09d3929c5625637ec34a49 Mon Sep 17 00:00:00 2001 From: Noam Postavsky Date: Sun, 11 Sep 2016 11:09:57 -0400 Subject: [PATCH] Make limit on scroll-margin variable * src/xdisp.c (maximum-scroll-margin): New variable. * lisp/cus-start.el: Make it customizable. * etc/NEWS: Mention it. * doc/emacs/display.texi (Auto Scrolling): * doc/lispref/windows.texi (Textual Scrolling): Document it. * src/window.c (window_scroll_pixel_based): Use it instead of hardcoding division by 4 (Bug #5718). --- doc/emacs/display.texi | 12 ++++++++---- doc/lispref/windows.texi | 15 +++++++++++++++ etc/NEWS | 5 +++++ lisp/cus-start.el | 1 + src/window.c | 19 ++++++++++++++----- src/xdisp.c | 8 ++++++++ 6 files changed, 51 insertions(+), 9 deletions(-) diff --git a/doc/emacs/display.texi b/doc/emacs/display.texi index c6e990d9082..15c700892bc 100644 --- a/doc/emacs/display.texi +++ b/doc/emacs/display.texi @@ -285,13 +285,17 @@ multiple variables, the order of priority is: @code{scroll-up-aggressively} / @code{scroll-down-aggressively}. @vindex scroll-margin +@vindex maximum-scroll-margin The variable @code{scroll-margin} restricts how close point can come to the top or bottom of a window (even if aggressive scrolling specifies a fraction @var{f} that is larger than the window portion -between the top and the bottom margins). Its value is a number of screen -lines; if point comes within that many lines of the top or bottom of -the window, Emacs performs automatic scrolling. By default, -@code{scroll-margin} is 0. +between the top and the bottom margins). Its value is a number of +screen lines; if point comes within that many lines of the top or +bottom of the window, Emacs performs automatic scrolling. By default, +@code{scroll-margin} is 0. The effective margin size is limited to a +quarter of the window height by default, but this limit can be +increased up to half (or decreased down to zero) by customizing +@code{maximum-scroll-margin}. @node Horizontal Scrolling @section Horizontal Scrolling diff --git a/doc/lispref/windows.texi b/doc/lispref/windows.texi index 6f3de0c8a0e..affa28c9202 100644 --- a/doc/lispref/windows.texi +++ b/doc/lispref/windows.texi @@ -3924,6 +3924,21 @@ redisplay scrolls the text automatically (if possible) to move point out of the margin, closer to the center of the window. @end defopt +@defopt maximum-scroll-margin +This variable limits the effective value of @code{scroll-margin} to a +fraction of the current window line height. For example, if the +current window has 20 lines and @code{maximum-scroll-margin} is 0.1, +then the scroll margins will never be larger than 2 lines, no matter +how big @code{scroll-margin} is. + +@code{maximum-scroll-margin} itself has a maximum value of 0.5, which +allows setting margins large to keep the cursor at the middle line of +the window (or two middle lines if the window has an even number of +lines). If it's set to a larger value (or any value other than a +float between 0.0 and 0.5) then the default value of 0.25 will be used +instead. +@end defopt + @defopt scroll-conservatively This variable controls how scrolling is done automatically when point moves off the screen (or into the scroll margin). If the value is a diff --git a/etc/NEWS b/etc/NEWS index ddd40fa8535..617f39f9b4c 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -307,6 +307,11 @@ 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/lisp/cus-start.el b/lisp/cus-start.el index a790419b86f..51c43c7d21a 100644 --- a/lisp/cus-start.el +++ b/lisp/cus-start.el @@ -511,6 +511,7 @@ since it could result in memory overflow and make Emacs crash." (scroll-step windows integer) (scroll-conservatively windows integer) (scroll-margin windows integer) + (maximum-scroll-margin windows float "26.1") (hscroll-margin windows integer "22.1") (hscroll-step windows number "22.1") (truncate-partial-width-windows diff --git a/src/window.c b/src/window.c index 235c3c1ade8..ba03780f3df 100644 --- a/src/window.c +++ b/src/window.c @@ -4801,11 +4801,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 8a450b7a8a4..134ef6c6196 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -31520,6 +31520,14 @@ 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. 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). */); -- 2.39.5