mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-02-16 17:24:23 +00:00
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.
This commit is contained in:
parent
4ad214f36c
commit
1ac1905538
3 changed files with 54 additions and 11 deletions
|
|
@ -2462,6 +2462,10 @@ struct it
|
|||
descent/ascent (line-height property). Reset after this glyph. */
|
||||
bool_bf constrain_row_ascent_descent_p : 1;
|
||||
|
||||
/* If true, glyphs for line number display were already produced for
|
||||
the current row. */
|
||||
bool_bf line_number_produced_p : 1;
|
||||
|
||||
enum line_wrap_method line_wrap;
|
||||
|
||||
/* The ID of the default face to use. One of DEFAULT_FACE_ID,
|
||||
|
|
@ -2641,6 +2645,12 @@ struct it
|
|||
/* The line number of point's line, or zero if not computed yet. */
|
||||
ptrdiff_t pt_lnum;
|
||||
|
||||
/* Number of pixels to offset tab stops due to width fixup of the
|
||||
first glyph that crosses first_visible_x. This is only needed on
|
||||
GUI frames, only when display-line-numbers is in effect, and only
|
||||
in hscrolled windows. */
|
||||
int tab_offset;
|
||||
|
||||
/* Left fringe bitmap number (enum fringe_bitmap_type). */
|
||||
unsigned left_user_fringe_bitmap : FRINGE_ID_BITS;
|
||||
|
||||
|
|
|
|||
|
|
@ -1591,13 +1591,13 @@ produce_glyphs (struct it *it)
|
|||
+ it->continuation_lines_width);
|
||||
int x0 = absolute_x;
|
||||
/* Adjust for line numbers. */
|
||||
if (!NILP (Vdisplay_line_numbers))
|
||||
if (!NILP (Vdisplay_line_numbers) && it->line_number_produced_p)
|
||||
absolute_x -= it->lnum_pixel_width;
|
||||
int next_tab_x
|
||||
= (((1 + absolute_x + it->tab_width - 1)
|
||||
/ it->tab_width)
|
||||
* it->tab_width);
|
||||
if (!NILP (Vdisplay_line_numbers))
|
||||
if (!NILP (Vdisplay_line_numbers) && it->line_number_produced_p)
|
||||
next_tab_x += it->lnum_pixel_width;
|
||||
int nspaces;
|
||||
|
||||
|
|
|
|||
51
src/xdisp.c
51
src/xdisp.c
|
|
@ -8716,8 +8716,12 @@ move_it_in_display_line_to (struct it *it,
|
|||
|
||||
if (it->hpos == 0)
|
||||
{
|
||||
/* If line numbers are being displayed, produce a line number. */
|
||||
if (should_produce_line_number (it))
|
||||
/* If line numbers are being displayed, produce a line number.
|
||||
But don't do that if we are to reach first_visible_x, because
|
||||
line numbers are not relevant to stuff that is not visible on
|
||||
display. */
|
||||
if (!((op && MOVE_TO_X) && to_x == it->first_visible_x)
|
||||
&& should_produce_line_number (it))
|
||||
{
|
||||
if (it->current_x == it->first_visible_x)
|
||||
maybe_produce_line_number (it);
|
||||
|
|
@ -21173,6 +21177,8 @@ maybe_produce_line_number (struct it *it)
|
|||
it->max_phys_descent = max (it->max_phys_descent, tem_it.max_phys_descent);
|
||||
}
|
||||
|
||||
it->line_number_produced_p = true;
|
||||
|
||||
bidi_unshelve_cache (itdata, false);
|
||||
}
|
||||
|
||||
|
|
@ -21290,6 +21296,8 @@ display_line (struct it *it, int cursor_vpos)
|
|||
row->displays_text_p = true;
|
||||
row->starts_in_middle_of_char_p = it->starts_in_middle_of_char_p;
|
||||
it->starts_in_middle_of_char_p = false;
|
||||
it->tab_offset = 0;
|
||||
it->line_number_produced_p = false;
|
||||
|
||||
/* Arrange the overlays nicely for our purposes. Usually, we call
|
||||
display_line on only one line at a time, in which case this
|
||||
|
|
@ -21334,6 +21342,10 @@ display_line (struct it *it, int cursor_vpos)
|
|||
|| move_result == MOVE_POS_MATCH_OR_ZV))
|
||||
it->current_x = it->first_visible_x;
|
||||
|
||||
/* In case move_it_in_display_line_to above "produced" the line
|
||||
number. */
|
||||
it->line_number_produced_p = false;
|
||||
|
||||
/* Record the smallest positions seen while we moved over
|
||||
display elements that are not visible. This is needed by
|
||||
redisplay_internal for optimizing the case where the cursor
|
||||
|
|
@ -21553,6 +21565,10 @@ display_line (struct it *it, int cursor_vpos)
|
|||
row->extra_line_spacing = max (row->extra_line_spacing,
|
||||
it->max_extra_line_spacing);
|
||||
if (it->current_x - it->pixel_width < it->first_visible_x
|
||||
/* When line numbers are displayed, row->x should not be
|
||||
offset, as the first glyph after the line number can
|
||||
never be partially visible. */
|
||||
&& !line_number_needed
|
||||
/* In R2L rows, we arrange in extend_face_to_end_of_line
|
||||
to add a right offset to the line, by a suitable
|
||||
change to the stretch glyph that is the leftmost
|
||||
|
|
@ -21794,7 +21810,8 @@ display_line (struct it *it, int cursor_vpos)
|
|||
if (it->bidi_p)
|
||||
RECORD_MAX_MIN_POS (it);
|
||||
|
||||
if (x < it->first_visible_x && !row->reversed_p)
|
||||
if (x < it->first_visible_x && !row->reversed_p
|
||||
&& !line_number_needed)
|
||||
/* Glyph is partially visible, i.e. row starts at
|
||||
negative X position. Don't do that in R2L
|
||||
rows, where we arrange to add a right offset to
|
||||
|
|
@ -21810,6 +21827,7 @@ display_line (struct it *it, int cursor_vpos)
|
|||
be taken care of in produce_special_glyphs. */
|
||||
if (row->reversed_p
|
||||
&& new_x > it->last_visible_x
|
||||
&& !line_number_needed
|
||||
&& !(it->line_wrap == TRUNCATE
|
||||
&& WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0))
|
||||
{
|
||||
|
|
@ -28274,8 +28292,14 @@ x_produce_glyphs (struct it *it)
|
|||
int x = it->current_x + it->continuation_lines_width;
|
||||
int x0 = x;
|
||||
/* Adjust for line numbers, if needed. */
|
||||
if (!NILP (Vdisplay_line_numbers) && x0 >= it->lnum_pixel_width)
|
||||
x -= it->lnum_pixel_width;
|
||||
if (!NILP (Vdisplay_line_numbers) && it->line_number_produced_p)
|
||||
{
|
||||
x -= it->lnum_pixel_width;
|
||||
/* Restore the original TAB width, if required. */
|
||||
if (x + it->tab_offset >= it->first_visible_x)
|
||||
x += it->tab_offset;
|
||||
}
|
||||
|
||||
int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width;
|
||||
|
||||
/* If the distance from the current position to the next tab
|
||||
|
|
@ -28283,10 +28307,19 @@ x_produce_glyphs (struct it *it)
|
|||
tab stop after that. */
|
||||
if (next_tab_x - x < font->space_width)
|
||||
next_tab_x += tab_width;
|
||||
if (!NILP (Vdisplay_line_numbers) && x0 >= it->lnum_pixel_width)
|
||||
next_tab_x += (it->lnum_pixel_width
|
||||
- ((it->w->hscroll * font->space_width)
|
||||
% tab_width));
|
||||
if (!NILP (Vdisplay_line_numbers) && it->line_number_produced_p)
|
||||
{
|
||||
next_tab_x += it->lnum_pixel_width;
|
||||
/* If the line is hscrolled, and the TAB starts before
|
||||
the first visible pixel, simulate negative row->x. */
|
||||
if (x < it->first_visible_x)
|
||||
{
|
||||
next_tab_x -= it->first_visible_x - x;
|
||||
it->tab_offset = it->first_visible_x - x;
|
||||
}
|
||||
else
|
||||
next_tab_x -= it->tab_offset;
|
||||
}
|
||||
|
||||
it->pixel_width = next_tab_x - x0;
|
||||
it->nglyphs = 1;
|
||||
|
|
|
|||
Loading…
Reference in a new issue