Refactor uses of scroll_margin to a function

Its effective range needs to be clamped between 0 and (window height /
4), so it's better to have this constraint in a single place.

* src/window.c (window_scroll_margin): New function.
(window_scroll_pixel_based, window_scroll_line_based):
(Frecenter, Fmove_to_window_line):
* src/xdisp.c (try_scrolling, try_cursor_movement):
(redisplay_window, try_window, try_window_id): Use it.
This commit is contained in:
Noam Postavsky 2016-08-28 16:38:04 -04:00
parent 53c16c75a5
commit d17e92da06
3 changed files with 39 additions and 74 deletions

View file

@ -4790,6 +4790,29 @@ window_scroll (Lisp_Object window, EMACS_INT n, bool whole, bool noerror)
XWINDOW (window)->window_end_valid = false;
}
/* Compute scroll margin for WINDOW.
We scroll when point is within this distance from the top or bottom
of the window. The result is measured in lines or in pixels
depending on the second parameter. */
int
window_scroll_margin (struct window *window, enum margin_unit unit)
{
if (scroll_margin > 0)
{
int frame_line_height = default_line_pixel_height (window);
int window_total_lines
= window->total_lines * WINDOW_FRAME_LINE_HEIGHT (window)
/ frame_line_height;
int margin = min (scroll_margin, window_total_lines / 4);
if (unit == MARGIN_IN_PIXELS)
return margin * frame_line_height;
else
return margin;
}
else
return 0;
}
/* Implementation of window_scroll that works based on pixel line
heights. See the comment of window_scroll for parameter
@ -4806,7 +4829,6 @@ window_scroll_pixel_based (Lisp_Object window, int n, bool whole, bool noerror)
bool vscrolled = false;
int x, y, rtop, rbot, rowh, vpos;
void *itdata = NULL;
int window_total_lines;
int frame_line_height = default_line_pixel_height (w);
bool adjust_old_pointm = !NILP (Fequal (Fwindow_point (window),
Fwindow_old_point (window)));
@ -5062,12 +5084,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, bool whole, bool noerror)
/* Move PT out of scroll margins.
This code wants current_y to be zero at the window start position
even if there is a header line. */
window_total_lines
= w->total_lines * WINDOW_FRAME_LINE_HEIGHT (w) / frame_line_height;
this_scroll_margin = max (0, scroll_margin);
this_scroll_margin
= min (this_scroll_margin, window_total_lines / 4);
this_scroll_margin *= frame_line_height;
this_scroll_margin = window_scroll_margin (w, MARGIN_IN_PIXELS);
if (n > 0)
{
@ -5290,9 +5307,7 @@ window_scroll_line_based (Lisp_Object window, int n, bool whole, bool noerror)
if (pos < ZV)
{
/* Don't use a scroll margin that is negative or too large. */
int this_scroll_margin =
max (0, min (scroll_margin, w->total_lines / 4));
int this_scroll_margin = window_scroll_margin (w, MARGIN_IN_LINES);
set_marker_restricted_both (w->start, w->contents, pos, pos_byte);
w->start_at_line_beg = !NILP (bolp);
@ -5722,8 +5737,7 @@ and redisplay normally--don't erase and redraw the frame. */)
/* Do this after making BUF current
in case scroll_margin is buffer-local. */
this_scroll_margin
= max (0, min (scroll_margin, w->total_lines / 4));
this_scroll_margin = window_scroll_margin (w, MARGIN_IN_LINES);
/* Don't use redisplay code for initial frames, as the necessary
data structures might not be set up yet then. */
@ -5962,10 +5976,6 @@ from the top of the window. */)
lines = displayed_window_lines (w);
#if false
this_scroll_margin = max (0, min (scroll_margin, lines / 4));
#endif
if (NILP (arg))
XSETFASTINT (arg, lines / 2);
else
@ -5981,6 +5991,8 @@ from the top of the window. */)
it is probably better not to install it. However, it is here
inside #if false so as not to lose it. -- rms. */
this_scroll_margin = window_scroll_margin (w, MARGIN_IN_LINES);
/* Don't let it get into the margin at either top or bottom. */
iarg = max (iarg, this_scroll_margin);
iarg = min (iarg, lines - this_scroll_margin - 1);

View file

@ -1120,6 +1120,8 @@ extern bool compare_window_configurations (Lisp_Object, Lisp_Object, bool);
extern void mark_window_cursors_off (struct window *);
extern int window_internal_height (struct window *);
extern int window_body_width (struct window *w, bool);
enum margin_unit { MARGIN_IN_LINES, MARGIN_IN_PIXELS };
extern int window_scroll_margin (struct window *, enum margin_unit);
extern void temp_output_buffer_show (Lisp_Object);
extern void replace_buffer_in_windows (Lisp_Object);
extern void replace_buffer_in_windows_safely (Lisp_Object);

View file

@ -15316,7 +15316,6 @@ try_scrolling (Lisp_Object window, bool just_this_one_p,
bool temp_scroll_step, bool last_line_misfit)
{
struct window *w = XWINDOW (window);
struct frame *f = XFRAME (w->frame);
struct text_pos pos, startp;
struct it it;
int this_scroll_margin, scroll_max, rc, height;
@ -15327,8 +15326,6 @@ try_scrolling (Lisp_Object window, bool just_this_one_p,
/* We will never try scrolling more than this number of lines. */
int scroll_limit = SCROLL_LIMIT;
int frame_line_height = default_line_pixel_height (w);
int window_total_lines
= WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) / frame_line_height;
#ifdef GLYPH_DEBUG
debug_method_add (w, "try_scrolling");
@ -15336,13 +15333,7 @@ try_scrolling (Lisp_Object window, bool just_this_one_p,
SET_TEXT_POS_FROM_MARKER (startp, w->start);
/* Compute scroll margin height in pixels. We scroll when point is
within this distance from the top or bottom of the window. */
if (scroll_margin > 0)
this_scroll_margin = min (scroll_margin, window_total_lines / 4)
* frame_line_height;
else
this_scroll_margin = 0;
this_scroll_margin = window_scroll_margin (w, MARGIN_IN_PIXELS);
/* Force arg_scroll_conservatively to have a reasonable value, to
avoid scrolling too far away with slow move_it_* functions. Note
@ -15816,23 +15807,12 @@ try_cursor_movement (Lisp_Object window, struct text_pos startp,
{
int this_scroll_margin, top_scroll_margin;
struct glyph_row *row = NULL;
int frame_line_height = default_line_pixel_height (w);
int window_total_lines
= WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) / frame_line_height;
#ifdef GLYPH_DEBUG
debug_method_add (w, "cursor movement");
#endif
/* Scroll if point within this distance from the top or bottom
of the window. This is a pixel value. */
if (scroll_margin > 0)
{
this_scroll_margin = min (scroll_margin, window_total_lines / 4);
this_scroll_margin *= frame_line_height;
}
else
this_scroll_margin = 0;
this_scroll_margin = window_scroll_margin (w, MARGIN_IN_PIXELS);
top_scroll_margin = this_scroll_margin;
if (WINDOW_WANTS_HEADER_LINE_P (w))
@ -16280,7 +16260,7 @@ redisplay_window (Lisp_Object window, bool just_this_one_p)
int centering_position = -1;
bool last_line_misfit = false;
ptrdiff_t beg_unchanged, end_unchanged;
int frame_line_height;
int frame_line_height, margin;
bool use_desired_matrix;
void *itdata = NULL;
@ -16310,6 +16290,8 @@ redisplay_window (Lisp_Object window, bool just_this_one_p)
restart:
reconsider_clip_changes (w);
frame_line_height = default_line_pixel_height (w);
margin = window_scroll_margin (w, MARGIN_IN_LINES);
/* Has the mode line to be updated? */
update_mode_line = (w->update_mode_line
@ -16614,10 +16596,7 @@ redisplay_window (Lisp_Object window, bool just_this_one_p)
/* Some people insist on not letting point enter the scroll
margin, even though this part handles windows that didn't
scroll at all. */
int window_total_lines
= WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) / frame_line_height;
int margin = min (scroll_margin, window_total_lines / 4);
int pixel_margin = margin * frame_line_height;
int pixel_margin = margin * frame_line_height;
bool header_line = WINDOW_WANTS_HEADER_LINE_P (w);
/* Note: We add an extra FRAME_LINE_HEIGHT, because the loop
@ -16901,12 +16880,6 @@ redisplay_window (Lisp_Object window, bool just_this_one_p)
it.current_y = it.last_visible_y;
if (centering_position < 0)
{
int window_total_lines
= WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) / frame_line_height;
int margin
= scroll_margin > 0
? min (scroll_margin, window_total_lines / 4)
: 0;
ptrdiff_t margin_pos = CHARPOS (startp);
Lisp_Object aggressive;
bool scrolling_up;
@ -17150,10 +17123,6 @@ redisplay_window (Lisp_Object window, bool just_this_one_p)
{
int window_total_lines
= WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) / frame_line_height;
int margin =
scroll_margin > 0
? min (scroll_margin, window_total_lines / 4)
: 0;
bool move_down = w->cursor.vpos >= window_total_lines / 2;
move_it_by_lines (&it, move_down ? margin + 1 : -(margin + 1));
@ -17359,7 +17328,6 @@ try_window (Lisp_Object window, struct text_pos pos, int flags)
struct it it;
struct glyph_row *last_text_row = NULL;
struct frame *f = XFRAME (w->frame);
int frame_line_height = default_line_pixel_height (w);
/* Make POS the new window start. */
set_marker_both (w->start, Qnil, CHARPOS (pos), BYTEPOS (pos));
@ -17385,17 +17353,7 @@ try_window (Lisp_Object window, struct text_pos pos, int flags)
if ((flags & TRY_WINDOW_CHECK_MARGINS)
&& !MINI_WINDOW_P (w))
{
int this_scroll_margin;
int window_total_lines
= WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) / frame_line_height;
if (scroll_margin > 0)
{
this_scroll_margin = min (scroll_margin, window_total_lines / 4);
this_scroll_margin *= frame_line_height;
}
else
this_scroll_margin = 0;
int this_scroll_margin = window_scroll_margin (w, MARGIN_IN_PIXELS);
if ((w->cursor.y >= 0 /* not vscrolled */
&& w->cursor.y < this_scroll_margin
@ -18679,15 +18637,8 @@ try_window_id (struct window *w)
/* Don't let the cursor end in the scroll margins. */
{
int this_scroll_margin, cursor_height;
int frame_line_height = default_line_pixel_height (w);
int window_total_lines
= WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (it.f) / frame_line_height;
this_scroll_margin =
max (0, min (scroll_margin, window_total_lines / 4));
this_scroll_margin *= frame_line_height;
cursor_height = MATRIX_ROW (w->desired_matrix, w->cursor.vpos)->height;
int this_scroll_margin = window_scroll_margin (w, MARGIN_IN_PIXELS);
int cursor_height = MATRIX_ROW (w->desired_matrix, w->cursor.vpos)->height;
if ((w->cursor.y < this_scroll_margin
&& CHARPOS (start) > BEGV)