emacs-diffs
[Top][All Lists]
Advanced

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

master 5a79bb2aed: Merge branch 'feature/long-lines-improvements'


From: Gregory Heytings
Subject: master 5a79bb2aed: Merge branch 'feature/long-lines-improvements'
Date: Thu, 4 Aug 2022 15:20:40 -0400 (EDT)

branch: master
commit 5a79bb2aed617f5b0ecf8e20ec958682e72fcc75
Merge: b335e1a046 a95c5baa6a
Author: Gregory Heytings <gregory@heytings.org>
Commit: Gregory Heytings <gregory@heytings.org>

    Merge branch 'feature/long-lines-improvements'
---
 src/buffer.c     |  5 ++++-
 src/composite.c  | 20 +++++++++++++-------
 src/dispextern.h |  2 ++
 src/keyboard.c   | 54 +++++++++++++++++++++++++++++++++++++++++++++---------
 src/lisp.h       |  1 +
 src/xdisp.c      | 36 +++++++++++++++++++++++-------------
 6 files changed, 88 insertions(+), 30 deletions(-)

diff --git a/src/buffer.c b/src/buffer.c
index a07194aef7..e5601af505 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -6431,12 +6431,15 @@ will run for `clone-indirect-buffer' calls as well.  
*/);
 
   DEFVAR_LISP ("long-line-threshold", Vlong_line_threshold,
     doc: /* Line length above which to use redisplay shortcuts.
+
 The value should be a positive integer or nil.
 If the value is an integer, shortcuts in the display code intended
 to speed up redisplay for long lines will automatically be enabled
 in buffers which contain one or more lines whose length is above
 this threshold.
-If nil, these display shortcuts will always remain disabled.  */);
+If nil, these display shortcuts will always remain disabled.
+
+There is no reason to change that value except for debugging purposes.  */);
   XSETFASTINT (Vlong_line_threshold, 10000);
 
   defsubr (&Sbuffer_live_p);
diff --git a/src/composite.c b/src/composite.c
index 0f90b92a78..a13839939b 100644
--- a/src/composite.c
+++ b/src/composite.c
@@ -1021,7 +1021,11 @@ composition_compute_stop_pos (struct composition_it 
*cmp_it, ptrdiff_t charpos,
          /* But we don't know where to stop the searching.  */
          endpos = NILP (string) ? BEGV - 1 : -1;
          /* Usually we don't reach ENDPOS because we stop searching
-            at an uncomposable character (NL, LRE, etc).  */
+            at an uncomposable character (NL, LRE, etc).  In buffers
+            with long lines, however, NL might be far away, so
+            pretend that the buffer is smaller.  */
+         if (current_buffer->long_line_optimizations_p)
+           endpos = get_closer_narrowed_begv (cmp_it->parent_it->w, charpos);
        }
     }
   cmp_it->id = -1;
@@ -1580,7 +1584,6 @@ find_automatic_composition (ptrdiff_t pos, ptrdiff_t 
limit, ptrdiff_t backlim,
   Lisp_Object window;
   struct window *w;
   bool need_adjustment = 0;
-  ptrdiff_t narrowed_begv;
 
   window = Fget_buffer_window (Fcurrent_buffer (), Qnil);
   if (NILP (window))
@@ -1597,11 +1600,14 @@ find_automatic_composition (ptrdiff_t pos, ptrdiff_t 
limit, ptrdiff_t backlim,
        }
       else
        head = backlim;
-      /* In buffers with very long lines, this function becomes very
-        slow.  Pretend that the buffer is narrowed to make it fast.  */
-      narrowed_begv = get_narrowed_begv (w, window_point (w));
-      if (narrowed_begv && pos > narrowed_begv)
-       head = narrowed_begv;
+      if (current_buffer->long_line_optimizations_p)
+       {
+         /* In buffers with very long lines, this function becomes very
+            slow.  Pretend that the buffer is narrowed to make it fast.  */
+         ptrdiff_t begv = get_closer_narrowed_begv (w, window_point (w));
+         if (pos > begv)
+           head = begv;
+       }
       tail = ZV;
       stop = GPT;
       cur.pos_byte = CHAR_TO_BYTE (cur.pos);
diff --git a/src/dispextern.h b/src/dispextern.h
index 037e02ff58..12ba927261 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -2287,6 +2287,8 @@ struct composition_it
      reverse order, and thus the grapheme clusters must be rendered
      from the last to the first.  */
   bool reversed_p;
+  /* Parent iterator. */
+  struct it *parent_it;
 
   /** The following members contain information about the current
       grapheme cluster.  */
diff --git a/src/keyboard.c b/src/keyboard.c
index 2863058d63..02e02448ff 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -1295,7 +1295,8 @@ command_loop_1 (void)
       /* Note that the value cell will never directly contain nil
         if the symbol is a local variable.  */
       if (!NILP (Vpost_command_hook) && !NILP (Vrun_hooks))
-       safe_run_hooks (Qpost_command_hook);
+       safe_run_hooks_maybe_narrowed (Qpost_command_hook,
+                                      XWINDOW (selected_window));
 
       /* If displaying a message, resize the echo area window to fit
         that message's size exactly.  */
@@ -1461,7 +1462,9 @@ command_loop_1 (void)
       }
       Vthis_command = cmd;
       Vreal_this_command = cmd;
-      safe_run_hooks (Qpre_command_hook);
+
+      safe_run_hooks_maybe_narrowed (Qpre_command_hook,
+                                    XWINDOW (selected_window));
 
       already_adjusted = 0;
 
@@ -1513,7 +1516,8 @@ command_loop_1 (void)
           }
       kset_last_prefix_arg (current_kboard, Vcurrent_prefix_arg);
 
-      safe_run_hooks (Qpost_command_hook);
+      safe_run_hooks_maybe_narrowed (Qpost_command_hook,
+                                    XWINDOW (selected_window));
 
       /* If displaying a message, resize the echo area window to fit
         that message's size exactly.  Do this only if the echo area
@@ -1895,6 +1899,22 @@ safe_run_hooks (Lisp_Object hook)
   unbind_to (count, Qnil);
 }
 
+void
+safe_run_hooks_maybe_narrowed (Lisp_Object hook, struct window *w)
+{
+  specpdl_ref count = SPECPDL_INDEX ();
+
+  specbind (Qinhibit_quit, Qt);
+
+  if (current_buffer->long_line_optimizations_p)
+    narrow_to_region_internal (make_fixnum (get_narrowed_begv (w, PT)),
+                              make_fixnum (get_narrowed_zv (w, PT)),
+                              true);
+
+  run_hook_with_args (2, ((Lisp_Object []) {hook, hook}), 
safe_run_hook_funcall);
+  unbind_to (count, Qnil);
+}
+
 
 /* Nonzero means polling for input is temporarily suppressed.  */
 
@@ -12622,23 +12642,39 @@ Buffer modification stores t in this variable.  */);
 
   DEFVAR_LISP ("pre-command-hook", Vpre_command_hook,
               doc: /* Normal hook run before each command is executed.
-If an unhandled error happens in running this hook,
-the function in which the error occurred is unconditionally removed, since
-otherwise the error might happen repeatedly and make Emacs nonfunctional.
+
+If an unhandled error happens in running this hook, the function in
+which the error occurred is unconditionally removed, since otherwise
+the error might happen repeatedly and make Emacs nonfunctional.
+
+Note that, when the current buffer contains one or more lines whose
+length is above `long-line-threshold', these hook functions are called
+with the buffer narrowed to a small portion around point, and the
+narrowing is locked (see `narrow-to-region'), so that these hook
+functions cannot use `widen' to gain access to other portions of
+buffer text.
 
 See also `post-command-hook'.  */);
   Vpre_command_hook = Qnil;
 
   DEFVAR_LISP ("post-command-hook", Vpost_command_hook,
               doc: /* Normal hook run after each command is executed.
-If an unhandled error happens in running this hook,
-the function in which the error occurred is unconditionally removed, since
-otherwise the error might happen repeatedly and make Emacs nonfunctional.
+
+If an unhandled error happens in running this hook, the function in
+which the error occurred is unconditionally removed, since otherwise
+the error might happen repeatedly and make Emacs nonfunctional.
 
 It is a bad idea to use this hook for expensive processing.  If
 unavoidable, wrap your code in `(while-no-input (redisplay) CODE)' to
 avoid making Emacs unresponsive while the user types.
 
+Note that, when the current buffer contains one or more lines whose
+length is above `long-line-threshold', these hook functions are called
+with the buffer narrowed to a small portion around point, and the
+narrowing is locked (see `narrow-to-region'), so that these hook
+functions cannot use `widen' to gain access to other portions of
+buffer text.
+
 See also `pre-command-hook'.  */);
   Vpost_command_hook = Qnil;
 
diff --git a/src/lisp.h b/src/lisp.h
index c8ad0bc56f..8e36620fe5 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -4830,6 +4830,7 @@ extern bool detect_input_pending (void);
 extern bool detect_input_pending_ignore_squeezables (void);
 extern bool detect_input_pending_run_timers (bool);
 extern void safe_run_hooks (Lisp_Object);
+extern void safe_run_hooks_maybe_narrowed (Lisp_Object, struct window *);
 extern void cmd_error_internal (Lisp_Object, const char *);
 extern Lisp_Object command_loop_2 (Lisp_Object);
 extern Lisp_Object read_menu_command (void);
diff --git a/src/xdisp.c b/src/xdisp.c
index 2bedf1c784..099efed2db 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -3229,6 +3229,7 @@ init_iterator (struct it *it, struct window *w,
   it->f = XFRAME (w->frame);
 
   it->cmp_it.id = -1;
+  it->cmp_it.parent_it = it;
 
   if (max_redisplay_ticks > 0)
     update_redisplay_ticks (0, w);
@@ -3413,12 +3414,6 @@ init_iterator (struct it *it, struct window *w,
        }
     }
 
-  if (current_buffer->long_line_optimizations_p)
-    {
-      it->narrowed_begv = get_narrowed_begv (w, window_point (w));
-      it->narrowed_zv = get_narrowed_zv (w, window_point (w));
-    }
-
   /* If a buffer position was specified, set the iterator there,
      getting overlays and face properties from that position.  */
   if (charpos >= BUF_BEG (current_buffer))
@@ -3478,6 +3473,9 @@ init_iterator (struct it *it, struct window *w,
                        &it->bidi_it);
        }
 
+      if (current_buffer->long_line_optimizations_p)
+       it->narrowed_begv = 0;
+
       /* Compute faces etc.  */
       reseat (it, it->current.pos, true);
     }
@@ -3510,9 +3508,7 @@ ptrdiff_t
 get_narrowed_begv (struct window *w, ptrdiff_t pos)
 {
   int len = get_narrowed_len (w);
-  ptrdiff_t begv;
-  begv = max ((pos / len - 1) * len, BEGV);
-  return begv == BEGV ? 0 : begv;
+  return max ((pos / len - 1) * len, BEGV);
 }
 
 ptrdiff_t
@@ -4397,13 +4393,12 @@ handle_fontified_prop (struct it *it)
 
       if (current_buffer->long_line_optimizations_p)
        {
-         ptrdiff_t begv = it->narrowed_begv ? it->narrowed_begv : BEGV;
+         ptrdiff_t begv = it->narrowed_begv;
          ptrdiff_t zv = it->narrowed_zv;
          ptrdiff_t charpos = IT_CHARPOS (*it);
          if (charpos < begv || charpos > zv)
            {
              begv = get_narrowed_begv (it->w, charpos);
-             if (!begv) begv = BEGV;
              zv = get_narrowed_zv (it->w, charpos);
            }
          narrow_to_region_internal (make_fixnum (begv), make_fixnum (zv), 
true);
@@ -7533,6 +7528,21 @@ reseat (struct it *it, struct text_pos pos, bool force_p)
 
   reseat_1 (it, pos, false);
 
+  if (current_buffer->long_line_optimizations_p)
+    {
+      if (!it->narrowed_begv)
+       {
+         it->narrowed_begv = get_narrowed_begv (it->w, window_point (it->w));
+         it->narrowed_zv = get_narrowed_zv (it->w, window_point (it->w));
+       }
+      else if ((pos.charpos < it->narrowed_begv || pos.charpos > 
it->narrowed_zv)
+               && (!redisplaying_p || it->line_wrap == TRUNCATE))
+       {
+         it->narrowed_begv = get_narrowed_begv (it->w, pos.charpos);
+         it->narrowed_zv = get_narrowed_zv (it->w, pos.charpos);
+       }
+    }
+
   /* Determine where to check text properties.  Avoid doing it
      where possible because text property lookup is very expensive.  */
   if (force_p
@@ -8838,7 +8848,7 @@ get_visually_first_element (struct it *it)
 
   SET_WITH_NARROWED_BEGV (it, bob,
                          string_p ? 0 :
-                         IT_BYTEPOS (*it) < BEGV ? obegv : BEGV,
+                         IT_CHARPOS (*it) < BEGV ? obegv : BEGV,
                          it->narrowed_begv);
 
   if (STRINGP (it->string))
@@ -10773,7 +10783,7 @@ move_it_vertically_backward (struct it *it, int dy)
          dec_both (&cp, &bp);
          SET_WITH_NARROWED_BEGV (it, cp,
                                  find_newline_no_quit (cp, bp, -1, NULL),
-                                 it->narrowed_begv);
+                                 get_closer_narrowed_begv (it->w, IT_CHARPOS 
(*it)));
          move_it_to (it, cp, -1, -1, -1, MOVE_TO_POS);
        }
       bidi_unshelve_cache (it3data, true);



reply via email to

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