diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/xdisp.c | 64 |
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]; |