aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEli Zaretskii2011-07-23 13:42:24 +0300
committerEli Zaretskii2011-07-23 13:42:24 +0300
commitc1734fbd6fa365e362c600b7b94c40b13401c255 (patch)
tree13ca21188a81d26cf89e9ddb1ac6a4f929f11fca /src
parentb6d5a68964e812af176a6217882add25703914b2 (diff)
downloademacs-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/ChangeLog8
-rw-r--r--src/xdisp.c58
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 @@
12011-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
12011-07-22 Eli Zaretskii <eliz@gnu.org> 92011-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. */