aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPo Lu2024-02-01 16:16:09 +0800
committerPo Lu2024-02-01 16:16:09 +0800
commit881a1ade30d2efacf9fcbd136b8fea722760f36e (patch)
tree3f00756ea293c9c25186c716b0e5cc205894af93 /src
parentb86bc02096c65517b9a29c20635ece100864fc62 (diff)
downloademacs-881a1ade30d2efacf9fcbd136b8fea722760f36e.tar.gz
emacs-881a1ade30d2efacf9fcbd136b8fea722760f36e.zip
Prevent continuation from affecting tab width in/after line prefix
* src/dispextern.h (struct it) <wrap_prefix_width>: New field, synchronized with current_x when producing glyphs for wrap prefixes, and subtracted from it->current_x when computing tab widths. * src/term.c (produce_glyphs): Set wrap_prefix_width. * src/xdisp.c (start_display, display_min_width, move_it_to) (move_it_vertically_backward, move_it_by_lines) (window_text_pixel_size, display_tab_bar_line) (display_tool_bar_line, redisplay_internal, redisplay_window) (try_window_id, insert_left_trunc_glyphs) (extend_face_to_end_of_line, display_line) (Fmove_point_visually): Set or clear wrap_prefix_width as appropriate. (gui_produce_glyphs): Set or clear it->wrap_prefix_width. When computing the base position of a tab character, do not subtract the continuation line width if a line prefix is the current iterator method. Subtract the wrap_prefix_width otherwise, in order that the width of the tab is computed free of influence from the wrap prefix.
Diffstat (limited to 'src')
-rw-r--r--src/dispextern.h10
-rw-r--r--src/term.c8
-rw-r--r--src/xdisp.c74
3 files changed, 74 insertions, 18 deletions
diff --git a/src/dispextern.h b/src/dispextern.h
index 84b9dadc184..5387cb45603 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -2752,6 +2752,16 @@ struct it
2752 pixel_width with each call to produce_glyphs. */ 2752 pixel_width with each call to produce_glyphs. */
2753 int current_x; 2753 int current_x;
2754 2754
2755 /* Pixel position within a display line with a wrap prefix. Updated
2756 to reflect current_x in produce_glyphs when producing glyphs from
2757 a prefix string and continuation_lines_width > 0, which is to
2758 say, from a wrap prefix.
2759
2760 Such updates are unnecessary where it is impossible for a wrap
2761 prefix to be active, e.g. when continuation lines are being
2762 produced. */
2763 int wrap_prefix_width;
2764
2755 /* Accumulated width of continuation lines. If > 0, this means we 2765 /* Accumulated width of continuation lines. If > 0, this means we
2756 are currently in a continuation line. This is initially zero and 2766 are currently in a continuation line. This is initially zero and
2757 incremented/reset by display_line, move_it_to etc. */ 2767 incremented/reset by display_line, move_it_to etc. */
diff --git a/src/term.c b/src/term.c
index 447876d288a..b3793088fac 100644
--- a/src/term.c
+++ b/src/term.c
@@ -1704,7 +1704,13 @@ produce_glyphs (struct it *it)
1704 /* Advance current_x by the pixel width as a convenience for 1704 /* Advance current_x by the pixel width as a convenience for
1705 the caller. */ 1705 the caller. */
1706 if (it->area == TEXT_AREA) 1706 if (it->area == TEXT_AREA)
1707 it->current_x += it->pixel_width; 1707 {
1708 it->current_x += it->pixel_width;
1709
1710 if (it->continuation_lines_width
1711 && it->string_from_prefix_prop_p)
1712 it->wrap_prefix_width = it->current_x;
1713 }
1708 it->ascent = it->max_ascent = it->phys_ascent = it->max_phys_ascent = 0; 1714 it->ascent = it->max_ascent = it->phys_ascent = it->max_phys_ascent = 0;
1709 it->descent = it->max_descent = it->phys_descent = it->max_phys_descent = 1; 1715 it->descent = it->max_descent = it->phys_descent = it->max_phys_descent = 1;
1710#endif 1716#endif
diff --git a/src/xdisp.c b/src/xdisp.c
index 066217a2f0f..4ff689b2df7 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -3821,7 +3821,7 @@ start_display (struct it *it, struct window *w, struct text_pos pos)
3821 3821
3822 it->current_y = first_y; 3822 it->current_y = first_y;
3823 it->vpos = 0; 3823 it->vpos = 0;
3824 it->current_x = it->hpos = 0; 3824 it->current_x = it->hpos = it->wrap_prefix_width = 0;
3825 } 3825 }
3826 } 3826 }
3827} 3827}
@@ -5532,7 +5532,13 @@ display_min_width (struct it *it, ptrdiff_t bufpos,
5532 it->object = list3 (Qspace, QCwidth, w); 5532 it->object = list3 (Qspace, QCwidth, w);
5533 produce_stretch_glyph (it); 5533 produce_stretch_glyph (it);
5534 if (it->area == TEXT_AREA) 5534 if (it->area == TEXT_AREA)
5535 it->current_x += it->pixel_width; 5535 {
5536 it->current_x += it->pixel_width;
5537
5538 if (it->continuation_lines_width
5539 && it->string_from_prefix_prop_p)
5540 it->wrap_prefix_width = it->current_x;
5541 }
5536 it->min_width_property = Qnil; 5542 it->min_width_property = Qnil;
5537 } 5543 }
5538 } 5544 }
@@ -10797,6 +10803,7 @@ move_it_to (struct it *it, ptrdiff_t to_charpos, int to_x, int to_y, int to_vpos
10797 10803
10798 /* Reset/increment for the next run. */ 10804 /* Reset/increment for the next run. */
10799 it->current_x = line_start_x; 10805 it->current_x = line_start_x;
10806 it->wrap_prefix_width = 0;
10800 line_start_x = 0; 10807 line_start_x = 0;
10801 it->hpos = 0; 10808 it->hpos = 0;
10802 it->line_number_produced_p = false; 10809 it->line_number_produced_p = false;
@@ -10827,6 +10834,7 @@ move_it_to (struct it *it, ptrdiff_t to_charpos, int to_x, int to_y, int to_vpos
10827 { 10834 {
10828 it->continuation_lines_width += it->current_x; 10835 it->continuation_lines_width += it->current_x;
10829 it->current_x = it->hpos = it->max_ascent = it->max_descent = 0; 10836 it->current_x = it->hpos = it->max_ascent = it->max_descent = 0;
10837 it->wrap_prefix_width = 0;
10830 it->current_y += it->max_ascent + it->max_descent; 10838 it->current_y += it->max_ascent + it->max_descent;
10831 ++it->vpos; 10839 ++it->vpos;
10832 last_height = it->max_ascent + it->max_descent; 10840 last_height = it->max_ascent + it->max_descent;
@@ -10886,6 +10894,7 @@ move_it_vertically_backward (struct it *it, int dy)
10886 reseat_1 (it, it->current.pos, true); 10894 reseat_1 (it, it->current.pos, true);
10887 10895
10888 /* We are now surely at a line start. */ 10896 /* We are now surely at a line start. */
10897 it->wrap_prefix_width = 0;
10889 it->current_x = it->hpos = 0; /* FIXME: this is incorrect when bidi 10898 it->current_x = it->hpos = 0; /* FIXME: this is incorrect when bidi
10890 reordering is in effect. */ 10899 reordering is in effect. */
10891 it->continuation_lines_width = 0; 10900 it->continuation_lines_width = 0;
@@ -11164,7 +11173,7 @@ move_it_by_lines (struct it *it, ptrdiff_t dvpos)
11164 dvpos--; 11173 dvpos--;
11165 } 11174 }
11166 11175
11167 it->current_x = it->hpos = 0; 11176 it->current_x = it->hpos = it->wrap_prefix_width = 0;
11168 11177
11169 /* Above call may have moved too far if continuation lines 11178 /* Above call may have moved too far if continuation lines
11170 are involved. Scan forward and see if it did. */ 11179 are involved. Scan forward and see if it did. */
@@ -11173,7 +11182,7 @@ move_it_by_lines (struct it *it, ptrdiff_t dvpos)
11173 move_it_to (&it2, start_charpos, -1, -1, -1, MOVE_TO_POS); 11182 move_it_to (&it2, start_charpos, -1, -1, -1, MOVE_TO_POS);
11174 it->vpos -= it2.vpos; 11183 it->vpos -= it2.vpos;
11175 it->current_y -= it2.current_y; 11184 it->current_y -= it2.current_y;
11176 it->current_x = it->hpos = 0; 11185 it->current_x = it->hpos = it->wrap_prefix_width = 0;
11177 11186
11178 /* If we moved too far back, move IT some lines forward. */ 11187 /* If we moved too far back, move IT some lines forward. */
11179 if (it2.vpos > -dvpos) 11188 if (it2.vpos > -dvpos)
@@ -11452,7 +11461,7 @@ window_text_pixel_size (Lisp_Object window, Lisp_Object from, Lisp_Object to,
11452 IT.current_x will be incorrectly set to zero at some arbitrary 11461 IT.current_x will be incorrectly set to zero at some arbitrary
11453 non-zero X coordinate. */ 11462 non-zero X coordinate. */
11454 move_it_by_lines (&it, 0); 11463 move_it_by_lines (&it, 0);
11455 it.current_x = it.hpos = 0; 11464 it.current_x = it.hpos = it.wrap_prefix_width = 0;
11456 if (IT_CHARPOS (it) != start) 11465 if (IT_CHARPOS (it) != start)
11457 { 11466 {
11458 void *it1data = NULL; 11467 void *it1data = NULL;
@@ -11505,7 +11514,7 @@ window_text_pixel_size (Lisp_Object window, Lisp_Object from, Lisp_Object to,
11505 /* If FROM is on a newline, pretend that we start at the beginning 11514 /* If FROM is on a newline, pretend that we start at the beginning
11506 of the next line, because the newline takes no place on display. */ 11515 of the next line, because the newline takes no place on display. */
11507 if (FETCH_BYTE (start) == '\n') 11516 if (FETCH_BYTE (start) == '\n')
11508 it.current_x = 0; 11517 it.current_x = 0, it.wrap_prefix_width = 0;
11509 if (!NILP (x_limit)) 11518 if (!NILP (x_limit))
11510 { 11519 {
11511 it.last_visible_x = max_x; 11520 it.last_visible_x = max_x;
@@ -14417,7 +14426,7 @@ display_tab_bar_line (struct it *it, int height)
14417 row->truncated_on_left_p = false; 14426 row->truncated_on_left_p = false;
14418 row->truncated_on_right_p = false; 14427 row->truncated_on_right_p = false;
14419 14428
14420 it->current_x = it->hpos = 0; 14429 it->current_x = it->hpos = it->wrap_prefix_width = 0;
14421 it->current_y += row->height; 14430 it->current_y += row->height;
14422 ++it->vpos; 14431 ++it->vpos;
14423 ++it->glyph_row; 14432 ++it->glyph_row;
@@ -15441,7 +15450,7 @@ display_tool_bar_line (struct it *it, int height)
15441 row->truncated_on_left_p = false; 15450 row->truncated_on_left_p = false;
15442 row->truncated_on_right_p = false; 15451 row->truncated_on_right_p = false;
15443 15452
15444 it->current_x = it->hpos = 0; 15453 it->current_x = it->hpos = it->wrap_prefix_width = 0;
15445 it->current_y += row->height; 15454 it->current_y += row->height;
15446 ++it->vpos; 15455 ++it->vpos;
15447 ++it->glyph_row; 15456 ++it->glyph_row;
@@ -17141,6 +17150,7 @@ redisplay_internal (void)
17141 NULL, DEFAULT_FACE_ID); 17150 NULL, DEFAULT_FACE_ID);
17142 it.current_x = this_line_start_x; 17151 it.current_x = this_line_start_x;
17143 it.current_y = this_line_y; 17152 it.current_y = this_line_y;
17153 it.wrap_prefix_width = 0;
17144 it.vpos = this_line_vpos; 17154 it.vpos = this_line_vpos;
17145 17155
17146 if (current_buffer->long_line_optimizations_p 17156 if (current_buffer->long_line_optimizations_p
@@ -20587,7 +20597,7 @@ redisplay_window (Lisp_Object window, bool just_this_one_p)
20587 it.current_y = 0; 20597 it.current_y = 0;
20588 } 20598 }
20589 20599
20590 it.current_x = it.hpos = 0; 20600 it.current_x = it.wrap_prefix_width = it.hpos = 0;
20591 20601
20592 /* Set the window start position here explicitly, to avoid an 20602 /* Set the window start position here explicitly, to avoid an
20593 infinite loop in case the functions in window-scroll-functions 20603 infinite loop in case the functions in window-scroll-functions
@@ -22555,7 +22565,7 @@ try_window_id (struct window *w)
22555 /* We may start in a continuation line. If so, we have to 22565 /* We may start in a continuation line. If so, we have to
22556 get the right continuation_lines_width and current_x. */ 22566 get the right continuation_lines_width and current_x. */
22557 it.continuation_lines_width = last_row->continuation_lines_width; 22567 it.continuation_lines_width = last_row->continuation_lines_width;
22558 it.hpos = it.current_x = 0; 22568 it.hpos = it.current_x = it.wrap_prefix_width = 0;
22559 22569
22560 /* Display the rest of the lines at the window end. */ 22570 /* Display the rest of the lines at the window end. */
22561 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos); 22571 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
@@ -23160,6 +23170,7 @@ insert_left_trunc_glyphs (struct it *it)
23160 /* Get the truncation glyphs. */ 23170 /* Get the truncation glyphs. */
23161 truncate_it = *it; 23171 truncate_it = *it;
23162 truncate_it.current_x = 0; 23172 truncate_it.current_x = 0;
23173 truncate_it.wrap_prefix_width = 0;
23163 truncate_it.face_id = DEFAULT_FACE_ID; 23174 truncate_it.face_id = DEFAULT_FACE_ID;
23164 truncate_it.glyph_row = &scratch_glyph_row; 23175 truncate_it.glyph_row = &scratch_glyph_row;
23165 truncate_it.area = TEXT_AREA; 23176 truncate_it.area = TEXT_AREA;
@@ -23922,6 +23933,10 @@ extend_face_to_end_of_line (struct it *it)
23922 for (it->current_x = 0; g < e; g++) 23933 for (it->current_x = 0; g < e; g++)
23923 it->current_x += g->pixel_width; 23934 it->current_x += g->pixel_width;
23924 23935
23936 if (it->continuation_lines_width
23937 && it->string_from_prefix_prop_p)
23938 it->wrap_prefix_width = it->current_x;
23939
23925 it->area = LEFT_MARGIN_AREA; 23940 it->area = LEFT_MARGIN_AREA;
23926 it->face_id = default_face->id; 23941 it->face_id = default_face->id;
23927 while (it->glyph_row->used[LEFT_MARGIN_AREA] 23942 while (it->glyph_row->used[LEFT_MARGIN_AREA]
@@ -25064,7 +25079,10 @@ display_line (struct it *it, int cursor_vpos)
25064 if (it->current_x < it->first_visible_x 25079 if (it->current_x < it->first_visible_x
25065 && (move_result == MOVE_NEWLINE_OR_CR 25080 && (move_result == MOVE_NEWLINE_OR_CR
25066 || move_result == MOVE_POS_MATCH_OR_ZV)) 25081 || move_result == MOVE_POS_MATCH_OR_ZV))
25067 it->current_x = it->first_visible_x; 25082 {
25083 it->current_x = it->first_visible_x;
25084 it->wrap_prefix_width = 0;
25085 }
25068 25086
25069 /* In case move_it_in_display_line_to above "produced" the line 25087 /* In case move_it_in_display_line_to above "produced" the line
25070 number. */ 25088 number. */
@@ -25921,7 +25939,7 @@ display_line (struct it *it, int cursor_vpos)
25921 HPOS) = (0 0). Vertical positions are incremented. As a 25939 HPOS) = (0 0). Vertical positions are incremented. As a
25922 convenience for the caller, IT->glyph_row is set to the next 25940 convenience for the caller, IT->glyph_row is set to the next
25923 row to be used. */ 25941 row to be used. */
25924 it->current_x = it->hpos = 0; 25942 it->wrap_prefix_width = it->current_x = it->hpos = 0;
25925 it->current_y += row->height; 25943 it->current_y += row->height;
25926 /* Restore the first and last visible X if we adjusted them for 25944 /* Restore the first and last visible X if we adjusted them for
25927 current-line hscrolling. */ 25945 current-line hscrolling. */
@@ -26400,7 +26418,7 @@ Value is the new character position of point. */)
26400 { 26418 {
26401 struct text_pos pt; 26419 struct text_pos pt;
26402 struct it it; 26420 struct it it;
26403 int pt_x, target_x, pixel_width, pt_vpos; 26421 int pt_x, pt_wrap_prefix_x, target_x, pixel_width, pt_vpos;
26404 bool at_eol_p; 26422 bool at_eol_p;
26405 bool overshoot_expected = false; 26423 bool overshoot_expected = false;
26406 bool target_is_eol_p = false; 26424 bool target_is_eol_p = false;
@@ -26432,6 +26450,7 @@ Value is the new character position of point. */)
26432 reseat: 26450 reseat:
26433 reseat_at_previous_visible_line_start (&it); 26451 reseat_at_previous_visible_line_start (&it);
26434 it.current_x = it.hpos = it.current_y = it.vpos = 0; 26452 it.current_x = it.hpos = it.current_y = it.vpos = 0;
26453 it.wrap_prefix_width = 0;
26435 if (IT_CHARPOS (it) != PT) 26454 if (IT_CHARPOS (it) != PT)
26436 { 26455 {
26437 move_it_to (&it, overshoot_expected ? PT - 1 : PT, 26456 move_it_to (&it, overshoot_expected ? PT - 1 : PT,
@@ -26450,6 +26469,7 @@ Value is the new character position of point. */)
26450 move_it_in_display_line (&it, PT, -1, MOVE_TO_POS); 26469 move_it_in_display_line (&it, PT, -1, MOVE_TO_POS);
26451 } 26470 }
26452 pt_x = it.current_x; 26471 pt_x = it.current_x;
26472 pt_wrap_prefix_x = it.wrap_prefix_width;
26453 pt_vpos = it.vpos; 26473 pt_vpos = it.vpos;
26454 if (dir > 0 || overshoot_expected) 26474 if (dir > 0 || overshoot_expected)
26455 { 26475 {
@@ -26464,10 +26484,11 @@ Value is the new character position of point. */)
26464 it.glyph_row = NULL; 26484 it.glyph_row = NULL;
26465 PRODUCE_GLYPHS (&it); /* compute it.pixel_width */ 26485 PRODUCE_GLYPHS (&it); /* compute it.pixel_width */
26466 it.glyph_row = row; 26486 it.glyph_row = row;
26467 /* PRODUCE_GLYPHS advances it.current_x, so we must restore 26487 /* PRODUCE_GLYPHS advances it.current_x, so it must be
26468 it, lest it will become out of sync with it's buffer 26488 restored, lest it become out of sync with its buffer
26469 position. */ 26489 position. */
26470 it.current_x = pt_x; 26490 it.current_x = pt_x;
26491 it.wrap_prefix_width = pt_wrap_prefix_x;
26471 } 26492 }
26472 else 26493 else
26473 at_eol_p = ITERATOR_AT_END_OF_LINE_P (&it); 26494 at_eol_p = ITERATOR_AT_END_OF_LINE_P (&it);
@@ -26512,6 +26533,7 @@ Value is the new character position of point. */)
26512 it.last_visible_x = DISP_INFINITY; 26533 it.last_visible_x = DISP_INFINITY;
26513 reseat_at_previous_visible_line_start (&it); 26534 reseat_at_previous_visible_line_start (&it);
26514 it.current_x = it.current_y = it.hpos = 0; 26535 it.current_x = it.current_y = it.hpos = 0;
26536 it.wrap_prefix_width = 0;
26515 if (pt_vpos != 0) 26537 if (pt_vpos != 0)
26516 move_it_by_lines (&it, pt_vpos); 26538 move_it_by_lines (&it, pt_vpos);
26517 } 26539 }
@@ -32659,7 +32681,19 @@ gui_produce_glyphs (struct it *it)
32659 if (font->space_width > 0) 32681 if (font->space_width > 0)
32660 { 32682 {
32661 int tab_width = it->tab_width * font->space_width; 32683 int tab_width = it->tab_width * font->space_width;
32662 int x = it->current_x + it->continuation_lines_width; 32684 /* wrap-prefix strings are prepended to continuation
32685 lines, so the width of tab characters inside should
32686 be computed from the start of this screen line rather
32687 than as a product of the total width of the physical
32688 line being wrapped. */
32689 int x = it->current_x + (it->string_from_prefix_prop_p
32690 /* Subtract the width of the
32691 prefix from it->current_x if
32692 it exists. */
32693 ? 0 : (it->continuation_lines_width
32694 ? (it->continuation_lines_width
32695 - it->wrap_prefix_width)
32696 : 0));
32663 int x0 = x; 32697 int x0 = x;
32664 /* Adjust for line numbers, if needed. */ 32698 /* Adjust for line numbers, if needed. */
32665 if (!NILP (Vdisplay_line_numbers) && it->line_number_produced_p) 32699 if (!NILP (Vdisplay_line_numbers) && it->line_number_produced_p)
@@ -33130,7 +33164,13 @@ gui_produce_glyphs (struct it *it)
33130 because this isn't true for images with `:ascent 100'. */ 33164 because this isn't true for images with `:ascent 100'. */
33131 eassert (it->ascent >= 0 && it->descent >= 0); 33165 eassert (it->ascent >= 0 && it->descent >= 0);
33132 if (it->area == TEXT_AREA) 33166 if (it->area == TEXT_AREA)
33133 it->current_x += it->pixel_width; 33167 {
33168 it->current_x += it->pixel_width;
33169
33170 if (it->continuation_lines_width
33171 && it->string_from_prefix_prop_p)
33172 it->wrap_prefix_width = it->current_x;
33173 }
33134 33174
33135 if (extra_line_spacing > 0) 33175 if (extra_line_spacing > 0)
33136 { 33176 {