]> git.eshelyaron.com Git - emacs.git/commitdiff
Continue debugging continuation lines.
authorEli Zaretskii <eliz@gnu.org>
Sat, 6 Mar 2010 16:06:24 +0000 (11:06 -0500)
committerEli Zaretskii <eliz@gnu.org>
Sat, 6 Mar 2010 16:06:24 +0000 (11:06 -0500)
 .gdbinit (prowlims, pmtxrows): New commands.
 xdisp.c (display_line): Special-case the calculation of row->end
 in rows that end at ZV, to avoid abort in CHAR_TO_BYTE.  Handle
 empty lines correctly when calculating row's max and min pos.
 Display cursor at the first glyph row that has its ends_at_zv_p
 flag set.

src/.gdbinit
src/ChangeLog.bidi
src/xdisp.c

index 8949e66134c75c0e90e55cb7379507118f91db39..659bc870710153ece73c42c99367410f3b641923 100644 (file)
@@ -613,6 +613,28 @@ document pgrowit
 Pretty print all glyphs in it->glyph_row.
 end
 
+define prowlims
+  printf "start=%d,end=%d,reversed=%d,cont=%d\n", $arg0->start.pos.charpos, $arg0->end.pos.charpos, $arg0->reversed_p, $arg0->continued_p
+end
+document prowlims
+Print important attributes of a glyph_row structure.
+Takes one argument, a pointer to a glyph_row structure.
+end
+
+define pmtxrows
+  set $mtx = $arg0
+  set $gl = $mtx->rows
+  set $glend = $mtx->rows + $mtx->nrows
+  while ($gl < $glend)
+    prowlims $gl
+    set $gl = $gl + 1
+  end
+end
+document pmtxrows
+Print data about glyph rows in a glyph matrix.
+Takes one argument, a pointer to a glyph_matrix structure.
+end
+
 define xtype
   xgettype $
   output $type
index 234723bf6f7460f5feef05b40c1dafd89c72e3a9..7f7eb0808d23147fea269923b0924fca08afe908 100644 (file)
@@ -1,3 +1,13 @@
+2010-03-06  Eli Zaretskii  <eliz@gnu.org>
+
+       * .gdbinit (prowlims, pmtxrows): New commands.
+
+       * xdisp.c (display_line): Special-case the calculation of row->end
+       in rows that end at ZV, to avoid abort in CHAR_TO_BYTE.  Handle
+       empty lines correctly when calculating row's max and min pos.
+       Display cursor at the first glyph row that has its ends_at_zv_p
+       flag set.
+
 2010-02-20  Eli Zaretskii  <eliz@gnu.org>
 
        * xdisp.c (set_cursor_from_row): Compare candidate cursor
index 056a009a7d96864bd73108f9c61367433d8979f9..e481809164dccce77ce34389324dfde5acc51d3f 100644 (file)
@@ -17604,19 +17604,18 @@ display_line (it)
   compute_line_metrics (it);
 
   /* Remember the position at which this line ends.  */
-  if (!it->bidi_p)
-    row->end = row_end = it->current;
-  else
+  row->end = row_end = it->current;
+  if (it->bidi_p)
     {
-      EMACS_INT min_pos = row->start.pos.charpos, max_pos = 0;
-      struct glyph *g;
-      struct it save_it;
-      struct text_pos tpos;
-
       /* ROW->start and ROW->end must be the smallest and largest
         buffer positions in ROW.  But if ROW was bidi-reordered,
         these two positions can be anywhere in the row, so we must
         rescan all of the ROW's glyphs to find them.  */
+      EMACS_INT min_pos = ZV + 1, max_pos = 0;
+      struct glyph *g;
+      struct it save_it;
+      struct text_pos tpos;
+
       for (g = row->glyphs[TEXT_AREA];
           g < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
           g++)
@@ -17629,34 +17628,68 @@ display_line (it)
                max_pos = g->charpos;
            }
        }
-      if (min_pos < row->start.pos.charpos)
+      /* Empty lines have a valid buffer position at their first
+        glyph, but that glyph's OBJECT is zero, as if it didn't come
+        from a buffer.  If we didn't find any valid buffer positions
+        in this row, maybe we have such an empty line.  */
+      if (min_pos == ZV + 1 && row->used[TEXT_AREA])
        {
-         row->start.pos.charpos = min_pos;
-         row->start.pos.bytepos = CHAR_TO_BYTE (min_pos);
+         for (g = row->glyphs[TEXT_AREA];
+              g < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
+              g++)
+           {
+             if (INTEGERP (g->object))
+               {
+                 if (g->charpos && g->charpos < min_pos)
+                   min_pos = g->charpos;
+                 if (g->charpos > max_pos)
+                   max_pos = g->charpos;
+               }
+           }
+       }
+      if (min_pos <= ZV)
+       {
+         if (min_pos != row->start.pos.charpos)
+           {
+             row->start.pos.charpos = min_pos;
+             row->start.pos.bytepos = CHAR_TO_BYTE (min_pos);
+           }
+         if (max_pos == 0)
+           max_pos = min_pos;
        }
-      if (max_pos == 0)
-       max_pos = min_pos;
       /* For ROW->end, we need the position that is _after_ max_pos,
-        in the logical order.  */
-      SET_TEXT_POS (tpos, max_pos + 1, CHAR_TO_BYTE (max_pos + 1));
-      /* If the character at max_pos+1 is a newline, skip that as
-        well.  Note that this may skip some invisible text.  */
-      if (FETCH_CHAR (tpos.bytepos) == '\n'
-         || (FETCH_CHAR (tpos.bytepos) == '\r' && it->selective))
-       {
-         save_it = *it;
-         it->bidi_p = 0;
-         reseat_1 (it, tpos, 0);
-         set_iterator_to_next (it, 1);
-         row_end = it->current;
-         *it = save_it;
+        in the logical order, unless we are at ZV.  */
+      if (row->ends_at_zv_p)
+       {
+         row_end = row->end = it->current;
+         if (!row->used[TEXT_AREA])
+           {
+             row->start.pos.charpos = row_end.pos.charpos;
+             row->start.pos.bytepos = row_end.pos.bytepos;
+           }
        }
-      else
+      else if (row->used[TEXT_AREA] && max_pos)
        {
-         row_end = it->current;
-         row_end.pos = tpos;
+         SET_TEXT_POS (tpos, max_pos + 1, CHAR_TO_BYTE (max_pos + 1));
+         /* If the character at max_pos+1 is a newline, skip that as
+            well.  Note that this may skip some invisible text.  */
+         if (FETCH_CHAR (tpos.bytepos) == '\n'
+             || (FETCH_CHAR (tpos.bytepos) == '\r' && it->selective))
+           {
+             save_it = *it;
+             it->bidi_p = 0;
+             reseat_1 (it, tpos, 0);
+             set_iterator_to_next (it, 1);
+             row_end = it->current;
+             *it = save_it;
+           }
+         else
+           {
+             row_end = it->current;
+             row_end.pos = tpos;
+           }
+         row->end = row_end;
        }
-      row->end = row_end;
     }
 
   /* Record whether this row ends inside an ellipsis.  */
@@ -17680,8 +17713,11 @@ display_line (it)
        /* In bidi-reordered rows, keep checking for proper cursor
          position even if one has been found already, because buffer
          positions in such rows change non-linearly with ROW->VPOS,
-         when a line is continued.  */
-       || it->bidi_p)
+         when a line is continued.  One exception: when we are at ZV,
+         display cursor on the first suitable glyph row, since all
+         the empty rows after that also have their ends_at_zv_p flag
+         set.  */
+       || (it->bidi_p && !row->ends_at_zv_p))
       && PT >= MATRIX_ROW_START_CHARPOS (row)
       && PT <= MATRIX_ROW_END_CHARPOS (row)
       && cursor_row_p (it->w, row))