]> git.eshelyaron.com Git - emacs.git/commitdiff
Fix bug #9212 with selective-display under bidi.
authorEli Zaretskii <eliz@gnu.org>
Mon, 1 Aug 2011 17:34:04 +0000 (20:34 +0300)
committerEli Zaretskii <eliz@gnu.org>
Mon, 1 Aug 2011 17:34:04 +0000 (20:34 +0300)
 src/xdisp.c (forward_to_next_line_start): Accept additional argument
 BIDI_IT_PREV, and store into it the state of the bidi iterator had
 on the newline.
 (reseat_at_next_visible_line_start): Use the bidi iterator state
 returned by forward_to_next_line_start to restore the state of
 it->bidi_it after backing up to previous newline.  (Bug#9212)

src/ChangeLog
src/xdisp.c

index 623ccc6f4bec4ba11970140f1a06ebd224b643aa..4e8217cdf5fb26b9b94e4c401174ad2e218684e0 100644 (file)
@@ -1,3 +1,12 @@
+2011-08-01  Eli Zaretskii  <eliz@gnu.org>
+
+       * xdisp.c (forward_to_next_line_start): Accept additional argument
+       BIDI_IT_PREV, and store into it the state of the bidi iterator had
+       on the newline.
+       (reseat_at_next_visible_line_start): Use the bidi iterator state
+       returned by forward_to_next_line_start to restore the state of
+       it->bidi_it after backing up to previous newline.  (Bug#9212)
+
 2011-07-30  Andreas Schwab  <schwab@linux-m68k.org>
 
        * regex.c (re_comp): Protoize.
index 84c75bd91d99af31bac5de6ec9326bef00dc5a88..a17d200c827d735b272c8eb941547c418ce646ec 100644 (file)
@@ -899,7 +899,7 @@ static void init_to_row_start (struct it *, struct window *,
 static int init_to_row_end (struct it *, struct window *,
                             struct glyph_row *);
 static void back_to_previous_line_start (struct it *);
-static int forward_to_next_line_start (struct it *, int *);
+static int forward_to_next_line_start (struct it *, int *, struct bidi_it *);
 static struct text_pos string_pos_nchars_ahead (struct text_pos,
                                                 Lisp_Object, EMACS_INT);
 static struct text_pos string_pos (EMACS_INT, Lisp_Object);
@@ -5494,6 +5494,9 @@ back_to_previous_line_start (struct it *it)
    continuously over the text).  Otherwise, don't change the value
    of *SKIPPED_P.
 
+   If BIDI_IT_PREV is non-NULL, store into it the state of the bidi
+   iterator on the newline, if it was found.
+
    Newlines may come from buffer text, overlay strings, or strings
    displayed via the `display' property.  That's the reason we can't
    simply use find_next_newline_no_quit.
@@ -5506,7 +5509,8 @@ back_to_previous_line_start (struct it *it)
    leads to wrong cursor motion.  */
 
 static int
-forward_to_next_line_start (struct it *it, int *skipped_p)
+forward_to_next_line_start (struct it *it, int *skipped_p,
+                           struct bidi_it *bidi_it_prev)
 {
   EMACS_INT old_selective;
   int newline_found_p, n;
@@ -5518,6 +5522,8 @@ forward_to_next_line_start (struct it *it, int *skipped_p)
       && it->c == '\n'
       && CHARPOS (it->position) == IT_CHARPOS (*it))
     {
+      if (it->bidi_p && bidi_it_prev)
+       *bidi_it_prev = it->bidi_it;
       set_iterator_to_next (it, 0);
       it->c = 0;
       return 1;
@@ -5539,6 +5545,8 @@ forward_to_next_line_start (struct it *it, int *skipped_p)
       if (!get_next_display_element (it))
        return 0;
       newline_found_p = it->what == IT_CHARACTER && it->c == '\n';
+      if (newline_found_p && it->bidi_p && bidi_it_prev)
+       *bidi_it_prev = it->bidi_it;
       set_iterator_to_next (it, 0);
     }
 
@@ -5573,6 +5581,8 @@ forward_to_next_line_start (struct it *it, int *skipped_p)
                 && !newline_found_p)
            {
              newline_found_p = ITERATOR_AT_END_OF_LINE_P (it);
+             if (newline_found_p && it->bidi_p && bidi_it_prev)
+               *bidi_it_prev = it->bidi_it;
              set_iterator_to_next (it, 0);
            }
        }
@@ -5696,8 +5706,9 @@ static void
 reseat_at_next_visible_line_start (struct it *it, int on_newline_p)
 {
   int newline_found_p, skipped_p = 0;
+  struct bidi_it bidi_it_prev;
 
-  newline_found_p = forward_to_next_line_start (it, &skipped_p);
+  newline_found_p = forward_to_next_line_start (it, &skipped_p, &bidi_it_prev);
 
   /* Skip over lines that are invisible because they are indented
      more than the value of IT->selective.  */
@@ -5708,7 +5719,8 @@ reseat_at_next_visible_line_start (struct it *it, int on_newline_p)
       {
        xassert (IT_BYTEPOS (*it) == BEGV
                 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
-       newline_found_p = forward_to_next_line_start (it, &skipped_p);
+       newline_found_p =
+         forward_to_next_line_start (it, &skipped_p, &bidi_it_prev);
       }
 
   /* Position on the newline if that's what's requested.  */
@@ -5718,29 +5730,30 @@ reseat_at_next_visible_line_start (struct it *it, int on_newline_p)
        {
          if (IT_STRING_CHARPOS (*it) > 0)
            {
-             if (!it->bidi_p)
+             --IT_STRING_CHARPOS (*it);
+             --IT_STRING_BYTEPOS (*it);
+             if (it->bidi_p)
                {
-                 --IT_STRING_CHARPOS (*it);
-                 --IT_STRING_BYTEPOS (*it);
+                 /* We need to restore the bidi iterator to the state
+                    it had on the newline.  */
+                 it->bidi_it = bidi_it_prev;
+                 xassert (IT_STRING_CHARPOS (*it) == it->bidi_it.charpos
+                          && IT_STRING_BYTEPOS (*it) == it->bidi_it.bytepos);
                }
-             else
-               /* Setting this flag will cause
-                  bidi_move_to_visually_next not to advance, but
-                  instead deliver the current character (newline),
-                  which is what the ON_NEWLINE_P flag wants.  */
-               it->bidi_it.first_elt = 1;
            }
        }
       else if (IT_CHARPOS (*it) > BEGV)
        {
-         if (!it->bidi_p)
+         --IT_CHARPOS (*it);
+         --IT_BYTEPOS (*it);
+         if (it->bidi_p)
            {
-             --IT_CHARPOS (*it);
-             --IT_BYTEPOS (*it);
+             /* We need to restore the bidi iterator to the state it
+                had on the newline.  */
+             it->bidi_it = bidi_it_prev;
+             xassert (IT_CHARPOS (*it) == it->bidi_it.charpos
+                      && IT_BYTEPOS (*it) == it->bidi_it.bytepos);
            }
-         /* With bidi iteration, the call to `reseat' will cause
-            bidi_move_to_visually_next deliver the current character,
-            the newline, instead of advancing.  */
          reseat (it, it->current.pos, 0);
        }
     }