emacs-diffs
[Top][All Lists]
Advanced

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

[Emacs-diffs] master c16a8fc: Update current buffer when changing text p


From: Eli Zaretskii
Subject: [Emacs-diffs] master c16a8fc: Update current buffer when changing text properties
Date: Sat, 6 Jul 2019 12:21:30 -0400 (EDT)

branch: master
commit c16a8fc180ad766fe7dd97af0bab99e3e4552690
Author: Pip Cet <address@hidden>
Commit: Eli Zaretskii <address@hidden>

    Update current buffer when changing text properties
    
    * src/textprop.c (add_text_properties_1, set_text_properties)
    (set_text_properties_1, Fremove_text_properties): Switch buffer if
    necessary.  (Bug#36190)
    
    * doc/lispref/text.texi (Examining Properties): Document performance
    FIXME.
---
 doc/lispref/text.texi |  2 +-
 src/textprop.c        | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 67 insertions(+), 1 deletion(-)

diff --git a/doc/lispref/text.texi b/doc/lispref/text.texi
index c4fc524..ca0dd66 100644
--- a/doc/lispref/text.texi
+++ b/doc/lispref/text.texi
@@ -2800,7 +2800,7 @@ functions to examine the properties of a number of 
characters at once.
 
   These functions handle both strings and buffers.  Keep in mind that
 positions in a string start from 0, whereas positions in a buffer start
-from 1.
+from 1.  Passing a buffer other than the current buffer may be slow.
 
 @defun get-text-property pos prop &optional object
 This function returns the value of the @var{prop} property of the
diff --git a/src/textprop.c b/src/textprop.c
index 9023f4e..44c3332 100644
--- a/src/textprop.c
+++ b/src/textprop.c
@@ -1142,6 +1142,18 @@ static Lisp_Object
 add_text_properties_1 (Lisp_Object start, Lisp_Object end,
                       Lisp_Object properties, Lisp_Object object,
                       enum property_set_type set_type) {
+  /* Ensure we run the modification hooks for the right buffer,
+     without switching buffers twice (bug 36190).  FIXME: Switching
+     buffers is slow and often unnecessary.  */
+  if (BUFFERP (object) && XBUFFER (object) != current_buffer)
+    {
+      ptrdiff_t count = SPECPDL_INDEX ();
+      record_unwind_current_buffer ();
+      set_buffer_internal (XBUFFER (object));
+      return unbind_to (count, add_text_properties_1 (start, end, properties,
+                                                     object, set_type));
+    }
+
   INTERVAL i, unchanged;
   ptrdiff_t s, len;
   bool modified = false;
@@ -1343,6 +1355,19 @@ Lisp_Object
 set_text_properties (Lisp_Object start, Lisp_Object end, Lisp_Object 
properties,
                     Lisp_Object object, Lisp_Object coherent_change_p)
 {
+  /* Ensure we run the modification hooks for the right buffer,
+     without switching buffers twice (bug 36190).  FIXME: Switching
+     buffers is slow and often unnecessary.  */
+  if (BUFFERP (object) && XBUFFER (object) != current_buffer)
+    {
+      ptrdiff_t count = SPECPDL_INDEX ();
+      record_unwind_current_buffer ();
+      set_buffer_internal (XBUFFER (object));
+      return unbind_to (count,
+                       set_text_properties (start, end, properties,
+                                            object, coherent_change_p));
+    }
+
   INTERVAL i;
   bool first_time = true;
 
@@ -1413,6 +1438,20 @@ void
 set_text_properties_1 (Lisp_Object start, Lisp_Object end,
                       Lisp_Object properties, Lisp_Object object, INTERVAL i)
 {
+  /* Ensure we run the modification hooks for the right buffer,
+     without switching buffers twice (bug 36190).  FIXME: Switching
+     buffers is slow and often unnecessary.  */
+  if (BUFFERP (object) && XBUFFER (object) != current_buffer)
+    {
+      ptrdiff_t count = SPECPDL_INDEX ();
+      record_unwind_current_buffer ();
+      set_buffer_internal (XBUFFER (object));
+
+      set_text_properties_1 (start, end, properties, object, i);
+      unbind_to (count, Qnil);
+      return;
+    }
+
   INTERVAL prev_changed = NULL;
   ptrdiff_t s = XFIXNUM (start);
   ptrdiff_t len = XFIXNUM (end) - s;
@@ -1495,6 +1534,19 @@ Return t if any property was actually removed, nil 
otherwise.
 Use `set-text-properties' if you want to remove all text properties.  */)
   (Lisp_Object start, Lisp_Object end, Lisp_Object properties, Lisp_Object 
object)
 {
+  /* Ensure we run the modification hooks for the right buffer,
+     without switching buffers twice (bug 36190).  FIXME: Switching
+     buffers is slow and often unnecessary.  */
+  if (BUFFERP (object) && XBUFFER (object) != current_buffer)
+    {
+      ptrdiff_t count = SPECPDL_INDEX ();
+      record_unwind_current_buffer ();
+      set_buffer_internal (XBUFFER (object));
+      return unbind_to (count,
+                       Fremove_text_properties (start, end, properties,
+                                                object));
+    }
+
   INTERVAL i, unchanged;
   ptrdiff_t s, len;
   bool modified = false;
@@ -1607,6 +1659,20 @@ markers).  If OBJECT is a string, START and END are 
0-based indices into it.
 Return t if any property was actually removed, nil otherwise.  */)
   (Lisp_Object start, Lisp_Object end, Lisp_Object list_of_properties, 
Lisp_Object object)
 {
+  /* Ensure we run the modification hooks for the right buffer,
+     without switching buffers twice (bug 36190).  FIXME: Switching
+     buffers is slow and often unnecessary.  */
+  if (BUFFERP (object) && XBUFFER (object) != current_buffer)
+    {
+      ptrdiff_t count = SPECPDL_INDEX ();
+      record_unwind_current_buffer ();
+      set_buffer_internal (XBUFFER (object));
+      return unbind_to (count,
+                       Fremove_list_of_text_properties (start, end,
+                                                        list_of_properties,
+                                                        object));
+    }
+
   INTERVAL i, unchanged;
   ptrdiff_t s, len;
   bool modified = false;



reply via email to

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