aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/xdisp.c64
1 files changed, 61 insertions, 3 deletions
diff --git a/src/xdisp.c b/src/xdisp.c
index 009074ede9d..851e1984cc7 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -9460,6 +9460,14 @@ set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
9460{ 9460{
9461 struct glyph *glyph = row->glyphs[TEXT_AREA]; 9461 struct glyph *glyph = row->glyphs[TEXT_AREA];
9462 struct glyph *end = glyph + row->used[TEXT_AREA]; 9462 struct glyph *end = glyph + row->used[TEXT_AREA];
9463 /* The first glyph that starts a sequence of glyphs from string. */
9464 struct glyph *string_start;
9465 /* The X coordinate of string_start. */
9466 int string_start_x;
9467 /* The last known character position. */
9468 int last_pos = MATRIX_ROW_START_CHARPOS (row) + delta;
9469 /* The last known character position before string_start. */
9470 int string_before_pos;
9463 int x = row->x; 9471 int x = row->x;
9464 int pt_old = PT - delta; 9472 int pt_old = PT - delta;
9465 9473
@@ -9475,13 +9483,63 @@ set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
9475 ++glyph; 9483 ++glyph;
9476 } 9484 }
9477 9485
9486 string_start = NULL;
9478 while (glyph < end 9487 while (glyph < end
9479 && !INTEGERP (glyph->object) 9488 && !INTEGERP (glyph->object)
9480 && (!BUFFERP (glyph->object) 9489 && (!BUFFERP (glyph->object)
9481 || glyph->charpos < pt_old)) 9490 || (last_pos = glyph->charpos) < pt_old))
9482 { 9491 {
9483 x += glyph->pixel_width; 9492 if (! STRINGP (glyph->object))
9484 ++glyph; 9493 {
9494 string_start = NULL;
9495 x += glyph->pixel_width;
9496 ++glyph;
9497 }
9498 else
9499 {
9500 string_before_pos = last_pos;
9501 string_start = glyph;
9502 string_start_x = x;
9503 /* Skip all glyphs from string. */
9504 do
9505 {
9506 x += glyph->pixel_width;
9507 ++glyph;
9508 }
9509 while (glyph < end && STRINGP (glyph->object));
9510 }
9511 }
9512
9513 if (string_start
9514 && (glyph == end || !BUFFERP (glyph->object) || last_pos > pt_old))
9515 {
9516 /* We may have skipped over point because the previous glyphs
9517 are from string. As there's no easy way to know the
9518 character position of the current glyph, find the correct
9519 glyph on point by scanning from string_start again. */
9520 Lisp_Object pos, limit;
9521
9522 limit = make_number (MATRIX_ROW_END_CHARPOS (row) + delta);
9523 glyph = string_start;
9524 x = string_start_x;
9525 pos = make_number (string_buffer_position (w, glyph->object,
9526 string_before_pos));
9527 pos = Fnext_single_char_property_change (pos, Qdisplay, Qnil, limit);
9528 while (XINT (pos) <= pt_old)
9529 {
9530 /* Skip glyphs from the same string. */
9531 do
9532 {
9533 x += glyph->pixel_width;
9534 ++glyph;
9535 }
9536 while (glyph < end
9537 && EQ (glyph->object, string_start->object));
9538 if (glyph == end || !STRINGP (glyph->object))
9539 break;
9540 string_start = glyph;
9541 pos = Fnext_single_char_property_change (pos, Qdisplay, Qnil, limit);
9542 }
9485 } 9543 }
9486 9544
9487 w->cursor.hpos = glyph - row->glyphs[TEXT_AREA]; 9545 w->cursor.hpos = glyph - row->glyphs[TEXT_AREA];