[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
master 55c25e73d4: Fix C-n/C-p inside bidirectional text
From: |
Eli Zaretskii |
Subject: |
master 55c25e73d4: Fix C-n/C-p inside bidirectional text |
Date: |
Sat, 6 Aug 2022 09:25:48 -0400 (EDT) |
branch: master
commit 55c25e73d46685e4b4423b13b0d3287fee170386
Author: Eli Zaretskii <eliz@gnu.org>
Commit: Eli Zaretskii <eliz@gnu.org>
Fix C-n/C-p inside bidirectional text
* src/xdisp.c (move_it_by_lines, try_cursor_movement): Handle
glyph rows whose direction of increasing buffer positions is
reverse of the normal: going down in the window makes buffer
positions higher.
* src/indent.c (Fvertical_motion): When looking for the last glyph
row occupied by point, take into account the bidi iteration
direction.
---
src/indent.c | 10 +++++++++-
src/xdisp.c | 41 +++++++++++++++++++++++++++++++++++++----
2 files changed, 46 insertions(+), 5 deletions(-)
diff --git a/src/indent.c b/src/indent.c
index fd2e763665..d2dfaee254 100644
--- a/src/indent.c
+++ b/src/indent.c
@@ -2345,7 +2345,15 @@ whether or not it is currently displayed in some window.
*/)
last line that it occupies. */
if (it_start < ZV)
{
- while (IT_CHARPOS (it) <= it_start)
+ if ((it.bidi_it.scan_dir > 0)
+ ? IT_CHARPOS (it) < it_start
+ : IT_CHARPOS (it) > it_start)
+ {
+ it.vpos = 0;
+ it.current_y = 0;
+ move_it_by_lines (&it, 1);
+ }
+ while (IT_CHARPOS (it) == it_start)
{
it.vpos = 0;
it.current_y = 0;
diff --git a/src/xdisp.c b/src/xdisp.c
index 3ca0022a6d..c756e7f04f 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -10956,15 +10956,21 @@ move_it_by_lines (struct it *it, ptrdiff_t dvpos)
int nchars_per_row
= (it->last_visible_x - it->first_visible_x) / FRAME_COLUMN_WIDTH
(it->f);
bool hit_pos_limit = false;
+ bool reverse_rows = false;
ptrdiff_t pos_limit;
/* Start at the beginning of the screen line containing IT's
position. This may actually move vertically backwards,
in case of overlays, so adjust dvpos accordingly. */
dvpos += it->vpos;
+ start_charpos = IT_CHARPOS (*it);
move_it_vertically_backward (it, 0);
dvpos -= it->vpos;
+ /* Do we have glyph rows whose positions _increase_ as we go up? */
+ if (IT_CHARPOS (*it) > start_charpos)
+ reverse_rows = true;
+
/* Go back -DVPOS buffer lines, but no farther than -DVPOS full
screen lines, and reseat the iterator there. */
start_charpos = IT_CHARPOS (*it);
@@ -11015,7 +11021,8 @@ move_it_by_lines (struct it *it, ptrdiff_t dvpos)
SAVE_IT (it2, *it, it2data);
move_it_to (it, -1, -1, -1, it->vpos + delta, MOVE_TO_VPOS);
/* Move back again if we got too far ahead. */
- if (IT_CHARPOS (*it) >= start_charpos)
+ if ((IT_CHARPOS (*it) >= start_charpos && !reverse_rows)
+ || (IT_CHARPOS (*it) <= start_charpos && reverse_rows))
RESTORE_IT (it, &it2, it2data);
else
bidi_unshelve_cache (it2data, true);
@@ -18837,6 +18844,8 @@ try_cursor_movement (Lisp_Object window, struct
text_pos startp,
{
/* Cursor has to be moved backward. Note that PT >=
CHARPOS (startp) because of the outer if-statement. */
+ struct glyph_row *row0 = row;
+
while (!row->mode_line_p
&& (MATRIX_ROW_START_CHARPOS (row) > PT
|| (MATRIX_ROW_START_CHARPOS (row) == PT
@@ -18851,6 +18860,23 @@ try_cursor_movement (Lisp_Object window, struct
text_pos startp,
--row;
}
+ /* With bidi-reordered rows we can have buffer positions
+ _decrease_ when going down by rows. If we haven't
+ found our row in the loop above, give it another try
+ now going in the other direction from the original row. */
+ if (!(MATRIX_ROW_START_CHARPOS (row) <= PT
+ && PT <= MATRIX_ROW_END_CHARPOS (row))
+ && row0->continued_p)
+ {
+ row = row0;
+ while (MATRIX_ROW_START_CHARPOS (row) > PT
+ && MATRIX_ROW_BOTTOM_Y (row) < last_y)
+ {
+ eassert (row->enabled_p);
+ ++row;
+ }
+ }
+
/* Consider the following case: Window starts at BEGV,
there is invisible, intangible text at BEGV, so that
display starts at some point START > BEGV. It can
@@ -18874,9 +18900,16 @@ try_cursor_movement (Lisp_Object window, struct
text_pos startp,
&& !cursor_row_p (row))
++row;
- /* If within the scroll margin, scroll. */
- if (row->y < top_scroll_margin
- && CHARPOS (startp) != BEGV)
+ /* If within the scroll margin, either the top one or
+ the bottom one, scroll. */
+ if ((row->y < top_scroll_margin
+ && CHARPOS (startp) != BEGV)
+ || MATRIX_ROW_BOTTOM_Y (row) > last_y
+ || PT > MATRIX_ROW_END_CHARPOS (row)
+ || (MATRIX_ROW_BOTTOM_Y (row) == last_y
+ && PT == MATRIX_ROW_END_CHARPOS (row)
+ && !row->ends_at_zv_p
+ && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
scroll_p = true;
}
else
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- master 55c25e73d4: Fix C-n/C-p inside bidirectional text,
Eli Zaretskii <=