diff options
| author | Eli Zaretskii | 2018-09-30 14:14:59 +0300 |
|---|---|---|
| committer | Eli Zaretskii | 2018-09-30 14:14:59 +0300 |
| commit | 8bd48212020ee206b782477ac32b918861bcaf08 (patch) | |
| tree | e0f3b1bb8ae2aac091da77e22b06809f5e4adada /src | |
| parent | 6217746dd64b43a2a2b3b66ab50cfbbfc984f36c (diff) | |
| download | emacs-8bd48212020ee206b782477ac32b918861bcaf08.tar.gz emacs-8bd48212020ee206b782477ac32b918861bcaf08.zip | |
Allow 'make-cursor-line-fully-visible' name a function
* src/xdisp.c (cursor_row_fully_visible_p): Handle the case of
make-cursor-line-fully-visible being a function. Accept a 3rd
argument; if non-zero, assume the caller already tested the
conditions for the cursor being fully-visible, and don't
recheck them. All callers changed.
(try_cursor_movement, try_window_id): Call
cursor_row_fully_visible_p instead of testing the value of
make-cursor-line-fully-visible directly.
(syms_of_xdisp) <make-cursor-line-fully-visible>: Update the
doc string. Define a symbol Qmake_cursor_line_fully_visible.
(Bug#32848)
* lisp/cus-start.el (standard): Update the Custom form.
* etc/NEWS: Mention the change in possible values of
'make-cursor-line-fully-visible'.
Diffstat (limited to 'src')
| -rw-r--r-- | src/xdisp.c | 69 |
1 files changed, 52 insertions, 17 deletions
diff --git a/src/xdisp.c b/src/xdisp.c index 93cd54a3240..d61d421f08a 100644 --- a/src/xdisp.c +++ b/src/xdisp.c | |||
| @@ -842,7 +842,7 @@ static Lisp_Object redisplay_window_1 (Lisp_Object); | |||
| 842 | static bool set_cursor_from_row (struct window *, struct glyph_row *, | 842 | static bool set_cursor_from_row (struct window *, struct glyph_row *, |
| 843 | struct glyph_matrix *, ptrdiff_t, ptrdiff_t, | 843 | struct glyph_matrix *, ptrdiff_t, ptrdiff_t, |
| 844 | int, int); | 844 | int, int); |
| 845 | static bool cursor_row_fully_visible_p (struct window *, bool, bool); | 845 | static bool cursor_row_fully_visible_p (struct window *, bool, bool, bool); |
| 846 | static bool update_menu_bar (struct frame *, bool, bool); | 846 | static bool update_menu_bar (struct frame *, bool, bool); |
| 847 | static bool try_window_reusing_current_matrix (struct window *); | 847 | static bool try_window_reusing_current_matrix (struct window *); |
| 848 | static int try_window_id (struct window *); | 848 | static int try_window_id (struct window *); |
| @@ -14346,7 +14346,7 @@ redisplay_internal (void) | |||
| 14346 | eassert (this_line_vpos == it.vpos); | 14346 | eassert (this_line_vpos == it.vpos); |
| 14347 | eassert (this_line_y == it.current_y); | 14347 | eassert (this_line_y == it.current_y); |
| 14348 | set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0); | 14348 | set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0); |
| 14349 | if (cursor_row_fully_visible_p (w, false, true)) | 14349 | if (cursor_row_fully_visible_p (w, false, true, false)) |
| 14350 | { | 14350 | { |
| 14351 | #ifdef GLYPH_DEBUG | 14351 | #ifdef GLYPH_DEBUG |
| 14352 | *w->desired_matrix->method = 0; | 14352 | *w->desired_matrix->method = 0; |
| @@ -15628,19 +15628,46 @@ run_window_scroll_functions (Lisp_Object window, struct text_pos startp) | |||
| 15628 | window's current glyph matrix; otherwise use the desired glyph | 15628 | window's current glyph matrix; otherwise use the desired glyph |
| 15629 | matrix. | 15629 | matrix. |
| 15630 | 15630 | ||
| 15631 | If JUST_TEST_USER_PREFERENCE_P, just test what the value of | ||
| 15632 | make-cursor-row-fully-visible requires, don't test the actual | ||
| 15633 | cursor position. The assumption is that in that case the caller | ||
| 15634 | performs the necessary testing of the cursor position. | ||
| 15635 | |||
| 15631 | A value of false means the caller should do scrolling | 15636 | A value of false means the caller should do scrolling |
| 15632 | as if point had gone off the screen. */ | 15637 | as if point had gone off the screen. */ |
| 15633 | 15638 | ||
| 15634 | static bool | 15639 | static bool |
| 15635 | cursor_row_fully_visible_p (struct window *w, bool force_p, | 15640 | cursor_row_fully_visible_p (struct window *w, bool force_p, |
| 15636 | bool current_matrix_p) | 15641 | bool current_matrix_p, |
| 15642 | bool just_test_user_preference_p) | ||
| 15637 | { | 15643 | { |
| 15638 | struct glyph_matrix *matrix; | 15644 | struct glyph_matrix *matrix; |
| 15639 | struct glyph_row *row; | 15645 | struct glyph_row *row; |
| 15640 | int window_height; | 15646 | int window_height; |
| 15647 | Lisp_Object mclfv_p = | ||
| 15648 | buffer_local_value (Qmake_cursor_line_fully_visible, w->contents); | ||
| 15641 | 15649 | ||
| 15642 | if (!make_cursor_line_fully_visible_p) | 15650 | /* If no local binding, use the global value. */ |
| 15651 | if (EQ (mclfv_p, Qunbound)) | ||
| 15652 | mclfv_p = Vmake_cursor_line_fully_visible; | ||
| 15653 | /* Follow mode sets the variable to a Lisp function in buffers that | ||
| 15654 | are under Follow mode. */ | ||
| 15655 | if (FUNCTIONP (mclfv_p)) | ||
| 15656 | { | ||
| 15657 | Lisp_Object window; | ||
| 15658 | XSETWINDOW (window, w); | ||
| 15659 | /* Implementation note: if the function we call here signals an | ||
| 15660 | error, we will NOT scroll when the cursor is partially-visible. */ | ||
| 15661 | Lisp_Object val = safe_call1 (mclfv_p, window); | ||
| 15662 | if (NILP (val)) | ||
| 15663 | return true; | ||
| 15664 | else if (just_test_user_preference_p) | ||
| 15665 | return false; | ||
| 15666 | } | ||
| 15667 | else if (NILP (mclfv_p)) | ||
| 15643 | return true; | 15668 | return true; |
| 15669 | else if (just_test_user_preference_p) | ||
| 15670 | return false; | ||
| 15644 | 15671 | ||
| 15645 | /* It's not always possible to find the cursor, e.g, when a window | 15672 | /* It's not always possible to find the cursor, e.g, when a window |
| 15646 | is full of overlay strings. Don't do anything in that case. */ | 15673 | is full of overlay strings. Don't do anything in that case. */ |
| @@ -16002,7 +16029,7 @@ try_scrolling (Lisp_Object window, bool just_this_one_p, | |||
| 16002 | /* If cursor ends up on a partially visible line, | 16029 | /* If cursor ends up on a partially visible line, |
| 16003 | treat that as being off the bottom of the screen. */ | 16030 | treat that as being off the bottom of the screen. */ |
| 16004 | if (! cursor_row_fully_visible_p (w, extra_scroll_margin_lines <= 1, | 16031 | if (! cursor_row_fully_visible_p (w, extra_scroll_margin_lines <= 1, |
| 16005 | false) | 16032 | false, false) |
| 16006 | /* It's possible that the cursor is on the first line of the | 16033 | /* It's possible that the cursor is on the first line of the |
| 16007 | buffer, which is partially obscured due to a vscroll | 16034 | buffer, which is partially obscured due to a vscroll |
| 16008 | (Bug#7537). In that case, avoid looping forever. */ | 16035 | (Bug#7537). In that case, avoid looping forever. */ |
| @@ -16367,7 +16394,7 @@ try_cursor_movement (Lisp_Object window, struct text_pos startp, | |||
| 16367 | /* Make sure this isn't a header line by any chance, since | 16394 | /* Make sure this isn't a header line by any chance, since |
| 16368 | then MATRIX_ROW_PARTIALLY_VISIBLE_P might yield true. */ | 16395 | then MATRIX_ROW_PARTIALLY_VISIBLE_P might yield true. */ |
| 16369 | && !row->mode_line_p | 16396 | && !row->mode_line_p |
| 16370 | && make_cursor_line_fully_visible_p) | 16397 | && !cursor_row_fully_visible_p (w, true, true, true)) |
| 16371 | { | 16398 | { |
| 16372 | if (PT == MATRIX_ROW_END_CHARPOS (row) | 16399 | if (PT == MATRIX_ROW_END_CHARPOS (row) |
| 16373 | && !row->ends_at_zv_p | 16400 | && !row->ends_at_zv_p |
| @@ -16385,7 +16412,7 @@ try_cursor_movement (Lisp_Object window, struct text_pos startp, | |||
| 16385 | else | 16412 | else |
| 16386 | { | 16413 | { |
| 16387 | set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0); | 16414 | set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0); |
| 16388 | if (!cursor_row_fully_visible_p (w, false, true)) | 16415 | if (!cursor_row_fully_visible_p (w, false, true, false)) |
| 16389 | rc = CURSOR_MOVEMENT_MUST_SCROLL; | 16416 | rc = CURSOR_MOVEMENT_MUST_SCROLL; |
| 16390 | else | 16417 | else |
| 16391 | rc = CURSOR_MOVEMENT_SUCCESS; | 16418 | rc = CURSOR_MOVEMENT_SUCCESS; |
| @@ -16964,7 +16991,7 @@ redisplay_window (Lisp_Object window, bool just_this_one_p) | |||
| 16964 | new_vpos = window_box_height (w) / 2; | 16991 | new_vpos = window_box_height (w) / 2; |
| 16965 | } | 16992 | } |
| 16966 | 16993 | ||
| 16967 | if (!cursor_row_fully_visible_p (w, false, false)) | 16994 | if (!cursor_row_fully_visible_p (w, false, false, false)) |
| 16968 | { | 16995 | { |
| 16969 | /* Point does appear, but on a line partly visible at end of window. | 16996 | /* Point does appear, but on a line partly visible at end of window. |
| 16970 | Move it back to a fully-visible line. */ | 16997 | Move it back to a fully-visible line. */ |
| @@ -17059,7 +17086,8 @@ redisplay_window (Lisp_Object window, bool just_this_one_p) | |||
| 17059 | goto need_larger_matrices; | 17086 | goto need_larger_matrices; |
| 17060 | } | 17087 | } |
| 17061 | } | 17088 | } |
| 17062 | if (w->cursor.vpos < 0 || !cursor_row_fully_visible_p (w, false, false)) | 17089 | if (w->cursor.vpos < 0 |
| 17090 | || !cursor_row_fully_visible_p (w, false, false, false)) | ||
| 17063 | { | 17091 | { |
| 17064 | clear_glyph_matrix (w->desired_matrix); | 17092 | clear_glyph_matrix (w->desired_matrix); |
| 17065 | goto try_to_scroll; | 17093 | goto try_to_scroll; |
| @@ -17206,7 +17234,7 @@ redisplay_window (Lisp_Object window, bool just_this_one_p) | |||
| 17206 | /* Forget any recorded base line for line number display. */ | 17234 | /* Forget any recorded base line for line number display. */ |
| 17207 | w->base_line_number = 0; | 17235 | w->base_line_number = 0; |
| 17208 | 17236 | ||
| 17209 | if (!cursor_row_fully_visible_p (w, true, false)) | 17237 | if (!cursor_row_fully_visible_p (w, true, false, false)) |
| 17210 | { | 17238 | { |
| 17211 | clear_glyph_matrix (w->desired_matrix); | 17239 | clear_glyph_matrix (w->desired_matrix); |
| 17212 | last_line_misfit = true; | 17240 | last_line_misfit = true; |
| @@ -17502,7 +17530,7 @@ redisplay_window (Lisp_Object window, bool just_this_one_p) | |||
| 17502 | set_cursor_from_row (w, row, matrix, 0, 0, 0, 0); | 17530 | set_cursor_from_row (w, row, matrix, 0, 0, 0, 0); |
| 17503 | } | 17531 | } |
| 17504 | 17532 | ||
| 17505 | if (!cursor_row_fully_visible_p (w, false, false)) | 17533 | if (!cursor_row_fully_visible_p (w, false, false, false)) |
| 17506 | { | 17534 | { |
| 17507 | /* If vscroll is enabled, disable it and try again. */ | 17535 | /* If vscroll is enabled, disable it and try again. */ |
| 17508 | if (w->vscroll) | 17536 | if (w->vscroll) |
| @@ -19068,9 +19096,10 @@ try_window_id (struct window *w) | |||
| 19068 | && CHARPOS (start) > BEGV) | 19096 | && CHARPOS (start) > BEGV) |
| 19069 | /* Old redisplay didn't take scroll margin into account at the bottom, | 19097 | /* Old redisplay didn't take scroll margin into account at the bottom, |
| 19070 | but then global-hl-line-mode doesn't scroll. KFS 2004-06-14 */ | 19098 | but then global-hl-line-mode doesn't scroll. KFS 2004-06-14 */ |
| 19071 | || (w->cursor.y + (make_cursor_line_fully_visible_p | 19099 | || (w->cursor.y |
| 19072 | ? cursor_height + this_scroll_margin | 19100 | + (cursor_row_fully_visible_p (w, false, true, true) |
| 19073 | : 1)) > it.last_visible_y) | 19101 | ? 1 |
| 19102 | : cursor_height + this_scroll_margin)) > it.last_visible_y) | ||
| 19074 | { | 19103 | { |
| 19075 | w->cursor.vpos = -1; | 19104 | w->cursor.vpos = -1; |
| 19076 | clear_glyph_matrix (w->desired_matrix); | 19105 | clear_glyph_matrix (w->desired_matrix); |
| @@ -32903,9 +32932,15 @@ automatically; to decrease the tool-bar height, use \\[recenter]. */); | |||
| 32903 | doc: /* Non-nil means raise tool-bar buttons when the mouse moves over them. */); | 32932 | doc: /* Non-nil means raise tool-bar buttons when the mouse moves over them. */); |
| 32904 | auto_raise_tool_bar_buttons_p = true; | 32933 | auto_raise_tool_bar_buttons_p = true; |
| 32905 | 32934 | ||
| 32906 | DEFVAR_BOOL ("make-cursor-line-fully-visible", make_cursor_line_fully_visible_p, | 32935 | DEFVAR_LISP ("make-cursor-line-fully-visible", Vmake_cursor_line_fully_visible, |
| 32907 | doc: /* Non-nil means to scroll (recenter) cursor line if it is not fully visible. */); | 32936 | doc: /* Whether to scroll the window if the cursor line is not fully visible. |
| 32908 | make_cursor_line_fully_visible_p = true; | 32937 | If the value is non-nil, Emacs scrolls or recenters the window to make |
| 32938 | the cursor line fully visible. The value could also be a function, which | ||
| 32939 | is called with a single argument, the window to be scrolled, and should | ||
| 32940 | return non-nil if the partially-visible cursor requires scrolling the | ||
| 32941 | window, nil if it's okay to leave the cursor partially-visible. */); | ||
| 32942 | Vmake_cursor_line_fully_visible = Qt; | ||
| 32943 | DEFSYM (Qmake_cursor_line_fully_visible, "make-cursor-line-fully-visible"); | ||
| 32909 | 32944 | ||
| 32910 | DEFVAR_LISP ("tool-bar-border", Vtool_bar_border, | 32945 | DEFVAR_LISP ("tool-bar-border", Vtool_bar_border, |
| 32911 | doc: /* Border below tool-bar in pixels. | 32946 | doc: /* Border below tool-bar in pixels. |