diff options
| author | Eli Zaretskii | 2018-03-07 20:40:44 +0200 |
|---|---|---|
| committer | Eli Zaretskii | 2018-06-02 12:15:14 +0300 |
| commit | 8b2b4b580c38d7f1d95f8b2bf1f7c6ad8b9207b9 (patch) | |
| tree | 86b9e59b3c5dd47b01064035c45466ec59cb66b4 /src | |
| parent | de69d28458e52487ebb9db47b100c23a16ab6093 (diff) | |
| download | emacs-8b2b4b580c38d7f1d95f8b2bf1f7c6ad8b9207b9.tar.gz emacs-8b2b4b580c38d7f1d95f8b2bf1f7c6ad8b9207b9.zip | |
Fix display of TABs in hscrolled windows with line numbers
* src/dispextern.h (struct it): New members tab_offset and
line_number_produced_p.
* src/xdisp.c (display_line): Don't set row->x to a negative value
if line numbers are being displayed. (Bug#30582)
Reset the line_number_produced_p flag before laying out the glyph
row.
(x_produce_glyphs): Use the line_number_produced_p flag to decide
whether to offset the X coordinate due to line-number display.
Use the tab_offset member to restore the original TAB width for
alignment purposes.
(move_it_in_display_line_to): Don't produce line numbers when moving
in hscrolled window to the left of first_visible_x.
(maybe_produce_line_number): Set the line_number_produced_p flag.
(Bug#30584)
* src/term.c (produce_glyphs): Correct TAB width only when
line_number_produced_p flag is set.
(cherry picked from commit 1ac190553886ff20817d3dd218464e2fc6f9e42a)
Diffstat (limited to 'src')
| -rw-r--r-- | src/dispextern.h | 10 | ||||
| -rw-r--r-- | src/term.c | 4 | ||||
| -rw-r--r-- | src/xdisp.c | 51 |
3 files changed, 54 insertions, 11 deletions
diff --git a/src/dispextern.h b/src/dispextern.h index d3e068677f0..29c401c61e5 100644 --- a/src/dispextern.h +++ b/src/dispextern.h | |||
| @@ -2462,6 +2462,10 @@ struct it | |||
| 2462 | descent/ascent (line-height property). Reset after this glyph. */ | 2462 | descent/ascent (line-height property). Reset after this glyph. */ |
| 2463 | bool_bf constrain_row_ascent_descent_p : 1; | 2463 | bool_bf constrain_row_ascent_descent_p : 1; |
| 2464 | 2464 | ||
| 2465 | /* If true, glyphs for line number display were already produced for | ||
| 2466 | the current row. */ | ||
| 2467 | bool_bf line_number_produced_p : 1; | ||
| 2468 | |||
| 2465 | enum line_wrap_method line_wrap; | 2469 | enum line_wrap_method line_wrap; |
| 2466 | 2470 | ||
| 2467 | /* The ID of the default face to use. One of DEFAULT_FACE_ID, | 2471 | /* The ID of the default face to use. One of DEFAULT_FACE_ID, |
| @@ -2641,6 +2645,12 @@ struct it | |||
| 2641 | /* The line number of point's line, or zero if not computed yet. */ | 2645 | /* The line number of point's line, or zero if not computed yet. */ |
| 2642 | ptrdiff_t pt_lnum; | 2646 | ptrdiff_t pt_lnum; |
| 2643 | 2647 | ||
| 2648 | /* Number of pixels to offset tab stops due to width fixup of the | ||
| 2649 | first glyph that crosses first_visible_x. This is only needed on | ||
| 2650 | GUI frames, only when display-line-numbers is in effect, and only | ||
| 2651 | in hscrolled windows. */ | ||
| 2652 | int tab_offset; | ||
| 2653 | |||
| 2644 | /* Left fringe bitmap number (enum fringe_bitmap_type). */ | 2654 | /* Left fringe bitmap number (enum fringe_bitmap_type). */ |
| 2645 | unsigned left_user_fringe_bitmap : FRINGE_ID_BITS; | 2655 | unsigned left_user_fringe_bitmap : FRINGE_ID_BITS; |
| 2646 | 2656 | ||
diff --git a/src/term.c b/src/term.c index b3707da70a2..f542fc527c4 100644 --- a/src/term.c +++ b/src/term.c | |||
| @@ -1591,13 +1591,13 @@ produce_glyphs (struct it *it) | |||
| 1591 | + it->continuation_lines_width); | 1591 | + it->continuation_lines_width); |
| 1592 | int x0 = absolute_x; | 1592 | int x0 = absolute_x; |
| 1593 | /* Adjust for line numbers. */ | 1593 | /* Adjust for line numbers. */ |
| 1594 | if (!NILP (Vdisplay_line_numbers)) | 1594 | if (!NILP (Vdisplay_line_numbers) && it->line_number_produced_p) |
| 1595 | absolute_x -= it->lnum_pixel_width; | 1595 | absolute_x -= it->lnum_pixel_width; |
| 1596 | int next_tab_x | 1596 | int next_tab_x |
| 1597 | = (((1 + absolute_x + it->tab_width - 1) | 1597 | = (((1 + absolute_x + it->tab_width - 1) |
| 1598 | / it->tab_width) | 1598 | / it->tab_width) |
| 1599 | * it->tab_width); | 1599 | * it->tab_width); |
| 1600 | if (!NILP (Vdisplay_line_numbers)) | 1600 | if (!NILP (Vdisplay_line_numbers) && it->line_number_produced_p) |
| 1601 | next_tab_x += it->lnum_pixel_width; | 1601 | next_tab_x += it->lnum_pixel_width; |
| 1602 | int nspaces; | 1602 | int nspaces; |
| 1603 | 1603 | ||
diff --git a/src/xdisp.c b/src/xdisp.c index 479a4c5a311..5a301e4090f 100644 --- a/src/xdisp.c +++ b/src/xdisp.c | |||
| @@ -8718,8 +8718,12 @@ move_it_in_display_line_to (struct it *it, | |||
| 8718 | 8718 | ||
| 8719 | if (it->hpos == 0) | 8719 | if (it->hpos == 0) |
| 8720 | { | 8720 | { |
| 8721 | /* If line numbers are being displayed, produce a line number. */ | 8721 | /* If line numbers are being displayed, produce a line number. |
| 8722 | if (should_produce_line_number (it)) | 8722 | But don't do that if we are to reach first_visible_x, because |
| 8723 | line numbers are not relevant to stuff that is not visible on | ||
| 8724 | display. */ | ||
| 8725 | if (!((op && MOVE_TO_X) && to_x == it->first_visible_x) | ||
| 8726 | && should_produce_line_number (it)) | ||
| 8723 | { | 8727 | { |
| 8724 | if (it->current_x == it->first_visible_x) | 8728 | if (it->current_x == it->first_visible_x) |
| 8725 | maybe_produce_line_number (it); | 8729 | maybe_produce_line_number (it); |
| @@ -21169,6 +21173,8 @@ maybe_produce_line_number (struct it *it) | |||
| 21169 | it->max_phys_descent = max (it->max_phys_descent, tem_it.max_phys_descent); | 21173 | it->max_phys_descent = max (it->max_phys_descent, tem_it.max_phys_descent); |
| 21170 | } | 21174 | } |
| 21171 | 21175 | ||
| 21176 | it->line_number_produced_p = true; | ||
| 21177 | |||
| 21172 | bidi_unshelve_cache (itdata, false); | 21178 | bidi_unshelve_cache (itdata, false); |
| 21173 | } | 21179 | } |
| 21174 | 21180 | ||
| @@ -21292,6 +21298,8 @@ display_line (struct it *it, int cursor_vpos) | |||
| 21292 | row->displays_text_p = true; | 21298 | row->displays_text_p = true; |
| 21293 | row->starts_in_middle_of_char_p = it->starts_in_middle_of_char_p; | 21299 | row->starts_in_middle_of_char_p = it->starts_in_middle_of_char_p; |
| 21294 | it->starts_in_middle_of_char_p = false; | 21300 | it->starts_in_middle_of_char_p = false; |
| 21301 | it->tab_offset = 0; | ||
| 21302 | it->line_number_produced_p = false; | ||
| 21295 | 21303 | ||
| 21296 | /* Arrange the overlays nicely for our purposes. Usually, we call | 21304 | /* Arrange the overlays nicely for our purposes. Usually, we call |
| 21297 | display_line on only one line at a time, in which case this | 21305 | display_line on only one line at a time, in which case this |
| @@ -21336,6 +21344,10 @@ display_line (struct it *it, int cursor_vpos) | |||
| 21336 | || move_result == MOVE_POS_MATCH_OR_ZV)) | 21344 | || move_result == MOVE_POS_MATCH_OR_ZV)) |
| 21337 | it->current_x = it->first_visible_x; | 21345 | it->current_x = it->first_visible_x; |
| 21338 | 21346 | ||
| 21347 | /* In case move_it_in_display_line_to above "produced" the line | ||
| 21348 | number. */ | ||
| 21349 | it->line_number_produced_p = false; | ||
| 21350 | |||
| 21339 | /* Record the smallest positions seen while we moved over | 21351 | /* Record the smallest positions seen while we moved over |
| 21340 | display elements that are not visible. This is needed by | 21352 | display elements that are not visible. This is needed by |
| 21341 | redisplay_internal for optimizing the case where the cursor | 21353 | redisplay_internal for optimizing the case where the cursor |
| @@ -21555,6 +21567,10 @@ display_line (struct it *it, int cursor_vpos) | |||
| 21555 | row->extra_line_spacing = max (row->extra_line_spacing, | 21567 | row->extra_line_spacing = max (row->extra_line_spacing, |
| 21556 | it->max_extra_line_spacing); | 21568 | it->max_extra_line_spacing); |
| 21557 | if (it->current_x - it->pixel_width < it->first_visible_x | 21569 | if (it->current_x - it->pixel_width < it->first_visible_x |
| 21570 | /* When line numbers are displayed, row->x should not be | ||
| 21571 | offset, as the first glyph after the line number can | ||
| 21572 | never be partially visible. */ | ||
| 21573 | && !line_number_needed | ||
| 21558 | /* In R2L rows, we arrange in extend_face_to_end_of_line | 21574 | /* In R2L rows, we arrange in extend_face_to_end_of_line |
| 21559 | to add a right offset to the line, by a suitable | 21575 | to add a right offset to the line, by a suitable |
| 21560 | change to the stretch glyph that is the leftmost | 21576 | change to the stretch glyph that is the leftmost |
| @@ -21796,7 +21812,8 @@ display_line (struct it *it, int cursor_vpos) | |||
| 21796 | if (it->bidi_p) | 21812 | if (it->bidi_p) |
| 21797 | RECORD_MAX_MIN_POS (it); | 21813 | RECORD_MAX_MIN_POS (it); |
| 21798 | 21814 | ||
| 21799 | if (x < it->first_visible_x && !row->reversed_p) | 21815 | if (x < it->first_visible_x && !row->reversed_p |
| 21816 | && !line_number_needed) | ||
| 21800 | /* Glyph is partially visible, i.e. row starts at | 21817 | /* Glyph is partially visible, i.e. row starts at |
| 21801 | negative X position. Don't do that in R2L | 21818 | negative X position. Don't do that in R2L |
| 21802 | rows, where we arrange to add a right offset to | 21819 | rows, where we arrange to add a right offset to |
| @@ -21812,6 +21829,7 @@ display_line (struct it *it, int cursor_vpos) | |||
| 21812 | be taken care of in produce_special_glyphs. */ | 21829 | be taken care of in produce_special_glyphs. */ |
| 21813 | if (row->reversed_p | 21830 | if (row->reversed_p |
| 21814 | && new_x > it->last_visible_x | 21831 | && new_x > it->last_visible_x |
| 21832 | && !line_number_needed | ||
| 21815 | && !(it->line_wrap == TRUNCATE | 21833 | && !(it->line_wrap == TRUNCATE |
| 21816 | && WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0)) | 21834 | && WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0)) |
| 21817 | { | 21835 | { |
| @@ -28264,8 +28282,14 @@ x_produce_glyphs (struct it *it) | |||
| 28264 | int x = it->current_x + it->continuation_lines_width; | 28282 | int x = it->current_x + it->continuation_lines_width; |
| 28265 | int x0 = x; | 28283 | int x0 = x; |
| 28266 | /* Adjust for line numbers, if needed. */ | 28284 | /* Adjust for line numbers, if needed. */ |
| 28267 | if (!NILP (Vdisplay_line_numbers) && x0 >= it->lnum_pixel_width) | 28285 | if (!NILP (Vdisplay_line_numbers) && it->line_number_produced_p) |
| 28268 | x -= it->lnum_pixel_width; | 28286 | { |
| 28287 | x -= it->lnum_pixel_width; | ||
| 28288 | /* Restore the original TAB width, if required. */ | ||
| 28289 | if (x + it->tab_offset >= it->first_visible_x) | ||
| 28290 | x += it->tab_offset; | ||
| 28291 | } | ||
| 28292 | |||
| 28269 | int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width; | 28293 | int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width; |
| 28270 | 28294 | ||
| 28271 | /* If the distance from the current position to the next tab | 28295 | /* If the distance from the current position to the next tab |
| @@ -28273,10 +28297,19 @@ x_produce_glyphs (struct it *it) | |||
| 28273 | tab stop after that. */ | 28297 | tab stop after that. */ |
| 28274 | if (next_tab_x - x < font->space_width) | 28298 | if (next_tab_x - x < font->space_width) |
| 28275 | next_tab_x += tab_width; | 28299 | next_tab_x += tab_width; |
| 28276 | if (!NILP (Vdisplay_line_numbers) && x0 >= it->lnum_pixel_width) | 28300 | if (!NILP (Vdisplay_line_numbers) && it->line_number_produced_p) |
| 28277 | next_tab_x += (it->lnum_pixel_width | 28301 | { |
| 28278 | - ((it->w->hscroll * font->space_width) | 28302 | next_tab_x += it->lnum_pixel_width; |
| 28279 | % tab_width)); | 28303 | /* If the line is hscrolled, and the TAB starts before |
| 28304 | the first visible pixel, simulate negative row->x. */ | ||
| 28305 | if (x < it->first_visible_x) | ||
| 28306 | { | ||
| 28307 | next_tab_x -= it->first_visible_x - x; | ||
| 28308 | it->tab_offset = it->first_visible_x - x; | ||
| 28309 | } | ||
| 28310 | else | ||
| 28311 | next_tab_x -= it->tab_offset; | ||
| 28312 | } | ||
| 28280 | 28313 | ||
| 28281 | it->pixel_width = next_tab_x - x0; | 28314 | it->pixel_width = next_tab_x - x0; |
| 28282 | it->nglyphs = 1; | 28315 | it->nglyphs = 1; |