Fix bidirectional redisplay when deletion creates a paragraph start.
authorEli Zaretskii <eliz@gnu.org>
Mon, 14 Apr 2014 15:32:27 +0000 (18:32 +0300)
committerEli Zaretskii <eliz@gnu.org>
Mon, 14 Apr 2014 15:32:27 +0000 (18:32 +0300)
 src/insdel.c (invalidate_buffer_caches): When deleting or replacing
 text, invalidate the bidi_paragraph_cache upto and including the
 preceding newline.

src/ChangeLog
src/insdel.c

index be4ce13..6b6bd06 100644 (file)
@@ -1,3 +1,9 @@
+2014-04-14  Eli Zaretskii  <eliz@gnu.org>
+
+       * insdel.c (invalidate_buffer_caches): When deleting or replacing
+       text, invalidate the bidi_paragraph_cache upto and including the
+       preceding newline.
+
 2014-04-13  Paul Eggert  <eggert@cs.ucla.edu>
 
        Port to IRIX 6.5 (Bug#9684).
index 30b22ec..ea5f630 100644 (file)
@@ -1866,9 +1866,35 @@ invalidate_buffer_caches (struct buffer *buf, ptrdiff_t start, ptrdiff_t end)
                              buf->width_run_cache,
                              start - BUF_BEG (buf), BUF_Z (buf) - end);
   if (buf->bidi_paragraph_cache)
-    invalidate_region_cache (buf,
-                             buf->bidi_paragraph_cache,
-                             start - BUF_BEG (buf), BUF_Z (buf) - end);
+    {
+      if (start != end
+         && start > BUF_BEG (buf))
+       {
+         /* If we are deleting or replacing characters, we could
+            create a paragraph start, because all of the characters
+            from START to the beginning of START's line are
+            whitespace.  Therefore, we must extend the region to be
+            invalidated up to the newline before START.  */
+         ptrdiff_t line_beg = start;
+         ptrdiff_t start_byte = buf_charpos_to_bytepos (buf, start);
+
+         if (BUF_FETCH_BYTE (buf, start_byte - 1) != '\n')
+           {
+             struct buffer *old = current_buffer;
+
+             set_buffer_internal (buf);
+
+             line_beg = find_newline_no_quit (start, start_byte, -1,
+                                              &start_byte);
+             set_buffer_internal (old);
+           }
+         if (line_beg > BUF_BEG (buf))
+           start = line_beg - 1;
+       }
+      invalidate_region_cache (buf,
+                              buf->bidi_paragraph_cache,
+                              start - BUF_BEG (buf), BUF_Z (buf) - end);
+    }
 }
 
 /* These macros work with an argument named `preserve_ptr'