emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

master dcc97fec29: Allow ensuring that a window's starting point is neve


From: Eli Zaretskii
Subject: master dcc97fec29: Allow ensuring that a window's starting point is never invisible
Date: Thu, 3 Feb 2022 12:38:19 -0500 (EST)

branch: master
commit dcc97fec29785051d7d11a66beb5f44fbaae6289
Author: Eli Zaretskii <eliz@gnu.org>
Commit: Eli Zaretskii <eliz@gnu.org>

    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)
---
 src/xdisp.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 47 insertions(+), 5 deletions(-)

diff --git a/src/xdisp.c b/src/xdisp.c
index 381df49070..20b0d97b97 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -19036,8 +19036,9 @@ redisplay_window (Lisp_Object window, bool 
just_this_one_p)
  force_start:
 
   /* Handle case where place to start displaying has been specified,
-     unless the specified location is outside the accessible range.  */
-  if (w->force_start)
+     unless the specified location is outside the accessible range, or
+     the buffer wants the window-start point to be always visible.  */
+  if (w->force_start && !make_window_start_visible)
     {
       /* We set this later on if we have to adjust point.  */
       int new_vpos = -1;
@@ -19227,6 +19228,8 @@ redisplay_window (Lisp_Object window, bool 
just_this_one_p)
       goto done;
     }
 
+  Lisp_Object iprop, dspec;
+  struct text_pos ignored;
   /* Handle case where text has not changed, only point, and it has
      not moved off the frame, and we are not retrying after hscroll.
      (current_matrix_up_to_date_p is true when retrying.)  */
@@ -19248,10 +19251,28 @@ redisplay_window (Lisp_Object window, bool 
just_this_one_p)
        }
     }
   /* If current starting point was originally the beginning of a line
-     but no longer is, find a new starting point.  */
+     but no longer is, or if the starting point is invisible but the
+     buffer wants it always visible, find a new starting point.  */
   else if (w->start_at_line_beg
-          && !(CHARPOS (startp) <= BEGV
-               || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n'))
+          && (!(CHARPOS (startp) <= BEGV
+                || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n')
+              || (make_window_start_visible
+                  /* Is window-start in invisible text?  */
+                  && ((CHARPOS (startp) > BEGV
+                       && ((iprop =
+                            Fget_char_property
+                            (make_fixnum (CHARPOS (startp) - 1), Qinvisible,
+                             window)),
+                           TEXT_PROP_MEANS_INVISIBLE (iprop) != 0))
+                      /* Is window-start covered by a replacing
+                         'display' property?  */
+                      || (!NILP (dspec =
+                                 Fget_char_property
+                                 (make_fixnum (CHARPOS (startp)), Qdisplay,
+                                  window))
+                          && handle_display_spec (NULL, dspec, Qnil, Qnil,
+                                                  &ignored, CHARPOS (startp),
+                                                  FRAME_WINDOW_P (f)) > 0)))))
     {
 #ifdef GLYPH_DEBUG
       debug_method_add (w, "recenter 1");
@@ -19327,6 +19348,21 @@ redisplay_window (Lisp_Object window, bool 
just_this_one_p)
          goto force_start;
        }
 
+      /* Don't use the same window-start if it is covered by a
+        replacing 'display' property and the buffer requested the
+        window-start to be always visible.  */
+      if (make_window_start_visible
+         && !NILP (dspec = Fget_char_property (make_fixnum (CHARPOS (startp)),
+                                               Qdisplay, window))
+         && handle_display_spec (NULL, dspec, Qnil, Qnil, &ignored,
+                                 CHARPOS (startp), FRAME_WINDOW_P (f)) > 0)
+       {
+#ifdef GLYPH_DEBUG
+         debug_method_add (w, "recenter 2");
+#endif
+         goto recenter;
+       }
+
 #ifdef GLYPH_DEBUG
       debug_method_add (w, "same window start");
 #endif
@@ -35973,6 +36009,12 @@ window, nil if it's okay to leave the cursor 
partially-visible.  */);
   Vmake_cursor_line_fully_visible = Qt;
   DEFSYM (Qmake_cursor_line_fully_visible, "make-cursor-line-fully-visible");
 
+  DEFVAR_BOOL ("make-window-start-visible", make_window_start_visible,
+    doc: /* Whether to ensure `window-start' position is never invisible.  */);
+  make_window_start_visible = false;
+  DEFSYM (Qmake_window_start_visible, "make-window-start-visible");
+  Fmake_variable_buffer_local (Qmake_window_start_visible);
+
   DEFSYM (Qclose_tab, "close-tab");
   DEFVAR_LISP ("tab-bar-border", Vtab_bar_border,
     doc: /* Border below tab-bar in pixels.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]