changeset 64281:6d94773592af

* xdisp.c (start_display): Don't reseat to next visible line start if current start position is in a string or image. (move_it_vertically_backward): Be sure to move out of strings and images when moving it2 forward. (move_it_by_lines): When moving forward, move to next buffer position if we end up in a string or image. When moving backward, count rows moved over when moving to start of current row in case row starts in middle of a string or image. Also move further backward if we end up in a string or image. (try_cursor_movement): if overlay string spans multiple lines, move backward to set cursor on start of an overlay string. (cursor_row_p): Row is ok if cursor is at newline from string, but string starts on this line (so we always position cursor at start of string).
author Kim F. Storm <storm@cua.dk>
date Wed, 13 Jul 2005 10:02:42 +0000
parents fbf7c36d9934
children 769e8d799acf
files src/xdisp.c
diffstat 1 files changed, 45 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/src/xdisp.c	Wed Jul 13 09:36:12 2005 +0000
+++ b/src/xdisp.c	Wed Jul 13 10:02:42 2005 +0000
@@ -2408,7 +2408,9 @@
   init_iterator (it, w, CHARPOS (pos), BYTEPOS (pos), row, DEFAULT_FACE_ID);
   it->first_vpos = first_vpos;
 
-  if (!it->truncate_lines_p)
+  /* Don't reseat to previous visible line start if current start
+     position is in a string or image.  */
+  if (it->method == GET_FROM_BUFFER && !it->truncate_lines_p)
     {
       int start_at_line_beg_p;
       int first_y = it->current_y;
@@ -6379,8 +6381,12 @@
      y-distance.  */
   it2 = *it;
   it2.max_ascent = it2.max_descent = 0;
-  move_it_to (&it2, start_pos, -1, -1, it2.vpos + 1,
-	      MOVE_TO_POS | MOVE_TO_VPOS);
+  do
+    {
+      move_it_to (&it2, start_pos, -1, -1, it2.vpos + 1,
+		  MOVE_TO_POS | MOVE_TO_VPOS);
+    }
+  while (it2.method != GET_FROM_BUFFER);
   xassert (IT_CHARPOS (*it) >= BEGV);
   it3 = it2;
 
@@ -6578,21 +6584,45 @@
       last_height = 0;
     }
   else if (dvpos > 0)
-    move_it_to (it, -1, -1, -1, it->vpos + dvpos, MOVE_TO_VPOS);
+    {
+      move_it_to (it, -1, -1, -1, it->vpos + dvpos, MOVE_TO_VPOS);
+      if (it->method != GET_FROM_BUFFER)
+	move_it_to (it, IT_CHARPOS (*it) + 1, -1, -1, -1, MOVE_TO_POS);
+    }
   else
     {
       struct it it2;
       int start_charpos, i;
 
       /* Start at the beginning of the screen line containing IT's
-	 position.  */
+	 position.  This may actually move vertically backwards,
+         in case of overlays, so adjust dvpos accordingly.  */
+      dvpos += it->vpos;
       move_it_vertically_backward (it, 0);
+      dvpos -= it->vpos;
 
       /* Go back -DVPOS visible lines and reseat the iterator there.  */
       start_charpos = IT_CHARPOS (*it);
-      for (i = -dvpos; i && IT_CHARPOS (*it) > BEGV; --i)
+      for (i = -dvpos; i > 0 && IT_CHARPOS (*it) > BEGV; --i)
 	back_to_previous_visible_line_start (it);
       reseat (it, it->current.pos, 1);
+
+      /* Move further back if we end up in a string or an image.  */
+      while (it->method != GET_FROM_BUFFER)
+	{
+	  /* First try to move to start of display line.  */
+	  dvpos += it->vpos;
+	  move_it_vertically_backward (it, 0);
+	  dvpos -= it->vpos;
+	  if (it->method == GET_FROM_BUFFER)
+	    break;
+	  /* If start of line is still in string or image,
+	     move further back.  */
+	  back_to_previous_visible_line_start (it);
+	  reseat (it, it->current.pos, 1);
+	  dvpos--;
+	}
+
       it->current_x = it->hpos = 0;
 
       /* Above call may have moved too far if continuation lines
@@ -11824,7 +11854,10 @@
 	      while (!row->mode_line_p
 		     && (MATRIX_ROW_START_CHARPOS (row) > PT
 			 || (MATRIX_ROW_START_CHARPOS (row) == PT
-			     && MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row)))
+			     && (MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row)
+				 || (/* STARTS_IN_MIDDLE_OF_STRING_P (row) */
+				     row > w->current_matrix->rows
+				     && (row-1)->ends_in_newline_from_string_p))))
 		     && (row->y > top_scroll_margin
 			 || CHARPOS (startp) == BEGV))
 		{
@@ -14995,10 +15028,12 @@
   if (PT == MATRIX_ROW_END_CHARPOS (row))
     {
       /* If the row ends with a newline from a string, we don't want
-	 the cursor there (if the row is continued it doesn't end in a
-	 newline).  */
+	 the cursor there, but we still want it at the start of the
+	 string if the string starts in this row.
+	 If the row is continued it doesn't end in a newline.  */
       if (CHARPOS (row->end.string_pos) >= 0)
-	cursor_row_p = row->continued_p;
+	cursor_row_p = (row->continued_p
+			|| PT >= MATRIX_ROW_START_CHARPOS (row));
       else if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
 	{
 	  /* If the row ends in middle of a real character,