diff options
| author | Eli Zaretskii | 2022-02-03 19:36:43 +0200 |
|---|---|---|
| committer | Eli Zaretskii | 2022-02-03 19:36:43 +0200 |
| commit | dcc97fec29785051d7d11a66beb5f44fbaae6289 (patch) | |
| tree | 5b3cc294b6c942f6fe5415c7d7d93b1e23e6ebbf | |
| parent | 37eef19fd608ca81acb40f974b8d7bbe7fc27127 (diff) | |
| download | emacs-dcc97fec29785051d7d11a66beb5f44fbaae6289.tar.gz emacs-dcc97fec29785051d7d11a66beb5f44fbaae6289.zip | |
Allow ensuring that a window's starting point is never invisible
* src/xdisp.c (syms_of_xdisp) <make-window-start-visible>: New
buffer-local variable.
(redisplay_window): If 'make-window-start-visible' is non-nil,
don't accept window-start position that is in invisible text or is
covered by a "replacing" 'display' property. (Bug#14582)
| -rw-r--r-- | src/xdisp.c | 52 |
1 files changed, 47 insertions, 5 deletions
diff --git a/src/xdisp.c b/src/xdisp.c index 381df490703..20b0d97b975 100644 --- a/src/xdisp.c +++ b/src/xdisp.c | |||
| @@ -19036,8 +19036,9 @@ redisplay_window (Lisp_Object window, bool just_this_one_p) | |||
| 19036 | force_start: | 19036 | force_start: |
| 19037 | 19037 | ||
| 19038 | /* Handle case where place to start displaying has been specified, | 19038 | /* Handle case where place to start displaying has been specified, |
| 19039 | unless the specified location is outside the accessible range. */ | 19039 | unless the specified location is outside the accessible range, or |
| 19040 | if (w->force_start) | 19040 | the buffer wants the window-start point to be always visible. */ |
| 19041 | if (w->force_start && !make_window_start_visible) | ||
| 19041 | { | 19042 | { |
| 19042 | /* We set this later on if we have to adjust point. */ | 19043 | /* We set this later on if we have to adjust point. */ |
| 19043 | int new_vpos = -1; | 19044 | int new_vpos = -1; |
| @@ -19227,6 +19228,8 @@ redisplay_window (Lisp_Object window, bool just_this_one_p) | |||
| 19227 | goto done; | 19228 | goto done; |
| 19228 | } | 19229 | } |
| 19229 | 19230 | ||
| 19231 | Lisp_Object iprop, dspec; | ||
| 19232 | struct text_pos ignored; | ||
| 19230 | /* Handle case where text has not changed, only point, and it has | 19233 | /* Handle case where text has not changed, only point, and it has |
| 19231 | not moved off the frame, and we are not retrying after hscroll. | 19234 | not moved off the frame, and we are not retrying after hscroll. |
| 19232 | (current_matrix_up_to_date_p is true when retrying.) */ | 19235 | (current_matrix_up_to_date_p is true when retrying.) */ |
| @@ -19248,10 +19251,28 @@ redisplay_window (Lisp_Object window, bool just_this_one_p) | |||
| 19248 | } | 19251 | } |
| 19249 | } | 19252 | } |
| 19250 | /* If current starting point was originally the beginning of a line | 19253 | /* If current starting point was originally the beginning of a line |
| 19251 | but no longer is, find a new starting point. */ | 19254 | but no longer is, or if the starting point is invisible but the |
| 19255 | buffer wants it always visible, find a new starting point. */ | ||
| 19252 | else if (w->start_at_line_beg | 19256 | else if (w->start_at_line_beg |
| 19253 | && !(CHARPOS (startp) <= BEGV | 19257 | && (!(CHARPOS (startp) <= BEGV |
| 19254 | || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n')) | 19258 | || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n') |
| 19259 | || (make_window_start_visible | ||
| 19260 | /* Is window-start in invisible text? */ | ||
| 19261 | && ((CHARPOS (startp) > BEGV | ||
| 19262 | && ((iprop = | ||
| 19263 | Fget_char_property | ||
| 19264 | (make_fixnum (CHARPOS (startp) - 1), Qinvisible, | ||
| 19265 | window)), | ||
| 19266 | TEXT_PROP_MEANS_INVISIBLE (iprop) != 0)) | ||
| 19267 | /* Is window-start covered by a replacing | ||
| 19268 | 'display' property? */ | ||
| 19269 | || (!NILP (dspec = | ||
| 19270 | Fget_char_property | ||
| 19271 | (make_fixnum (CHARPOS (startp)), Qdisplay, | ||
| 19272 | window)) | ||
| 19273 | && handle_display_spec (NULL, dspec, Qnil, Qnil, | ||
| 19274 | &ignored, CHARPOS (startp), | ||
| 19275 | FRAME_WINDOW_P (f)) > 0))))) | ||
| 19255 | { | 19276 | { |
| 19256 | #ifdef GLYPH_DEBUG | 19277 | #ifdef GLYPH_DEBUG |
| 19257 | debug_method_add (w, "recenter 1"); | 19278 | debug_method_add (w, "recenter 1"); |
| @@ -19327,6 +19348,21 @@ redisplay_window (Lisp_Object window, bool just_this_one_p) | |||
| 19327 | goto force_start; | 19348 | goto force_start; |
| 19328 | } | 19349 | } |
| 19329 | 19350 | ||
| 19351 | /* Don't use the same window-start if it is covered by a | ||
| 19352 | replacing 'display' property and the buffer requested the | ||
| 19353 | window-start to be always visible. */ | ||
| 19354 | if (make_window_start_visible | ||
| 19355 | && !NILP (dspec = Fget_char_property (make_fixnum (CHARPOS (startp)), | ||
| 19356 | Qdisplay, window)) | ||
| 19357 | && handle_display_spec (NULL, dspec, Qnil, Qnil, &ignored, | ||
| 19358 | CHARPOS (startp), FRAME_WINDOW_P (f)) > 0) | ||
| 19359 | { | ||
| 19360 | #ifdef GLYPH_DEBUG | ||
| 19361 | debug_method_add (w, "recenter 2"); | ||
| 19362 | #endif | ||
| 19363 | goto recenter; | ||
| 19364 | } | ||
| 19365 | |||
| 19330 | #ifdef GLYPH_DEBUG | 19366 | #ifdef GLYPH_DEBUG |
| 19331 | debug_method_add (w, "same window start"); | 19367 | debug_method_add (w, "same window start"); |
| 19332 | #endif | 19368 | #endif |
| @@ -35973,6 +36009,12 @@ window, nil if it's okay to leave the cursor partially-visible. */); | |||
| 35973 | Vmake_cursor_line_fully_visible = Qt; | 36009 | Vmake_cursor_line_fully_visible = Qt; |
| 35974 | DEFSYM (Qmake_cursor_line_fully_visible, "make-cursor-line-fully-visible"); | 36010 | DEFSYM (Qmake_cursor_line_fully_visible, "make-cursor-line-fully-visible"); |
| 35975 | 36011 | ||
| 36012 | DEFVAR_BOOL ("make-window-start-visible", make_window_start_visible, | ||
| 36013 | doc: /* Whether to ensure `window-start' position is never invisible. */); | ||
| 36014 | make_window_start_visible = false; | ||
| 36015 | DEFSYM (Qmake_window_start_visible, "make-window-start-visible"); | ||
| 36016 | Fmake_variable_buffer_local (Qmake_window_start_visible); | ||
| 36017 | |||
| 35976 | DEFSYM (Qclose_tab, "close-tab"); | 36018 | DEFSYM (Qclose_tab, "close-tab"); |
| 35977 | DEFVAR_LISP ("tab-bar-border", Vtab_bar_border, | 36019 | DEFVAR_LISP ("tab-bar-border", Vtab_bar_border, |
| 35978 | doc: /* Border below tab-bar in pixels. | 36020 | doc: /* Border below tab-bar in pixels. |