aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEli Zaretskii2016-05-21 12:35:08 +0300
committerEli Zaretskii2016-09-23 16:59:17 +0300
commitdf4f8125342bafe1d70130f84acfa67cc0c4a7f4 (patch)
tree6f2fa9895170462543b5c9d019ddb9e99b1f4b2d /src
parent9135bd7af7bdf9f805b185a77fe4e6d33dec4009 (diff)
downloademacs-df4f8125342bafe1d70130f84acfa67cc0c4a7f4.tar.gz
emacs-df4f8125342bafe1d70130f84acfa67cc0c4a7f4.zip
Fix 'vertical-motion' and 'posn-at-point' under 'visual-line-mode'
* src/xdisp.c (move_it_in_display_line_to): Don't assume we can wrap on a whitespace character if it's followed by another whitespace character. When returning under WORD_WRAP for a screen line that is continued, restore to wrap point when atpos/atx position would be displayed on the next screen line due to line-wrap. (Bug#23570) This is backported from master (cherry picked from commit 99848b37d2c3e14c0af45fc6da437a806aa58a80)
Diffstat (limited to 'src')
-rw-r--r--src/xdisp.c64
1 files changed, 52 insertions, 12 deletions
diff --git a/src/xdisp.c b/src/xdisp.c
index 24daa0c3b71..adbb6e5088b 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -8805,6 +8805,8 @@ move_it_in_display_line_to (struct it *it,
8805 ? WINDOW_LEFT_FRINGE_WIDTH (it->w) 8805 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
8806 : WINDOW_RIGHT_FRINGE_WIDTH (it->w))))) 8806 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)))))
8807 { 8807 {
8808 bool moved_forward = false;
8809
8808 if (/* IT->hpos == 0 means the very first glyph 8810 if (/* IT->hpos == 0 means the very first glyph
8809 doesn't fit on the line, e.g. a wide image. */ 8811 doesn't fit on the line, e.g. a wide image. */
8810 it->hpos == 0 8812 it->hpos == 0
@@ -8823,16 +8825,37 @@ move_it_in_display_line_to (struct it *it,
8823 now that we know it fits in this row. */ 8825 now that we know it fits in this row. */
8824 if (BUFFER_POS_REACHED_P ()) 8826 if (BUFFER_POS_REACHED_P ())
8825 { 8827 {
8828 bool can_wrap = true;
8829
8830 /* If we are at a whitespace character
8831 that barely fits on this screen line,
8832 but the next character is also
8833 whitespace, we cannot wrap here. */
8834 if (it->line_wrap == WORD_WRAP
8835 && wrap_it.sp >= 0
8836 && may_wrap
8837 && IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
8838 {
8839 struct it tem_it;
8840 void *tem_data = NULL;
8841
8842 SAVE_IT (tem_it, *it, tem_data);
8843 set_iterator_to_next (it, true);
8844 if (get_next_display_element (it)
8845 && IT_DISPLAYING_WHITESPACE (it))
8846 can_wrap = false;
8847 RESTORE_IT (it, &tem_it, tem_data);
8848 }
8826 if (it->line_wrap != WORD_WRAP 8849 if (it->line_wrap != WORD_WRAP
8827 || wrap_it.sp < 0 8850 || wrap_it.sp < 0
8828 /* If we've just found whitespace to 8851 /* If we've just found whitespace
8829 wrap, effectively ignore the 8852 where we can wrap, effectively
8830 previous wrap point -- it is no 8853 ignore the previous wrap point --
8831 longer relevant, but we won't 8854 it is no longer relevant, but we
8832 have an opportunity to update it, 8855 won't have an opportunity to
8833 since we've reached the edge of 8856 update it, since we've reached
8834 this screen line. */ 8857 the edge of this screen line. */
8835 || (may_wrap 8858 || (may_wrap && can_wrap
8836 && IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))) 8859 && IT_OVERFLOW_NEWLINE_INTO_FRINGE (it)))
8837 { 8860 {
8838 it->hpos = hpos_before_this_char; 8861 it->hpos = hpos_before_this_char;
@@ -8875,6 +8898,7 @@ move_it_in_display_line_to (struct it *it,
8875 result = MOVE_POS_MATCH_OR_ZV; 8898 result = MOVE_POS_MATCH_OR_ZV;
8876 break; 8899 break;
8877 } 8900 }
8901 moved_forward = true;
8878 if (BUFFER_POS_REACHED_P ()) 8902 if (BUFFER_POS_REACHED_P ())
8879 { 8903 {
8880 if (ITERATOR_AT_END_OF_LINE_P (it)) 8904 if (ITERATOR_AT_END_OF_LINE_P (it))
@@ -8902,7 +8926,14 @@ move_it_in_display_line_to (struct it *it,
8902 longer relevant, but we won't have an opportunity 8926 longer relevant, but we won't have an opportunity
8903 to update it, since we are done with this screen 8927 to update it, since we are done with this screen
8904 line. */ 8928 line. */
8905 if (may_wrap && IT_OVERFLOW_NEWLINE_INTO_FRINGE (it)) 8929 if (may_wrap && IT_OVERFLOW_NEWLINE_INTO_FRINGE (it)
8930 /* If the character after the one which set the
8931 may_wrap flag is also whitespace, we can't
8932 wrap here, since the screen line cannot be
8933 wrapped in the middle of whitespace.
8934 Therefore, wrap_it _is_ relevant in that
8935 case. */
8936 && !(moved_forward && IT_DISPLAYING_WHITESPACE (it)))
8906 { 8937 {
8907 /* If we've found TO_X, go back there, as we now 8938 /* If we've found TO_X, go back there, as we now
8908 know the last word fits on this screen line. */ 8939 know the last word fits on this screen line. */
@@ -9083,9 +9114,18 @@ move_it_in_display_line_to (struct it *it,
9083 9114
9084#undef BUFFER_POS_REACHED_P 9115#undef BUFFER_POS_REACHED_P
9085 9116
9086 /* If we scanned beyond to_pos and didn't find a point to wrap at, 9117 /* If we scanned beyond TO_POS, restore the saved iterator either to
9087 restore the saved iterator. */ 9118 the wrap point (if found), or to atpos/atx location. We decide which
9088 if (atpos_it.sp >= 0) 9119 data to use to restore the saved iterator state by their X coordinates,
9120 since buffer positions might increase non-monotonically with screen
9121 coordinates due to bidi reordering. */
9122 if (result == MOVE_LINE_CONTINUED
9123 && it->line_wrap == WORD_WRAP
9124 && wrap_it.sp >= 0
9125 && ((atpos_it.sp >= 0 && wrap_it.current_x < atpos_it.current_x)
9126 || (atx_it.sp >= 0 && wrap_it.current_x < atx_it.current_x)))
9127 RESTORE_IT (it, &wrap_it, wrap_data);
9128 else if (atpos_it.sp >= 0)
9089 RESTORE_IT (it, &atpos_it, atpos_data); 9129 RESTORE_IT (it, &atpos_it, atpos_data);
9090 else if (atx_it.sp >= 0) 9130 else if (atx_it.sp >= 0)
9091 RESTORE_IT (it, &atx_it, atx_data); 9131 RESTORE_IT (it, &atx_it, atx_data);