diff options
| author | Eli Zaretskii | 2014-03-23 17:57:25 +0200 |
|---|---|---|
| committer | Eli Zaretskii | 2014-03-23 17:57:25 +0200 |
| commit | 88c569ef11aa1d9e98bca49e7ac570942276eb3d (patch) | |
| tree | 618271f8246c930e9ecaa0006d8e1ddd48cf0216 /src | |
| parent | f1e06f7bffc1407f7e597f714b2969fc6d1d8eed (diff) | |
| download | emacs-88c569ef11aa1d9e98bca49e7ac570942276eb3d.tar.gz emacs-88c569ef11aa1d9e98bca49e7ac570942276eb3d.zip | |
Fix bug #17047 with cursor motion when invisible text starts a line.
src/xdisp.c (redisplay_window): If all previous attempts to find the
cursor row failed, try a few alternatives before falling back to
the top-most row of the window. Use row_containing_pos.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 6 | ||||
| -rw-r--r-- | src/xdisp.c | 46 |
2 files changed, 48 insertions, 4 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index e8ae781bf4d..a9a0ebbe4a1 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,9 @@ | |||
| 1 | 2014-03-23 Eli Zaretskii <eliz@gnu.org> | ||
| 2 | |||
| 3 | * xdisp.c (redisplay_window): If all previous attempts to find the | ||
| 4 | cursor row failed, try a few alternatives before falling back to | ||
| 5 | the top-most row of the window. (Bug#17047) | ||
| 6 | |||
| 1 | 2014-03-22 Daniel Colascione <dancol@dancol.org> | 7 | 2014-03-22 Daniel Colascione <dancol@dancol.org> |
| 2 | 8 | ||
| 3 | * process.c (conv_sockaddr_to_lisp): When extracting the string | 9 | * process.c (conv_sockaddr_to_lisp): When extracting the string |
diff --git a/src/xdisp.c b/src/xdisp.c index 6f39324d2f0..53bd46328f2 100644 --- a/src/xdisp.c +++ b/src/xdisp.c | |||
| @@ -16400,12 +16400,50 @@ redisplay_window (Lisp_Object window, bool just_this_one_p) | |||
| 16400 | /* Consider the following case: Window starts at BEGV, there is | 16400 | /* Consider the following case: Window starts at BEGV, there is |
| 16401 | invisible, intangible text at BEGV, so that display starts at | 16401 | invisible, intangible text at BEGV, so that display starts at |
| 16402 | some point START > BEGV. It can happen that we are called with | 16402 | some point START > BEGV. It can happen that we are called with |
| 16403 | PT somewhere between BEGV and START. Try to handle that case. */ | 16403 | PT somewhere between BEGV and START. Try to handle that case, |
| 16404 | and similar ones. */ | ||
| 16404 | if (w->cursor.vpos < 0) | 16405 | if (w->cursor.vpos < 0) |
| 16405 | { | 16406 | { |
| 16406 | struct glyph_row *row = w->current_matrix->rows; | 16407 | /* First, try locating the proper glyph row for PT. */ |
| 16407 | if (row->mode_line_p) | 16408 | struct glyph_row *row = |
| 16408 | ++row; | 16409 | row_containing_pos (w, PT, w->current_matrix->rows, NULL, 0); |
| 16410 | |||
| 16411 | /* Sometimes point is at the beginning of invisible text that is | ||
| 16412 | before the 1st character displayed in the row. In that case, | ||
| 16413 | row_containing_pos fails to find the row, because no glyphs | ||
| 16414 | with appropriate buffer positions are present in the row. | ||
| 16415 | Therefore, we next try to find the row which shows the 1st | ||
| 16416 | position after the invisible text. */ | ||
| 16417 | if (!row) | ||
| 16418 | { | ||
| 16419 | Lisp_Object val = | ||
| 16420 | get_char_property_and_overlay (make_number (PT), Qinvisible, | ||
| 16421 | Qnil, NULL); | ||
| 16422 | |||
| 16423 | if (TEXT_PROP_MEANS_INVISIBLE (val)) | ||
| 16424 | { | ||
| 16425 | ptrdiff_t alt_pos; | ||
| 16426 | Lisp_Object invis_end = | ||
| 16427 | Fnext_single_char_property_change (make_number (PT), Qinvisible, | ||
| 16428 | Qnil, Qnil); | ||
| 16429 | |||
| 16430 | if (NATNUMP (invis_end)) | ||
| 16431 | alt_pos = XFASTINT (invis_end); | ||
| 16432 | else | ||
| 16433 | alt_pos = ZV; | ||
| 16434 | row = row_containing_pos (w, alt_pos, w->current_matrix->rows, | ||
| 16435 | NULL, 0); | ||
| 16436 | } | ||
| 16437 | } | ||
| 16438 | /* Finally, fall back on the first row of the window after the | ||
| 16439 | header line (if any). This is slightly better than not | ||
| 16440 | displaying the cursor at all. */ | ||
| 16441 | if (!row) | ||
| 16442 | { | ||
| 16443 | row = w->current_matrix->rows; | ||
| 16444 | if (row->mode_line_p) | ||
| 16445 | ++row; | ||
| 16446 | } | ||
| 16409 | set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0); | 16447 | set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0); |
| 16410 | } | 16448 | } |
| 16411 | 16449 | ||