]> git.eshelyaron.com Git - emacs.git/commitdiff
Fix more failures of visual-order cursor movement under word-wrap (bug#16961).
authorEli Zaretskii <eliz@gnu.org>
Sat, 8 Mar 2014 10:54:43 +0000 (12:54 +0200)
committerEli Zaretskii <eliz@gnu.org>
Sat, 8 Mar 2014 10:54:43 +0000 (12:54 +0200)
 src/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.

src/ChangeLog
src/xdisp.c

index a63995129cd480e5227b64c652e2bc8b21571f24..18f412362f1b020d06ad8e11234c0f87393d4e25 100644 (file)
@@ -1,3 +1,18 @@
+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
index 1513d4a9a877e76cd06ef97c2d8c0d4436cb98c0..62915438e504cded17f25ada550fa6c371376237 100644 (file)
@@ -8651,7 +8651,12 @@ move_it_in_display_line_to (struct it *it,
                         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;
@@ -20857,6 +20862,27 @@ Value is the new character position of point.  */)
              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