[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Emacs-diffs] emacs-25 df4f812: Fix 'vertical-motion' and 'posn-at-point
From: |
Eli Zaretskii |
Subject: |
[Emacs-diffs] emacs-25 df4f812: Fix 'vertical-motion' and 'posn-at-point' under 'visual-line-mode' |
Date: |
Fri, 23 Sep 2016 14:00:35 +0000 (UTC) |
branch: emacs-25
commit df4f8125342bafe1d70130f84acfa67cc0c4a7f4
Author: Eli Zaretskii <address@hidden>
Commit: Eli Zaretskii <address@hidden>
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)
---
src/xdisp.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++-----------
1 file changed, 52 insertions(+), 12 deletions(-)
diff --git a/src/xdisp.c b/src/xdisp.c
index 24daa0c..adbb6e5 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -8805,6 +8805,8 @@ move_it_in_display_line_to (struct it *it,
? WINDOW_LEFT_FRINGE_WIDTH (it->w)
: WINDOW_RIGHT_FRINGE_WIDTH (it->w)))))
{
+ bool moved_forward = false;
+
if (/* IT->hpos == 0 means the very first glyph
doesn't fit on the line, e.g. a wide image. */
it->hpos == 0
@@ -8823,16 +8825,37 @@ move_it_in_display_line_to (struct it *it,
now that we know it fits in this row. */
if (BUFFER_POS_REACHED_P ())
{
+ bool can_wrap = true;
+
+ /* If we are at a whitespace character
+ that barely fits on this screen line,
+ but the next character is also
+ whitespace, we cannot wrap here. */
+ if (it->line_wrap == WORD_WRAP
+ && wrap_it.sp >= 0
+ && may_wrap
+ && IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
+ {
+ struct it tem_it;
+ void *tem_data = NULL;
+
+ SAVE_IT (tem_it, *it, tem_data);
+ set_iterator_to_next (it, true);
+ if (get_next_display_element (it)
+ && IT_DISPLAYING_WHITESPACE (it))
+ can_wrap = false;
+ RESTORE_IT (it, &tem_it, tem_data);
+ }
if (it->line_wrap != WORD_WRAP
|| wrap_it.sp < 0
- /* If we've just found whitespace to
- wrap, effectively ignore the
- previous wrap point -- it is no
- longer relevant, but we won't
- have an opportunity to update it,
- since we've reached the edge of
- this screen line. */
- || (may_wrap
+ /* If we've just found whitespace
+ where we can wrap, effectively
+ ignore the previous wrap point --
+ it is no longer relevant, but we
+ won't have an opportunity to
+ update it, since we've reached
+ the edge of this screen line. */
+ || (may_wrap && can_wrap
&& IT_OVERFLOW_NEWLINE_INTO_FRINGE (it)))
{
it->hpos = hpos_before_this_char;
@@ -8875,6 +8898,7 @@ move_it_in_display_line_to (struct it *it,
result = MOVE_POS_MATCH_OR_ZV;
break;
}
+ moved_forward = true;
if (BUFFER_POS_REACHED_P ())
{
if (ITERATOR_AT_END_OF_LINE_P (it))
@@ -8902,7 +8926,14 @@ move_it_in_display_line_to (struct it *it,
longer relevant, but we won't have an opportunity
to update it, since we are done with this screen
line. */
- if (may_wrap && IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
+ if (may_wrap && IT_OVERFLOW_NEWLINE_INTO_FRINGE (it)
+ /* If the character after the one which set the
+ may_wrap flag is also whitespace, we can't
+ wrap here, since the screen line cannot be
+ wrapped in the middle of whitespace.
+ Therefore, wrap_it _is_ relevant in that
+ case. */
+ && !(moved_forward && IT_DISPLAYING_WHITESPACE (it)))
{
/* If we've found TO_X, go back there, as we now
know the last word fits on this screen line. */
@@ -9083,9 +9114,18 @@ move_it_in_display_line_to (struct it *it,
#undef BUFFER_POS_REACHED_P
- /* If we scanned beyond to_pos and didn't find a point to wrap at,
- restore the saved iterator. */
- if (atpos_it.sp >= 0)
+ /* If we scanned beyond TO_POS, restore the saved iterator either to
+ the wrap point (if found), or to atpos/atx location. We decide which
+ data to use to restore the saved iterator state by their X coordinates,
+ since buffer positions might increase non-monotonically with screen
+ coordinates due to bidi reordering. */
+ if (result == MOVE_LINE_CONTINUED
+ && it->line_wrap == WORD_WRAP
+ && wrap_it.sp >= 0
+ && ((atpos_it.sp >= 0 && wrap_it.current_x < atpos_it.current_x)
+ || (atx_it.sp >= 0 && wrap_it.current_x < atx_it.current_x)))
+ RESTORE_IT (it, &wrap_it, wrap_data);
+ else if (atpos_it.sp >= 0)
RESTORE_IT (it, &atpos_it, atpos_data);
else if (atx_it.sp >= 0)
RESTORE_IT (it, &atx_it, atx_data);
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Emacs-diffs] emacs-25 df4f812: Fix 'vertical-motion' and 'posn-at-point' under 'visual-line-mode',
Eli Zaretskii <=