diff options
| author | Eli Zaretskii | 2016-05-21 12:35:08 +0300 |
|---|---|---|
| committer | Eli Zaretskii | 2016-05-21 12:35:08 +0300 |
| commit | 99848b37d2c3e14c0af45fc6da437a806aa58a80 (patch) | |
| tree | 36e1a4603d96c4bc380b2bcc1fe9203787bc684e /src | |
| parent | edb4af7a1d1e8e0ab67b2dedad0ca0380e6866d4 (diff) | |
| download | emacs-99848b37d2c3e14c0af45fc6da437a806aa58a80.tar.gz emacs-99848b37d2c3e14c0af45fc6da437a806aa58a80.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)
Diffstat (limited to 'src')
| -rw-r--r-- | src/xdisp.c | 64 |
1 files changed, 52 insertions, 12 deletions
diff --git a/src/xdisp.c b/src/xdisp.c index 10a0cf24b4a..e78d3d6f5b6 100644 --- a/src/xdisp.c +++ b/src/xdisp.c | |||
| @@ -8810,6 +8810,8 @@ move_it_in_display_line_to (struct it *it, | |||
| 8810 | ? WINDOW_LEFT_FRINGE_WIDTH (it->w) | 8810 | ? WINDOW_LEFT_FRINGE_WIDTH (it->w) |
| 8811 | : WINDOW_RIGHT_FRINGE_WIDTH (it->w))))) | 8811 | : WINDOW_RIGHT_FRINGE_WIDTH (it->w))))) |
| 8812 | { | 8812 | { |
| 8813 | bool moved_forward = false; | ||
| 8814 | |||
| 8813 | if (/* IT->hpos == 0 means the very first glyph | 8815 | if (/* IT->hpos == 0 means the very first glyph |
| 8814 | doesn't fit on the line, e.g. a wide image. */ | 8816 | doesn't fit on the line, e.g. a wide image. */ |
| 8815 | it->hpos == 0 | 8817 | it->hpos == 0 |
| @@ -8828,16 +8830,37 @@ move_it_in_display_line_to (struct it *it, | |||
| 8828 | now that we know it fits in this row. */ | 8830 | now that we know it fits in this row. */ |
| 8829 | if (BUFFER_POS_REACHED_P ()) | 8831 | if (BUFFER_POS_REACHED_P ()) |
| 8830 | { | 8832 | { |
| 8833 | bool can_wrap = true; | ||
| 8834 | |||
| 8835 | /* If we are at a whitespace character | ||
| 8836 | that barely fits on this screen line, | ||
| 8837 | but the next character is also | ||
| 8838 | whitespace, we cannot wrap here. */ | ||
| 8839 | if (it->line_wrap == WORD_WRAP | ||
| 8840 | && wrap_it.sp >= 0 | ||
| 8841 | && may_wrap | ||
| 8842 | && IT_OVERFLOW_NEWLINE_INTO_FRINGE (it)) | ||
| 8843 | { | ||
| 8844 | struct it tem_it; | ||
| 8845 | void *tem_data = NULL; | ||
| 8846 | |||
| 8847 | SAVE_IT (tem_it, *it, tem_data); | ||
| 8848 | set_iterator_to_next (it, true); | ||
| 8849 | if (get_next_display_element (it) | ||
| 8850 | && IT_DISPLAYING_WHITESPACE (it)) | ||
| 8851 | can_wrap = false; | ||
| 8852 | RESTORE_IT (it, &tem_it, tem_data); | ||
| 8853 | } | ||
| 8831 | if (it->line_wrap != WORD_WRAP | 8854 | if (it->line_wrap != WORD_WRAP |
| 8832 | || wrap_it.sp < 0 | 8855 | || wrap_it.sp < 0 |
| 8833 | /* If we've just found whitespace to | 8856 | /* If we've just found whitespace |
| 8834 | wrap, effectively ignore the | 8857 | where we can wrap, effectively |
| 8835 | previous wrap point -- it is no | 8858 | ignore the previous wrap point -- |
| 8836 | longer relevant, but we won't | 8859 | it is no longer relevant, but we |
| 8837 | have an opportunity to update it, | 8860 | won't have an opportunity to |
| 8838 | since we've reached the edge of | 8861 | update it, since we've reached |
| 8839 | this screen line. */ | 8862 | the edge of this screen line. */ |
| 8840 | || (may_wrap | 8863 | || (may_wrap && can_wrap |
| 8841 | && IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))) | 8864 | && IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))) |
| 8842 | { | 8865 | { |
| 8843 | it->hpos = hpos_before_this_char; | 8866 | it->hpos = hpos_before_this_char; |
| @@ -8880,6 +8903,7 @@ move_it_in_display_line_to (struct it *it, | |||
| 8880 | result = MOVE_POS_MATCH_OR_ZV; | 8903 | result = MOVE_POS_MATCH_OR_ZV; |
| 8881 | break; | 8904 | break; |
| 8882 | } | 8905 | } |
| 8906 | moved_forward = true; | ||
| 8883 | if (BUFFER_POS_REACHED_P ()) | 8907 | if (BUFFER_POS_REACHED_P ()) |
| 8884 | { | 8908 | { |
| 8885 | if (ITERATOR_AT_END_OF_LINE_P (it)) | 8909 | if (ITERATOR_AT_END_OF_LINE_P (it)) |
| @@ -8907,7 +8931,14 @@ move_it_in_display_line_to (struct it *it, | |||
| 8907 | longer relevant, but we won't have an opportunity | 8931 | longer relevant, but we won't have an opportunity |
| 8908 | to update it, since we are done with this screen | 8932 | to update it, since we are done with this screen |
| 8909 | line. */ | 8933 | line. */ |
| 8910 | if (may_wrap && IT_OVERFLOW_NEWLINE_INTO_FRINGE (it)) | 8934 | if (may_wrap && IT_OVERFLOW_NEWLINE_INTO_FRINGE (it) |
| 8935 | /* If the character after the one which set the | ||
| 8936 | may_wrap flag is also whitespace, we can't | ||
| 8937 | wrap here, since the screen line cannot be | ||
| 8938 | wrapped in the middle of whitespace. | ||
| 8939 | Therefore, wrap_it _is_ relevant in that | ||
| 8940 | case. */ | ||
| 8941 | && !(moved_forward && IT_DISPLAYING_WHITESPACE (it))) | ||
| 8911 | { | 8942 | { |
| 8912 | /* If we've found TO_X, go back there, as we now | 8943 | /* If we've found TO_X, go back there, as we now |
| 8913 | know the last word fits on this screen line. */ | 8944 | know the last word fits on this screen line. */ |
| @@ -9088,9 +9119,18 @@ move_it_in_display_line_to (struct it *it, | |||
| 9088 | 9119 | ||
| 9089 | #undef BUFFER_POS_REACHED_P | 9120 | #undef BUFFER_POS_REACHED_P |
| 9090 | 9121 | ||
| 9091 | /* If we scanned beyond to_pos and didn't find a point to wrap at, | 9122 | /* If we scanned beyond TO_POS, restore the saved iterator either to |
| 9092 | restore the saved iterator. */ | 9123 | the wrap point (if found), or to atpos/atx location. We decide which |
| 9093 | if (atpos_it.sp >= 0) | 9124 | data to use to restore the saved iterator state by their X coordinates, |
| 9125 | since buffer positions might increase non-monotonically with screen | ||
| 9126 | coordinates due to bidi reordering. */ | ||
| 9127 | if (result == MOVE_LINE_CONTINUED | ||
| 9128 | && it->line_wrap == WORD_WRAP | ||
| 9129 | && wrap_it.sp >= 0 | ||
| 9130 | && ((atpos_it.sp >= 0 && wrap_it.current_x < atpos_it.current_x) | ||
| 9131 | || (atx_it.sp >= 0 && wrap_it.current_x < atx_it.current_x))) | ||
| 9132 | RESTORE_IT (it, &wrap_it, wrap_data); | ||
| 9133 | else if (atpos_it.sp >= 0) | ||
| 9094 | RESTORE_IT (it, &atpos_it, atpos_data); | 9134 | RESTORE_IT (it, &atpos_it, atpos_data); |
| 9095 | else if (atx_it.sp >= 0) | 9135 | else if (atx_it.sp >= 0) |
| 9096 | RESTORE_IT (it, &atx_it, atx_data); | 9136 | RESTORE_IT (it, &atx_it, atx_data); |