emacs-diffs
[Top][All Lists]
Advanced

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

[Emacs-diffs] /srv/bzr/emacs/trunk r105856: Fix bug #9549 with longlines


From: Eli Zaretskii
Subject: [Emacs-diffs] /srv/bzr/emacs/trunk r105856: Fix bug #9549 with longlines-show-hard-newlines.
Date: Tue, 20 Sep 2011 20:13:45 +0300
User-agent: Bazaar (2.3.1)

------------------------------------------------------------
revno: 105856
fixes bug(s): http://debbugs.gnu.org/9549
committer: Eli Zaretskii <address@hidden>
branch nick: trunk
timestamp: Tue 2011-09-20 20:13:45 +0300
message:
  Fix bug #9549 with longlines-show-hard-newlines.
  
   src/xdisp.c (set_cursor_from_row): If the row ends in a newline from
   a display string, extend search for cursor position to end of row.
   (find_row_edges): If the row ends in a newline from a display
   string, increment its MATRIX_ROW_END_CHARPOS by one.
   Handle the case of a display string with multiple newlines.
modified:
  src/ChangeLog
  src/xdisp.c
=== modified file 'src/ChangeLog'
--- a/src/ChangeLog     2011-09-19 08:25:35 +0000
+++ b/src/ChangeLog     2011-09-20 17:13:45 +0000
@@ -1,3 +1,11 @@
+2011-09-20  Eli Zaretskii  <address@hidden>
+
+       * xdisp.c (set_cursor_from_row): If the row ends in a newline from
+       a display string, extend search for cursor position to end of row.
+       (find_row_edges): If the row ends in a newline from a display
+       string, increment its MATRIX_ROW_END_CHARPOS by one.  (Bug#9549)
+       Handle the case of a display string with multiple newlines.
+
 2011-09-19  Lars Magne Ingebrigtsen  <address@hidden>
 
        * lread.c (Fread_from_string): Document what FINAL-STRING-INDEX is

=== modified file 'src/xdisp.c'
--- a/src/xdisp.c       2011-09-18 19:02:17 +0000
+++ b/src/xdisp.c       2011-09-20 17:13:45 +0000
@@ -13666,6 +13666,17 @@
 
          x = -1;
 
+         /* If the row ends in a newline from a display string,
+            reordering could have moved the glyphs belonging to the
+            string out of the [GLYPH_BEFORE..GLYPH_AFTER] range.  So
+            in this case we extend the search to the last glyph in
+            the row that was not inserted by redisplay.  */
+         if (row->ends_in_newline_from_string_p)
+           {
+             glyph_after = end;
+             pos_after = MATRIX_ROW_END_CHARPOS (row) + delta;
+           }
+
          /* GLYPH_BEFORE and GLYPH_AFTER are the glyphs that
             correspond to POS_BEFORE and POS_AFTER, respectively.  We
             need START and STOP in the order that corresponds to the
@@ -18341,7 +18352,8 @@
      Line ends in a newline from buffer       eol_pos + 1
      Line is continued from buffer            max_pos + 1
      Line is truncated on right               it->current.pos
-     Line ends in a newline from string       max_pos
+     Line ends in a newline from string       max_pos + 1(*)
+      (*) + 1 only when line ends in a forward scan
      Line is continued from string            max_pos
      Line is continued from display vector    max_pos
      Line is entirely from a string           min_pos == max_pos
@@ -18354,8 +18366,76 @@
     row->maxpos = it->current.pos;
   else if (row->used[TEXT_AREA])
     {
-      if (row->ends_in_newline_from_string_p)
-       SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
+      int seen_this_string = 0;
+      struct glyph_row *r1 = row - 1;
+
+      /* Did we see the same display string on the previous row?  */
+      if (STRINGP (it->object)
+         /* this is not the first row */
+         && row > it->w->desired_matrix->rows
+         /* previous row is not the header line */
+         && !r1->mode_line_p
+         /* previous row also ends in a newline from a string */
+         && r1->ends_in_newline_from_string_p)
+       {
+         struct glyph *start, *end;
+
+         /* Search for the last glyph of the previous row that came
+            from buffer or string.  Depending on whether the row is
+            L2R or R2L, we need to process it front to back or the
+            other way round.  */
+         if (!r1->reversed_p)
+           {
+             start = r1->glyphs[TEXT_AREA];
+             end = start + r1->used[TEXT_AREA];
+             /* Glyphs inserted by redisplay have an integer (zero)
+                as their object.  */
+             while (end > start
+                    && INTEGERP ((end - 1)->object)
+                    && (end - 1)->charpos <= 0)
+               --end;
+             if (end > start)
+               {
+                 if (EQ ((end - 1)->object, it->object))
+                   seen_this_string = 1;
+               }
+             else
+               abort ();
+           }
+         else
+           {
+             end = r1->glyphs[TEXT_AREA] - 1;
+             start = end + r1->used[TEXT_AREA];
+             while (end < start
+                    && INTEGERP ((end + 1)->object)
+                    && (end + 1)->charpos <= 0)
+               ++end;
+             if (end < start)
+               {
+                 if (EQ ((end + 1)->object, it->object))
+                   seen_this_string = 1;
+               }
+             else
+               abort ();
+           }
+       }
+      /* Take note of each display string that covers a newline only
+        once, the first time we see it.  This is for when a display
+        string includes more than one newline in it.  */
+      if (row->ends_in_newline_from_string_p && !seen_this_string)
+       {
+         /* If we were scanning the buffer forward when we displayed
+            the string, we want to account for at least one buffer
+            position that belongs to this row (position covered by
+            the display string), so that cursor positioning will
+            consider this row as a candidate when point is at the end
+            of the visual line represented by this row.  This is not
+            required when scanning back, because max_pos will already
+            have a much larger value.  */
+         if (CHARPOS (row->end.pos) > max_pos)
+           INC_BOTH (max_pos, max_bpos);
+         SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
+       }
       else if (CHARPOS (it->eol_pos) > 0)
        SET_TEXT_POS (row->maxpos,
                      CHARPOS (it->eol_pos) + 1, BYTEPOS (it->eol_pos) + 1);


reply via email to

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