+2014-03-08 Eli Zaretskii <eliz@gnu.org>
+
+ * xdisp.c (move_it_in_display_line_to): If word-wrap is ON, and
+ there's a valid wrap point in the display line, the last glyph
+ cannot "just barely fit" on this row, because display_line doesn't
+ let it. Instead, proceed as if the last glyph didn't fit, so that
+ we eventually back up the iterator to the wrap point. This avoids
+ delusional behavior of move_it_to, whereby it proceeds to the next
+ display line, but sets current_x to zero for all the glyphs that
+ without word-wrap would fit on the previous display line. One
+ result was that visual-order cursor movement behaved erratically
+ under word-wrap.
+ (Fmove_point_visually): Add code to find the x coordinate of the
+ last character before wrap point, under word-wrap on a TTY.
+
2014-03-07 Eli Zaretskii <eliz@gnu.org>
* xdisp.c (Fmove_point_visually): When under word-wrap, accept
doesn't fit on the line, e.g. a wide image. */
it->hpos == 0
|| (new_x == it->last_visible_x
- && FRAME_WINDOW_P (it->f)))
+ && FRAME_WINDOW_P (it->f)
+ /* When word-wrap is ON and we have a valid
+ wrap point, we don't allow the last glyph
+ to "just barely fit" on the line. */
+ && (it->line_wrap != WORD_WRAP
+ || wrap_it.sp < 0)))
{
++it->hpos;
it->current_x = new_x;
move_it_by_lines (&it, -1);
target_x = it.last_visible_x - !FRAME_WINDOW_P (it.f);
target_is_eol_p = true;
+ /* Under word-wrap, we don't know the x coordinate of
+ the last character displayed on the previous line,
+ which immediately precedes the wrap point. To find
+ out its x coordinate, we try moving to the right
+ margin of the window, which will stop at the wrap
+ point, and then reset target_x to point at the
+ character that precedes the wrap point. This is not
+ needed on GUI frames, because (see below) there we
+ move from the left margin one grapheme cluster at a
+ time, and stop when we hit the wrap point. */
+ if (!FRAME_WINDOW_P (it.f) && it.line_wrap == WORD_WRAP)
+ {
+ void *it_data = NULL;
+ struct it it2;
+
+ SAVE_IT (it2, it, it_data);
+ move_it_in_display_line_to (&it, ZV, target_x,
+ MOVE_TO_POS | MOVE_TO_X);
+ target_x = it.current_x - 1;
+ RESTORE_IT (&it, &it2, it_data);
+ }
}
}
else