diff options
| author | Eli Zaretskii | 2011-07-23 13:42:24 +0300 |
|---|---|---|
| committer | Eli Zaretskii | 2011-07-23 13:42:24 +0300 |
| commit | c1734fbd6fa365e362c600b7b94c40b13401c255 (patch) | |
| tree | 13ca21188a81d26cf89e9ddb1ac6a4f929f11fca /src | |
| parent | b6d5a68964e812af176a6217882add25703914b2 (diff) | |
| download | emacs-c1734fbd6fa365e362c600b7b94c40b13401c255.tar.gz emacs-c1734fbd6fa365e362c600b7b94c40b13401c255.zip | |
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.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 8 | ||||
| -rw-r--r-- | src/xdisp.c | 58 |
2 files changed, 62 insertions, 4 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index c03acbcfd1c..dd5a1fba871 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,11 @@ | |||
| 1 | 2011-07-23 Eli Zaretskii <eliz@gnu.org> | ||
| 2 | |||
| 3 | * xdisp.c (move_it_in_display_line_to): Record the best matching | ||
| 4 | position for TO_CHARPOS while scanning the line, and restore it on | ||
| 5 | exit if none of the characters scanned was an exact match. Fixes | ||
| 6 | vertical-motion and pos-visible-in-window-p when exact match is | ||
| 7 | impossible due to invisible text, and the lines are truncated. | ||
| 8 | |||
| 1 | 2011-07-22 Eli Zaretskii <eliz@gnu.org> | 9 | 2011-07-22 Eli Zaretskii <eliz@gnu.org> |
| 2 | 10 | ||
| 3 | * xdisp.c (compute_stop_pos_backwards): New function. | 11 | * xdisp.c (compute_stop_pos_backwards): New function. |
diff --git a/src/xdisp.c b/src/xdisp.c index 52b1f484939..a5eb2aa923a 100644 --- a/src/xdisp.c +++ b/src/xdisp.c | |||
| @@ -7620,8 +7620,9 @@ move_it_in_display_line_to (struct it *it, | |||
| 7620 | { | 7620 | { |
| 7621 | enum move_it_result result = MOVE_UNDEFINED; | 7621 | enum move_it_result result = MOVE_UNDEFINED; |
| 7622 | struct glyph_row *saved_glyph_row; | 7622 | struct glyph_row *saved_glyph_row; |
| 7623 | struct it wrap_it, atpos_it, atx_it; | 7623 | struct it wrap_it, atpos_it, atx_it, ppos_it; |
| 7624 | void *wrap_data = NULL, *atpos_data = NULL, *atx_data = NULL; | 7624 | void *wrap_data = NULL, *atpos_data = NULL, *atx_data = NULL; |
| 7625 | void *ppos_data = NULL; | ||
| 7625 | int may_wrap = 0; | 7626 | int may_wrap = 0; |
| 7626 | enum it_method prev_method = it->method; | 7627 | enum it_method prev_method = it->method; |
| 7627 | EMACS_INT prev_pos = IT_CHARPOS (*it); | 7628 | EMACS_INT prev_pos = IT_CHARPOS (*it); |
| @@ -7640,6 +7641,19 @@ move_it_in_display_line_to (struct it *it, | |||
| 7640 | atpos_it.sp = -1; | 7641 | atpos_it.sp = -1; |
| 7641 | atx_it.sp = -1; | 7642 | atx_it.sp = -1; |
| 7642 | 7643 | ||
| 7644 | /* Use ppos_it under bidi reordering to save a copy of IT for the | ||
| 7645 | position > CHARPOS that is the closest to CHARPOS. We restore | ||
| 7646 | that position in IT when we have scanned the entire display line | ||
| 7647 | without finding a match for CHARPOS and all the character | ||
| 7648 | positions are greater than CHARPOS. */ | ||
| 7649 | if (it->bidi_p) | ||
| 7650 | { | ||
| 7651 | SAVE_IT (ppos_it, *it, ppos_data); | ||
| 7652 | SET_TEXT_POS (ppos_it.current.pos, ZV, ZV_BYTE); | ||
| 7653 | if ((op & MOVE_TO_POS) && IT_CHARPOS (*it) >= to_charpos) | ||
| 7654 | SAVE_IT (ppos_it, *it, ppos_data); | ||
| 7655 | } | ||
| 7656 | |||
| 7643 | #define BUFFER_POS_REACHED_P() \ | 7657 | #define BUFFER_POS_REACHED_P() \ |
| 7644 | ((op & MOVE_TO_POS) != 0 \ | 7658 | ((op & MOVE_TO_POS) != 0 \ |
| 7645 | && BUFFERP (it->object) \ | 7659 | && BUFFERP (it->object) \ |
| @@ -7765,6 +7779,11 @@ move_it_in_display_line_to (struct it *it, | |||
| 7765 | if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos)) | 7779 | if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos)) |
| 7766 | SET_TEXT_POS (this_line_min_pos, | 7780 | SET_TEXT_POS (this_line_min_pos, |
| 7767 | IT_CHARPOS (*it), IT_BYTEPOS (*it)); | 7781 | IT_CHARPOS (*it), IT_BYTEPOS (*it)); |
| 7782 | if (it->bidi_p | ||
| 7783 | && (op & MOVE_TO_POS) | ||
| 7784 | && IT_CHARPOS (*it) > to_charpos | ||
| 7785 | && IT_CHARPOS (*it) < IT_CHARPOS (ppos_it)) | ||
| 7786 | SAVE_IT (ppos_it, *it, ppos_data); | ||
| 7768 | continue; | 7787 | continue; |
| 7769 | } | 7788 | } |
| 7770 | 7789 | ||
| @@ -7975,7 +7994,11 @@ move_it_in_display_line_to (struct it *it, | |||
| 7975 | if ((op & MOVE_TO_POS) != 0 | 7994 | if ((op & MOVE_TO_POS) != 0 |
| 7976 | && !saw_smaller_pos | 7995 | && !saw_smaller_pos |
| 7977 | && IT_CHARPOS (*it) > to_charpos) | 7996 | && IT_CHARPOS (*it) > to_charpos) |
| 7978 | result = MOVE_POS_MATCH_OR_ZV; | 7997 | { |
| 7998 | result = MOVE_POS_MATCH_OR_ZV; | ||
| 7999 | if (it->bidi_p && IT_CHARPOS (ppos_it) < ZV) | ||
| 8000 | RESTORE_IT (it, &ppos_it, ppos_data); | ||
| 8001 | } | ||
| 7979 | else | 8002 | else |
| 7980 | result = MOVE_NEWLINE_OR_CR; | 8003 | result = MOVE_NEWLINE_OR_CR; |
| 7981 | break; | 8004 | break; |
| @@ -7991,6 +8014,11 @@ move_it_in_display_line_to (struct it *it, | |||
| 7991 | SET_TEXT_POS (this_line_min_pos, IT_CHARPOS (*it), IT_BYTEPOS (*it)); | 8014 | SET_TEXT_POS (this_line_min_pos, IT_CHARPOS (*it), IT_BYTEPOS (*it)); |
| 7992 | if (IT_CHARPOS (*it) < to_charpos) | 8015 | if (IT_CHARPOS (*it) < to_charpos) |
| 7993 | saw_smaller_pos = 1; | 8016 | saw_smaller_pos = 1; |
| 8017 | if (it->bidi_p | ||
| 8018 | && (op & MOVE_TO_POS) | ||
| 8019 | && IT_CHARPOS (*it) >= to_charpos | ||
| 8020 | && IT_CHARPOS (*it) < IT_CHARPOS (ppos_it)) | ||
| 8021 | SAVE_IT (ppos_it, *it, ppos_data); | ||
| 7994 | 8022 | ||
| 7995 | /* Stop if lines are truncated and IT's current x-position is | 8023 | /* Stop if lines are truncated and IT's current x-position is |
| 7996 | past the right edge of the window now. */ | 8024 | past the right edge of the window now. */ |
| @@ -8000,10 +8028,21 @@ move_it_in_display_line_to (struct it *it, | |||
| 8000 | if (!FRAME_WINDOW_P (it->f) | 8028 | if (!FRAME_WINDOW_P (it->f) |
| 8001 | || IT_OVERFLOW_NEWLINE_INTO_FRINGE (it)) | 8029 | || IT_OVERFLOW_NEWLINE_INTO_FRINGE (it)) |
| 8002 | { | 8030 | { |
| 8003 | if (!get_next_display_element (it) | 8031 | int at_eob_p = 0; |
| 8004 | || BUFFER_POS_REACHED_P ()) | 8032 | |
| 8033 | if ((at_eob_p = !get_next_display_element (it)) | ||
| 8034 | || BUFFER_POS_REACHED_P () | ||
| 8035 | /* If we are past TO_CHARPOS, but never saw any | ||
| 8036 | character positions smaller than TO_CHARPOS, | ||
| 8037 | return MOVE_POS_MATCH_OR_ZV, like the | ||
| 8038 | unidirectional display did. */ | ||
| 8039 | || ((op & MOVE_TO_POS) != 0 | ||
| 8040 | && !saw_smaller_pos | ||
| 8041 | && IT_CHARPOS (*it) > to_charpos)) | ||
| 8005 | { | 8042 | { |
| 8006 | result = MOVE_POS_MATCH_OR_ZV; | 8043 | result = MOVE_POS_MATCH_OR_ZV; |
| 8044 | if (it->bidi_p && !at_eob_p && IT_CHARPOS (ppos_it) < ZV) | ||
| 8045 | RESTORE_IT (it, &ppos_it, ppos_data); | ||
| 8007 | break; | 8046 | break; |
| 8008 | } | 8047 | } |
| 8009 | if (ITERATOR_AT_END_OF_LINE_P (it)) | 8048 | if (ITERATOR_AT_END_OF_LINE_P (it)) |
| @@ -8012,6 +8051,15 @@ move_it_in_display_line_to (struct it *it, | |||
| 8012 | break; | 8051 | break; |
| 8013 | } | 8052 | } |
| 8014 | } | 8053 | } |
| 8054 | else if ((op & MOVE_TO_POS) != 0 | ||
| 8055 | && !saw_smaller_pos | ||
| 8056 | && IT_CHARPOS (*it) > to_charpos) | ||
| 8057 | { | ||
| 8058 | result = MOVE_POS_MATCH_OR_ZV; | ||
| 8059 | if (it->bidi_p && IT_CHARPOS (ppos_it) < ZV) | ||
| 8060 | RESTORE_IT (it, &ppos_it, ppos_data); | ||
| 8061 | break; | ||
| 8062 | } | ||
| 8015 | result = MOVE_LINE_TRUNCATED; | 8063 | result = MOVE_LINE_TRUNCATED; |
| 8016 | break; | 8064 | break; |
| 8017 | } | 8065 | } |
| @@ -8035,6 +8083,8 @@ move_it_in_display_line_to (struct it *it, | |||
| 8035 | xfree (atx_data); | 8083 | xfree (atx_data); |
| 8036 | if (wrap_data) | 8084 | if (wrap_data) |
| 8037 | xfree (wrap_data); | 8085 | xfree (wrap_data); |
| 8086 | if (ppos_data) | ||
| 8087 | xfree (ppos_data); | ||
| 8038 | 8088 | ||
| 8039 | /* Restore the iterator settings altered at the beginning of this | 8089 | /* Restore the iterator settings altered at the beginning of this |
| 8040 | function. */ | 8090 | function. */ |