From 8610fe8b84e22f5d962f5e480001748a6687a3b2 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Wed, 24 Aug 2011 18:51:56 +0300 Subject: [PATCH] Fix cursor movement in R2L text within L2R paragraphs. src/xdisp.c (set_cursor_from_row): Consider candidate row a win if its glyph represents a newline and point is on that newline. Fixes cursor positioning on the newline at EOL of R2L text within L2R paragraph, and vice versa. (try_cursor_movement): Check continued rows, in addition to continuation rows. Fixes unwarranted scroll when point enters a continued line of R2L text within an L2R paragraph, or vice versa. (cursor_row_p): Consider the case of point being equal to MATRIX_ROW_END_CHARPOS. Prevents cursor being stuck when moving from the end of a short line to the beginning of a continued line of R2L text within L2R paragraph. (RECORD_MAX_MIN_POS): For max_pos, use IT_CHARPOS even for composed characters. --- src/ChangeLog | 13 +++++++++++++ src/xdisp.c | 21 +++++++++++++++------ 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index d4d6a4c4bbd..b9c627bf160 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -2,6 +2,19 @@ * xdisp.c (Fcurrent_bidi_paragraph_direction): For unibyte buffers, return left-to-right. + (set_cursor_from_row): Consider candidate row a win if its glyph + represents a newline and point is on that newline. Fixes cursor + positioning on the newline at EOL of R2L text within L2R + paragraph, and vice versa. + (try_cursor_movement): Check continued rows, in addition to + continuation rows. Fixes unwarranted scroll when point enters a + continued line of R2L text within an L2R paragraph, or vice versa. + (cursor_row_p): Consider the case of point being equal to + MATRIX_ROW_END_CHARPOS. Prevents cursor being stuck when moving + from the end of a short line to the beginning of a continued line + of R2L text within L2R paragraph. + (RECORD_MAX_MIN_POS): For max_pos, use IT_CHARPOS even for + composed characters. * bidi.c (bidi_check_type): Use xassert. (bidi_cache_iterator_state): Update the disp_pos and disp_prop_p diff --git a/src/xdisp.c b/src/xdisp.c index 8b3a71027b6..4ed08e72e19 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -13796,7 +13796,14 @@ set_cursor_from_row (struct window *w, struct glyph_row *row, && glyph->charpos != pt_old))))) return 0; /* If this candidate gives an exact match, use that. */ - if (!(BUFFERP (glyph->object) && glyph->charpos == pt_old) + if (!((BUFFERP (glyph->object) && glyph->charpos == pt_old) + /* If this candidate is a glyph created for the + terminating newline of a line, and point is on that + newline, it wins because it's an exact match. */ + || (!row->continued_p + && INTEGERP (glyph->object) + && glyph->charpos == 0 + && pt_old == MATRIX_ROW_END_CHARPOS (row) - 1)) /* Otherwise, keep the candidate that comes from a row spanning less buffer positions. This may win when one or both candidate positions are on glyphs that came from @@ -14578,7 +14585,8 @@ try_cursor_movement (Lisp_Object window, struct text_pos startp, int *scroll_ste } ++row; } - while ((MATRIX_ROW_CONTINUATION_LINE_P (row) + while (((MATRIX_ROW_CONTINUATION_LINE_P (row) + || row->continued_p) && MATRIX_ROW_BOTTOM_Y (row) <= last_y) || (MATRIX_ROW_START_CHARPOS (row) == PT && MATRIX_ROW_BOTTOM_Y (row) < last_y)); @@ -18009,7 +18017,8 @@ cursor_row_p (struct glyph_row *row) { int result = 1; - if (PT == CHARPOS (row->end.pos)) + if (PT == CHARPOS (row->end.pos) + || PT == MATRIX_ROW_END_CHARPOS (row)) { /* Suppose the row ends on a string. Unless the row is continued, that means it ends on a newline @@ -18404,10 +18413,10 @@ display_line (struct it *it) min_pos = current_pos; \ min_bpos = current_bpos; \ } \ - if (current_pos > max_pos) \ + if (IT_CHARPOS (*it) > max_pos) \ { \ - max_pos = current_pos; \ - max_bpos = current_bpos; \ + max_pos = IT_CHARPOS (*it); \ + max_bpos = IT_BYTEPOS (*it); \ } \ } \ while (0) -- 2.39.2