diff options
| -rw-r--r-- | src/ChangeLog | 12 | ||||
| -rw-r--r-- | src/bidi.c | 17 | ||||
| -rw-r--r-- | src/xdisp.c | 46 |
3 files changed, 60 insertions, 15 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 60c835cb100..039c225c1f6 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,15 @@ | |||
| 1 | 2011-08-06 Eli Zaretskii <eliz@gnu.org> | ||
| 2 | |||
| 3 | * xdisp.c (set_cursor_from_row): Fix cursor positioning when a | ||
| 4 | display property strides EOL and includes a newline, as in | ||
| 5 | longlines-mode. (Bug#9254) | ||
| 6 | (move_it_in_display_line_to): Fix vertical-motion in a buffer with | ||
| 7 | word-wrap under bidirectional display. (Bug#9224) | ||
| 8 | |||
| 9 | * bidi.c (bidi_unshelve_cache): Don't reset the cache if JUST_FREE | ||
| 10 | is non-zero, even if the data buffer is NULL. Fixes a crash in | ||
| 11 | vertical-motion with longlines-mode. (Bug#9254) | ||
| 12 | |||
| 1 | 2011-08-05 Eli Zaretskii <eliz@gnu.org> | 13 | 2011-08-05 Eli Zaretskii <eliz@gnu.org> |
| 2 | 14 | ||
| 3 | * bidi.c <bidi_cache_total_alloc>: Now static. | 15 | * bidi.c <bidi_cache_total_alloc>: Now static. |
diff --git a/src/bidi.c b/src/bidi.c index 0db144bea6c..2879198ce31 100644 --- a/src/bidi.c +++ b/src/bidi.c | |||
| @@ -666,7 +666,11 @@ bidi_shelve_cache (void) | |||
| 666 | return databuf; | 666 | return databuf; |
| 667 | } | 667 | } |
| 668 | 668 | ||
| 669 | /* Restore the cache state from a copy stashed away by bidi_shelve_cache. */ | 669 | /* Restore the cache state from a copy stashed away by |
| 670 | bidi_shelve_cache, and free the buffer used to stash that copy. | ||
| 671 | JUST_FREE non-zero means free the buffer, but don't restore the | ||
| 672 | cache; used when the corresponding iterator is discarded instead of | ||
| 673 | being restored. */ | ||
| 670 | void | 674 | void |
| 671 | bidi_unshelve_cache (void *databuf, int just_free) | 675 | bidi_unshelve_cache (void *databuf, int just_free) |
| 672 | { | 676 | { |
| @@ -674,10 +678,13 @@ bidi_unshelve_cache (void *databuf, int just_free) | |||
| 674 | 678 | ||
| 675 | if (!p) | 679 | if (!p) |
| 676 | { | 680 | { |
| 677 | /* A NULL pointer means an empty cache. */ | 681 | if (!just_free) |
| 678 | bidi_cache_start = 0; | 682 | { |
| 679 | bidi_cache_sp = 0; | 683 | /* A NULL pointer means an empty cache. */ |
| 680 | bidi_cache_reset (); | 684 | bidi_cache_start = 0; |
| 685 | bidi_cache_sp = 0; | ||
| 686 | bidi_cache_reset (); | ||
| 687 | } | ||
| 681 | } | 688 | } |
| 682 | else | 689 | else |
| 683 | { | 690 | { |
diff --git a/src/xdisp.c b/src/xdisp.c index 6800dcf694c..02683bad2f1 100644 --- a/src/xdisp.c +++ b/src/xdisp.c | |||
| @@ -8011,13 +8011,19 @@ move_it_in_display_line_to (struct it *it, | |||
| 8011 | positions smaller than TO_CHARPOS, return | 8011 | positions smaller than TO_CHARPOS, return |
| 8012 | MOVE_POS_MATCH_OR_ZV, like the unidirectional display | 8012 | MOVE_POS_MATCH_OR_ZV, like the unidirectional display |
| 8013 | did. */ | 8013 | did. */ |
| 8014 | if (it->bidi_p && (op & MOVE_TO_POS) != 0 | 8014 | if (it->bidi_p && (op & MOVE_TO_POS) != 0) |
| 8015 | && !saw_smaller_pos | ||
| 8016 | && IT_CHARPOS (*it) > to_charpos) | ||
| 8017 | { | 8015 | { |
| 8018 | if (IT_CHARPOS (ppos_it) < ZV) | 8016 | if (!saw_smaller_pos && IT_CHARPOS (*it) > to_charpos) |
| 8019 | RESTORE_IT (it, &ppos_it, ppos_data); | 8017 | { |
| 8020 | goto buffer_pos_reached; | 8018 | if (IT_CHARPOS (ppos_it) < ZV) |
| 8019 | RESTORE_IT (it, &ppos_it, ppos_data); | ||
| 8020 | goto buffer_pos_reached; | ||
| 8021 | } | ||
| 8022 | else if (it->line_wrap == WORD_WRAP && atpos_it.sp >= 0 | ||
| 8023 | && IT_CHARPOS (*it) > to_charpos) | ||
| 8024 | goto buffer_pos_reached; | ||
| 8025 | else | ||
| 8026 | result = MOVE_NEWLINE_OR_CR; | ||
| 8021 | } | 8027 | } |
| 8022 | else | 8028 | else |
| 8023 | result = MOVE_NEWLINE_OR_CR; | 8029 | result = MOVE_NEWLINE_OR_CR; |
| @@ -13287,6 +13293,9 @@ set_cursor_from_row (struct window *w, struct glyph_row *row, | |||
| 13287 | /* Last buffer position covered by an overlay string with an integer | 13293 | /* Last buffer position covered by an overlay string with an integer |
| 13288 | `cursor' property. */ | 13294 | `cursor' property. */ |
| 13289 | EMACS_INT bpos_covered = 0; | 13295 | EMACS_INT bpos_covered = 0; |
| 13296 | /* Non-zero means the display string on which to display the cursor | ||
| 13297 | comes from a text property, not from an overlay. */ | ||
| 13298 | int string_from_text_prop = 0; | ||
| 13290 | 13299 | ||
| 13291 | /* Skip over glyphs not having an object at the start and the end of | 13300 | /* Skip over glyphs not having an object at the start and the end of |
| 13292 | the row. These are special glyphs like truncation marks on | 13301 | the row. These are special glyphs like truncation marks on |
| @@ -13605,9 +13614,14 @@ set_cursor_from_row (struct window *w, struct glyph_row *row, | |||
| 13605 | { | 13614 | { |
| 13606 | Lisp_Object str; | 13615 | Lisp_Object str; |
| 13607 | EMACS_INT tem; | 13616 | EMACS_INT tem; |
| 13617 | /* If the display property covers the newline, we | ||
| 13618 | need to search for it one position farther. */ | ||
| 13619 | EMACS_INT lim = pos_after | ||
| 13620 | + (pos_after == MATRIX_ROW_END_CHARPOS (row) + delta); | ||
| 13608 | 13621 | ||
| 13622 | string_from_text_prop = 0; | ||
| 13609 | str = glyph->object; | 13623 | str = glyph->object; |
| 13610 | tem = string_buffer_position_lim (str, pos, pos_after, 0); | 13624 | tem = string_buffer_position_lim (str, pos, lim, 0); |
| 13611 | if (tem == 0 /* from overlay */ | 13625 | if (tem == 0 /* from overlay */ |
| 13612 | || pos <= tem) | 13626 | || pos <= tem) |
| 13613 | { | 13627 | { |
| @@ -13631,7 +13645,10 @@ set_cursor_from_row (struct window *w, struct glyph_row *row, | |||
| 13631 | EMACS_INT strpos = glyph->charpos; | 13645 | EMACS_INT strpos = glyph->charpos; |
| 13632 | 13646 | ||
| 13633 | if (tem) | 13647 | if (tem) |
| 13634 | cursor = glyph; | 13648 | { |
| 13649 | cursor = glyph; | ||
| 13650 | string_from_text_prop = 1; | ||
| 13651 | } | ||
| 13635 | for ( ; | 13652 | for ( ; |
| 13636 | (row->reversed_p ? glyph > stop : glyph < stop) | 13653 | (row->reversed_p ? glyph > stop : glyph < stop) |
| 13637 | && EQ (glyph->object, str); | 13654 | && EQ (glyph->object, str); |
| @@ -13732,8 +13749,17 @@ set_cursor_from_row (struct window *w, struct glyph_row *row, | |||
| 13732 | /* previous candidate is a glyph from a string that has | 13749 | /* previous candidate is a glyph from a string that has |
| 13733 | a non-nil `cursor' property */ | 13750 | a non-nil `cursor' property */ |
| 13734 | || (STRINGP (g1->object) | 13751 | || (STRINGP (g1->object) |
| 13735 | && !NILP (Fget_char_property (make_number (g1->charpos), | 13752 | && (!NILP (Fget_char_property (make_number (g1->charpos), |
| 13736 | Qcursor, g1->object))))) | 13753 | Qcursor, g1->object)) |
| 13754 | /* pevious candidate is from the same display | ||
| 13755 | string as this one, and the display string | ||
| 13756 | came from a text property */ | ||
| 13757 | || (EQ (g1->object, glyph->object) | ||
| 13758 | && string_from_text_prop) | ||
| 13759 | /* this candidate is from newline and its | ||
| 13760 | position is not an exact match */ | ||
| 13761 | || (INTEGERP (glyph->object) | ||
| 13762 | && glyph->charpos != pt_old))))) | ||
| 13737 | return 0; | 13763 | return 0; |
| 13738 | /* If this candidate gives an exact match, use that. */ | 13764 | /* If this candidate gives an exact match, use that. */ |
| 13739 | if (!(BUFFERP (glyph->object) && glyph->charpos == pt_old) | 13765 | if (!(BUFFERP (glyph->object) && glyph->charpos == pt_old) |