Fix pos-visible-in-window-p under bidi redisplay when lines are truncated.
src/xdisp.c (move_it_in_display_line_to): Record the best matching position for TO_CHARPOS while scanning the line, and restore it on exit if none of the characters scanned was an exact match. Fixes vertical-motion and pos-visible-in-window-p when exact match is impossible due to invisible text, and the lines are truncated.
This commit is contained in:
parent
b6d5a68964
commit
c1734fbd6f
2 changed files with 62 additions and 4 deletions
|
@ -1,3 +1,11 @@
|
|||
2011-07-23 Eli Zaretskii <eliz@gnu.org>
|
||||
|
||||
* xdisp.c (move_it_in_display_line_to): Record the best matching
|
||||
position for TO_CHARPOS while scanning the line, and restore it on
|
||||
exit if none of the characters scanned was an exact match. Fixes
|
||||
vertical-motion and pos-visible-in-window-p when exact match is
|
||||
impossible due to invisible text, and the lines are truncated.
|
||||
|
||||
2011-07-22 Eli Zaretskii <eliz@gnu.org>
|
||||
|
||||
* xdisp.c (compute_stop_pos_backwards): New function.
|
||||
|
|
58
src/xdisp.c
58
src/xdisp.c
|
@ -7620,8 +7620,9 @@ move_it_in_display_line_to (struct it *it,
|
|||
{
|
||||
enum move_it_result result = MOVE_UNDEFINED;
|
||||
struct glyph_row *saved_glyph_row;
|
||||
struct it wrap_it, atpos_it, atx_it;
|
||||
struct it wrap_it, atpos_it, atx_it, ppos_it;
|
||||
void *wrap_data = NULL, *atpos_data = NULL, *atx_data = NULL;
|
||||
void *ppos_data = NULL;
|
||||
int may_wrap = 0;
|
||||
enum it_method prev_method = it->method;
|
||||
EMACS_INT prev_pos = IT_CHARPOS (*it);
|
||||
|
@ -7640,6 +7641,19 @@ move_it_in_display_line_to (struct it *it,
|
|||
atpos_it.sp = -1;
|
||||
atx_it.sp = -1;
|
||||
|
||||
/* Use ppos_it under bidi reordering to save a copy of IT for the
|
||||
position > CHARPOS that is the closest to CHARPOS. We restore
|
||||
that position in IT when we have scanned the entire display line
|
||||
without finding a match for CHARPOS and all the character
|
||||
positions are greater than CHARPOS. */
|
||||
if (it->bidi_p)
|
||||
{
|
||||
SAVE_IT (ppos_it, *it, ppos_data);
|
||||
SET_TEXT_POS (ppos_it.current.pos, ZV, ZV_BYTE);
|
||||
if ((op & MOVE_TO_POS) && IT_CHARPOS (*it) >= to_charpos)
|
||||
SAVE_IT (ppos_it, *it, ppos_data);
|
||||
}
|
||||
|
||||
#define BUFFER_POS_REACHED_P() \
|
||||
((op & MOVE_TO_POS) != 0 \
|
||||
&& BUFFERP (it->object) \
|
||||
|
@ -7765,6 +7779,11 @@ move_it_in_display_line_to (struct it *it,
|
|||
if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
|
||||
SET_TEXT_POS (this_line_min_pos,
|
||||
IT_CHARPOS (*it), IT_BYTEPOS (*it));
|
||||
if (it->bidi_p
|
||||
&& (op & MOVE_TO_POS)
|
||||
&& IT_CHARPOS (*it) > to_charpos
|
||||
&& IT_CHARPOS (*it) < IT_CHARPOS (ppos_it))
|
||||
SAVE_IT (ppos_it, *it, ppos_data);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -7975,7 +7994,11 @@ move_it_in_display_line_to (struct it *it,
|
|||
if ((op & MOVE_TO_POS) != 0
|
||||
&& !saw_smaller_pos
|
||||
&& IT_CHARPOS (*it) > to_charpos)
|
||||
result = MOVE_POS_MATCH_OR_ZV;
|
||||
{
|
||||
result = MOVE_POS_MATCH_OR_ZV;
|
||||
if (it->bidi_p && IT_CHARPOS (ppos_it) < ZV)
|
||||
RESTORE_IT (it, &ppos_it, ppos_data);
|
||||
}
|
||||
else
|
||||
result = MOVE_NEWLINE_OR_CR;
|
||||
break;
|
||||
|
@ -7991,6 +8014,11 @@ move_it_in_display_line_to (struct it *it,
|
|||
SET_TEXT_POS (this_line_min_pos, IT_CHARPOS (*it), IT_BYTEPOS (*it));
|
||||
if (IT_CHARPOS (*it) < to_charpos)
|
||||
saw_smaller_pos = 1;
|
||||
if (it->bidi_p
|
||||
&& (op & MOVE_TO_POS)
|
||||
&& IT_CHARPOS (*it) >= to_charpos
|
||||
&& IT_CHARPOS (*it) < IT_CHARPOS (ppos_it))
|
||||
SAVE_IT (ppos_it, *it, ppos_data);
|
||||
|
||||
/* Stop if lines are truncated and IT's current x-position is
|
||||
past the right edge of the window now. */
|
||||
|
@ -8000,10 +8028,21 @@ move_it_in_display_line_to (struct it *it,
|
|||
if (!FRAME_WINDOW_P (it->f)
|
||||
|| IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
|
||||
{
|
||||
if (!get_next_display_element (it)
|
||||
|| BUFFER_POS_REACHED_P ())
|
||||
int at_eob_p = 0;
|
||||
|
||||
if ((at_eob_p = !get_next_display_element (it))
|
||||
|| BUFFER_POS_REACHED_P ()
|
||||
/* If we are past TO_CHARPOS, but never saw any
|
||||
character positions smaller than TO_CHARPOS,
|
||||
return MOVE_POS_MATCH_OR_ZV, like the
|
||||
unidirectional display did. */
|
||||
|| ((op & MOVE_TO_POS) != 0
|
||||
&& !saw_smaller_pos
|
||||
&& IT_CHARPOS (*it) > to_charpos))
|
||||
{
|
||||
result = MOVE_POS_MATCH_OR_ZV;
|
||||
if (it->bidi_p && !at_eob_p && IT_CHARPOS (ppos_it) < ZV)
|
||||
RESTORE_IT (it, &ppos_it, ppos_data);
|
||||
break;
|
||||
}
|
||||
if (ITERATOR_AT_END_OF_LINE_P (it))
|
||||
|
@ -8012,6 +8051,15 @@ move_it_in_display_line_to (struct it *it,
|
|||
break;
|
||||
}
|
||||
}
|
||||
else if ((op & MOVE_TO_POS) != 0
|
||||
&& !saw_smaller_pos
|
||||
&& IT_CHARPOS (*it) > to_charpos)
|
||||
{
|
||||
result = MOVE_POS_MATCH_OR_ZV;
|
||||
if (it->bidi_p && IT_CHARPOS (ppos_it) < ZV)
|
||||
RESTORE_IT (it, &ppos_it, ppos_data);
|
||||
break;
|
||||
}
|
||||
result = MOVE_LINE_TRUNCATED;
|
||||
break;
|
||||
}
|
||||
|
@ -8035,6 +8083,8 @@ move_it_in_display_line_to (struct it *it,
|
|||
xfree (atx_data);
|
||||
if (wrap_data)
|
||||
xfree (wrap_data);
|
||||
if (ppos_data)
|
||||
xfree (ppos_data);
|
||||
|
||||
/* Restore the iterator settings altered at the beginning of this
|
||||
function. */
|
||||
|
|
Loading…
Add table
Reference in a new issue