aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEli Zaretskii2017-07-08 10:49:36 +0300
committerEli Zaretskii2017-07-08 10:49:36 +0300
commit5df239fc6ffbbb16ea6e5546fbec1508bf2cb4b7 (patch)
tree9b1b8baff1c3ca9c9c560460b34a7951723f621c /src
parentb8ead34f5df92b771520f4d090ff6cde49ca5705 (diff)
parent13786d5e7d0aa0a37d7f81d1a1b82eddd3472796 (diff)
downloademacs-5df239fc6ffbbb16ea6e5546fbec1508bf2cb4b7.tar.gz
emacs-5df239fc6ffbbb16ea6e5546fbec1508bf2cb4b7.zip
Support display of line numbers natively
This merges branch 'line-numbers'. * src/buffer.c (disable_line_numbers_overlay_at_eob): New function. * src/lisp.h (disable_line_numbers_overlay_at_eob): Add prototype. * src/dispextern.h (struct it): New members pt_lnum, lnum, lnum_bytepos, lnum_width, and lnum_pixel_width. * src/indent.c (line_number_display_width): New function, refactored from line-number width calculations in vertical-motion. (Fvertical_motion): Call line_number_display_width when the width of line-number display is needed. (Fline_number_display_width): New defun. (syms_of_indent): Defsubr it. * src/indent.c (Fvertical_motion): Help C-n/C-p estimate correctly the width used up by line numbers by looking near the window-start point. If window-start is outside of the accessible portion, temporarily widen the buffer. * src/term.c (produce_glyphs): Adjust tab stops for the horizontal space taken by the line-number display. * src/xdisp.c (display_count_lines_logically) (display_count_lines_visually, maybe_produce_line_number) (should_produce_line_number, row_text_area_empty): New functions. (try_window_reusing_current_matrix): Don't use this method when display-line-numbers is in effect. (try_window_id, try_cursor_movement): Disable these optimizations when the line-number-current-line face is different from line-number face and for relative line numbers. (try_window_id, redisplay_window, try_cursor_movement): For visual line-number display, disable the same redisplay optimizations as for relative. (x_produce_glyphs): Adjust tab stops for the horizontal space taken by the line-number display. (hscroll_window_tree): Adjust hscroll calculations to line-number display. (DISP_INFINITY): Renamed from INFINITY to avoid clashes with math.h; all users changed. (set_cursor_from_row): Fix calculation of cursor X coordinate in R2L rows with display-produced glyphs at the beginning. (display_line): Use should_produce_line_number to determine whether a line number should be produced for each glyph row, and maybe_produce_line_number to produce line numbers. Don't display line numbers in the minibuffer and in tooltip frames. Call row_text_area_empty to verify that a glyph row's text area is devoid of any glyphs that came from a buffer or a string. This fixes a bug with empty-lines indication disappearing when line numbers or line-prefix are displayed. (syms_of_xdisp) <display-line-numbers, display-line-numbers-widen> <display-line-number-width>: New buffer-local variables. <display-line-numbers-current-absolute>: New variable. * lisp/cus-start.el (standard): Provide customization forms for display-line-numbers and its sub-features. * lisp/faces.el (line-number, line-number-current-line): New faces. * lisp/frame.el: Add display-line-numbers, display-line-numbers-widen, display-line-numbers-current-absolute, and display-line-number-width to the list of variables that should trigger redisplay of the current buffer. * lisp/menu-bar.el (menu-bar-showhide-menu): Add menu-bar item to turn display-line-numbers on and off. (toggle-display-line-numbers): New function. * lisp/simple.el (last--line-number-width): New internal variable. (line-move-visual): Use it to adjust temporary-goal-column when line-number display changes its width. * doc/emacs/basic.texi (Position Info): Add cross-reference to "Display Custom", for line-number display. * doc/emacs/custom.texi (Init Rebinding): * doc/emacs/modes.texi (Minor Modes): Remove references to linum-mode. * doc/emacs/display.texi (Display Custom): Describe the line-number display. * doc/lispref/display.texi (Size of Displayed Text): Document line-number-display-width. * etc/NEWS: Document display-line-numbers and its customizations.
Diffstat (limited to 'src')
-rw-r--r--src/buffer.c27
-rw-r--r--src/dispextern.h22
-rw-r--r--src/indent.c70
-rw-r--r--src/lisp.h1
-rw-r--r--src/term.c8
-rw-r--r--src/xdisp.c547
6 files changed, 647 insertions, 28 deletions
diff --git a/src/buffer.c b/src/buffer.c
index 80dbd3318dc..780e4d7a7d6 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -3054,6 +3054,33 @@ mouse_face_overlay_overlaps (Lisp_Object overlay)
3054 return i < n; 3054 return i < n;
3055} 3055}
3056 3056
3057/* Return the value of the 'display-line-numbers-disable' property at
3058 EOB, if there's an overlay at ZV with a non-nil value of that property. */
3059Lisp_Object
3060disable_line_numbers_overlay_at_eob (void)
3061{
3062 ptrdiff_t n, i, size;
3063 Lisp_Object *v, tem = Qnil;
3064 Lisp_Object vbuf[10];
3065 USE_SAFE_ALLOCA;
3066
3067 size = ARRAYELTS (vbuf);
3068 v = vbuf;
3069 n = overlays_in (ZV, ZV, 0, &v, &size, NULL, NULL);
3070 if (n > size)
3071 {
3072 SAFE_NALLOCA (v, 1, n);
3073 overlays_in (ZV, ZV, 0, &v, &n, NULL, NULL);
3074 }
3075
3076 for (i = 0; i < n; ++i)
3077 if ((tem = Foverlay_get (v[i], Qdisplay_line_numbers_disable),
3078 !NILP (tem)))
3079 break;
3080
3081 SAFE_FREE ();
3082 return tem;
3083}
3057 3084
3058 3085
3059/* Fast function to just test if we're at an overlay boundary. */ 3086/* Fast function to just test if we're at an overlay boundary. */
diff --git a/src/dispextern.h b/src/dispextern.h
index 8644ce26d13..1df769a8f99 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -384,6 +384,7 @@ struct glyph
384 glyph standing for newline at end of line 0 384 glyph standing for newline at end of line 0
385 empty space after the end of the line -1 385 empty space after the end of the line -1
386 overlay arrow on a TTY -1 386 overlay arrow on a TTY -1
387 glyph displaying line number -1
387 glyph at EOB that ends in a newline -1 388 glyph at EOB that ends in a newline -1
388 left truncation glyphs: -1 389 left truncation glyphs: -1
389 right truncation/continuation glyphs next buffer position 390 right truncation/continuation glyphs next buffer position
@@ -2537,7 +2538,12 @@ struct it
2537 Do NOT use !BUFFERP (it.object) as a test whether we are 2538 Do NOT use !BUFFERP (it.object) as a test whether we are
2538 iterating over a string; use STRINGP (it.string) instead. 2539 iterating over a string; use STRINGP (it.string) instead.
2539 2540
2540 Position is the current iterator position in object. */ 2541 Position is the current iterator position in object.
2542
2543 The 'position's CHARPOS is copied to glyph->charpos of the glyph
2544 produced by PRODUCE_GLYPHS, so any artificial value documented
2545 under 'struct glyph's 'charpos' member can also be found in the
2546 'position' member here. */
2541 Lisp_Object object; 2547 Lisp_Object object;
2542 struct text_pos position; 2548 struct text_pos position;
2543 2549
@@ -2621,6 +2627,20 @@ struct it
2621 coordinate is past first_visible_x. */ 2627 coordinate is past first_visible_x. */
2622 int hpos; 2628 int hpos;
2623 2629
2630 /* Current line number, zero-based. */
2631 ptrdiff_t lnum;
2632
2633 /* The byte position corresponding to lnum. */
2634 ptrdiff_t lnum_bytepos;
2635
2636 /* The width, in columns and in pixels, needed for display of the
2637 line numbers, or zero if not computed. */
2638 int lnum_width;
2639 int lnum_pixel_width;
2640
2641 /* The line number of point's line, or zero if not computed yet. */
2642 ptrdiff_t pt_lnum;
2643
2624 /* Left fringe bitmap number (enum fringe_bitmap_type). */ 2644 /* Left fringe bitmap number (enum fringe_bitmap_type). */
2625 unsigned left_user_fringe_bitmap : FRINGE_ID_BITS; 2645 unsigned left_user_fringe_bitmap : FRINGE_ID_BITS;
2626 2646
diff --git a/src/indent.c b/src/indent.c
index adecc3622a8..4c6dacd2042 100644
--- a/src/indent.c
+++ b/src/indent.c
@@ -1947,6 +1947,57 @@ vmotion (register ptrdiff_t from, register ptrdiff_t from_byte,
1947 -1, hscroll, 0, w); 1947 -1, hscroll, 0, w);
1948} 1948}
1949 1949
1950/* Return the width taken by line-number display in window W. */
1951static void
1952line_number_display_width (struct window *w, int *width, int *pixel_width)
1953{
1954 if (NILP (Vdisplay_line_numbers))
1955 {
1956 *width = 0;
1957 *pixel_width = 0;
1958 }
1959 else
1960 {
1961 struct it it;
1962 struct text_pos wstart;
1963 bool saved_restriction = false;
1964 ptrdiff_t count = SPECPDL_INDEX ();
1965 SET_TEXT_POS_FROM_MARKER (wstart, w->start);
1966 void *itdata = bidi_shelve_cache ();
1967 /* We must start from window's start point, but it could be
1968 outside the accessible region. */
1969 if (wstart.charpos < BEGV || wstart.charpos > ZV)
1970 {
1971 record_unwind_protect (save_restriction_restore,
1972 save_restriction_save ());
1973 Fwiden ();
1974 saved_restriction = true;
1975 }
1976 start_display (&it, w, wstart);
1977 move_it_by_lines (&it, 1);
1978 *width = it.lnum_width;
1979 *pixel_width = it.lnum_pixel_width;
1980 if (saved_restriction)
1981 unbind_to (count, Qnil);
1982 bidi_unshelve_cache (itdata, 0);
1983 }
1984}
1985
1986DEFUN ("line-number-display-width", Fline_number_display_width,
1987 Sline_number_display_width, 0, 1, 0,
1988 doc: /* Return the width used for displaying line numbers in the selected window.
1989If optional argument PIXELWISE is non-nil, return the width in pixels,
1990otherwise return the width in columns of the face used to display
1991line numbers, `line-number'. */)
1992 (Lisp_Object pixelwise)
1993{
1994 int width, pixel_width;
1995 line_number_display_width (XWINDOW (selected_window), &width, &pixel_width);
1996 if (!NILP (pixelwise))
1997 return make_number (pixel_width);
1998 return make_number (width);
1999}
2000
1950/* In window W (derived from WINDOW), return x coordinate for column 2001/* In window W (derived from WINDOW), return x coordinate for column
1951 COL (derived from COLUMN). */ 2002 COL (derived from COLUMN). */
1952static int 2003static int
@@ -2068,9 +2119,19 @@ whether or not it is currently displayed in some window. */)
2068 start_x = window_column_x (w, window, start_col, cur_col); 2119 start_x = window_column_x (w, window, start_col, cur_col);
2069 } 2120 }
2070 2121
2071 itdata = bidi_shelve_cache (); 2122 /* When displaying line numbers, we need to prime IT's
2123 lnum_width with the value calculated at window's start, since
2124 that's what normal window redisplay does. Otherwise C-n/C-p
2125 will sometimes err by one column. */
2126 int lnum_width = 0;
2127 int lnum_pixel_width = 0;
2128 if (!NILP (Vdisplay_line_numbers)
2129 && !EQ (Vdisplay_line_numbers, Qvisual))
2130 line_number_display_width (w, &lnum_width, &lnum_pixel_width);
2072 SET_TEXT_POS (pt, PT, PT_BYTE); 2131 SET_TEXT_POS (pt, PT, PT_BYTE);
2132 itdata = bidi_shelve_cache ();
2073 start_display (&it, w, pt); 2133 start_display (&it, w, pt);
2134 it.lnum_width = lnum_width;
2074 first_x = it.first_visible_x; 2135 first_x = it.first_visible_x;
2075 it_start = IT_CHARPOS (it); 2136 it_start = IT_CHARPOS (it);
2076 2137
@@ -2247,6 +2308,12 @@ whether or not it is currently displayed in some window. */)
2247 an addition to the hscroll amount. */ 2308 an addition to the hscroll amount. */
2248 if (lcols_given) 2309 if (lcols_given)
2249 { 2310 {
2311 /* If we are displaying line numbers, we could cross the
2312 line where the width of the line-number display changes,
2313 in which case we need to fix up the pixel coordinate
2314 accordingly. */
2315 if (lnum_pixel_width > 0)
2316 to_x += it.lnum_pixel_width - lnum_pixel_width;
2250 move_it_in_display_line (&it, ZV, first_x + to_x, MOVE_TO_X); 2317 move_it_in_display_line (&it, ZV, first_x + to_x, MOVE_TO_X);
2251 /* If we find ourselves in the middle of an overlay string 2318 /* If we find ourselves in the middle of an overlay string
2252 which includes a newline after current string position, 2319 which includes a newline after current string position,
@@ -2292,6 +2359,7 @@ syms_of_indent (void)
2292 defsubr (&Sindent_to); 2359 defsubr (&Sindent_to);
2293 defsubr (&Scurrent_column); 2360 defsubr (&Scurrent_column);
2294 defsubr (&Smove_to_column); 2361 defsubr (&Smove_to_column);
2362 defsubr (&Sline_number_display_width);
2295 defsubr (&Svertical_motion); 2363 defsubr (&Svertical_motion);
2296 defsubr (&Scompute_motion); 2364 defsubr (&Scompute_motion);
2297} 2365}
diff --git a/src/lisp.h b/src/lisp.h
index ff8dde2b825..f5cb6c75706 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -3965,6 +3965,7 @@ extern void syms_of_editfns (void);
3965 3965
3966/* Defined in buffer.c. */ 3966/* Defined in buffer.c. */
3967extern bool mouse_face_overlay_overlaps (Lisp_Object); 3967extern bool mouse_face_overlay_overlaps (Lisp_Object);
3968extern Lisp_Object disable_line_numbers_overlay_at_eob (void);
3968extern _Noreturn void nsberror (Lisp_Object); 3969extern _Noreturn void nsberror (Lisp_Object);
3969extern void adjust_overlays_for_insert (ptrdiff_t, ptrdiff_t); 3970extern void adjust_overlays_for_insert (ptrdiff_t, ptrdiff_t);
3970extern void adjust_overlays_for_delete (ptrdiff_t, ptrdiff_t); 3971extern void adjust_overlays_for_delete (ptrdiff_t, ptrdiff_t);
diff --git a/src/term.c b/src/term.c
index 3d7f4ada0b9..87a412666d0 100644
--- a/src/term.c
+++ b/src/term.c
@@ -1585,10 +1585,16 @@ produce_glyphs (struct it *it)
1585 { 1585 {
1586 int absolute_x = (it->current_x 1586 int absolute_x = (it->current_x
1587 + it->continuation_lines_width); 1587 + it->continuation_lines_width);
1588 int x0 = absolute_x;
1589 /* Adjust for line numbers. */
1590 if (!NILP (Vdisplay_line_numbers))
1591 absolute_x -= it->lnum_pixel_width;
1588 int next_tab_x 1592 int next_tab_x
1589 = (((1 + absolute_x + it->tab_width - 1) 1593 = (((1 + absolute_x + it->tab_width - 1)
1590 / it->tab_width) 1594 / it->tab_width)
1591 * it->tab_width); 1595 * it->tab_width);
1596 if (!NILP (Vdisplay_line_numbers))
1597 next_tab_x += it->lnum_pixel_width;
1592 int nspaces; 1598 int nspaces;
1593 1599
1594 /* If part of the TAB has been displayed on the previous line 1600 /* If part of the TAB has been displayed on the previous line
@@ -1596,7 +1602,7 @@ produce_glyphs (struct it *it)
1596 been incremented already by the part that fitted on the 1602 been incremented already by the part that fitted on the
1597 continued line. So, we will get the right number of spaces 1603 continued line. So, we will get the right number of spaces
1598 here. */ 1604 here. */
1599 nspaces = next_tab_x - absolute_x; 1605 nspaces = next_tab_x - x0;
1600 1606
1601 if (it->glyph_row) 1607 if (it->glyph_row)
1602 { 1608 {
diff --git a/src/xdisp.c b/src/xdisp.c
index 1c316fa4932..fad23bfdc9d 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -290,6 +290,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
290#include <stdio.h> 290#include <stdio.h>
291#include <stdlib.h> 291#include <stdlib.h>
292#include <limits.h> 292#include <limits.h>
293#include <math.h>
293 294
294#include "lisp.h" 295#include "lisp.h"
295#include "atimer.h" 296#include "atimer.h"
@@ -324,7 +325,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
324#define FRAME_X_OUTPUT(f) ((f)->output_data.x) 325#define FRAME_X_OUTPUT(f) ((f)->output_data.x)
325#endif 326#endif
326 327
327#define INFINITY 10000000 328#define DISP_INFINITY 10000000
328 329
329/* Holds the list (error). */ 330/* Holds the list (error). */
330static Lisp_Object list_of_error; 331static Lisp_Object list_of_error;
@@ -832,6 +833,8 @@ static bool cursor_row_fully_visible_p (struct window *, bool, bool);
832static bool update_menu_bar (struct frame *, bool, bool); 833static bool update_menu_bar (struct frame *, bool, bool);
833static bool try_window_reusing_current_matrix (struct window *); 834static bool try_window_reusing_current_matrix (struct window *);
834static int try_window_id (struct window *); 835static int try_window_id (struct window *);
836static void maybe_produce_line_number (struct it *);
837static bool should_produce_line_number (struct it *);
835static bool display_line (struct it *, int); 838static bool display_line (struct it *, int);
836static int display_mode_lines (struct window *); 839static int display_mode_lines (struct window *);
837static int display_mode_line (struct window *, enum face_id, Lisp_Object); 840static int display_mode_line (struct window *, enum face_id, Lisp_Object);
@@ -843,6 +846,8 @@ static const char *decode_mode_spec (struct window *, int, int, Lisp_Object *);
843static void display_menu_bar (struct window *); 846static void display_menu_bar (struct window *);
844static ptrdiff_t display_count_lines (ptrdiff_t, ptrdiff_t, ptrdiff_t, 847static ptrdiff_t display_count_lines (ptrdiff_t, ptrdiff_t, ptrdiff_t,
845 ptrdiff_t *); 848 ptrdiff_t *);
849static void pint2str (register char *, register int, register ptrdiff_t);
850
846static int display_string (const char *, Lisp_Object, Lisp_Object, 851static int display_string (const char *, Lisp_Object, Lisp_Object,
847 ptrdiff_t, ptrdiff_t, struct it *, int, int, int, int); 852 ptrdiff_t, ptrdiff_t, struct it *, int, int, int, int);
848static void compute_line_metrics (struct it *); 853static void compute_line_metrics (struct it *);
@@ -6764,7 +6769,7 @@ reseat_to_string (struct it *it, const char *s, Lisp_Object string,
6764 FIELD_WIDTH < 0 means infinite field width. This is useful for 6769 FIELD_WIDTH < 0 means infinite field width. This is useful for
6765 padding with `-' at the end of a mode line. */ 6770 padding with `-' at the end of a mode line. */
6766 if (field_width < 0) 6771 if (field_width < 0)
6767 field_width = INFINITY; 6772 field_width = DISP_INFINITY;
6768 /* Implementation note: We deliberately don't enlarge 6773 /* Implementation note: We deliberately don't enlarge
6769 it->bidi_it.string.schars here to fit it->end_charpos, because 6774 it->bidi_it.string.schars here to fit it->end_charpos, because
6770 the bidi iterator cannot produce characters out of thin air. */ 6775 the bidi iterator cannot produce characters out of thin air. */
@@ -8661,9 +8666,16 @@ move_it_in_display_line_to (struct it *it,
8661 || (it->method == GET_FROM_DISPLAY_VECTOR \ 8666 || (it->method == GET_FROM_DISPLAY_VECTOR \
8662 && it->dpvec + it->current.dpvec_index + 1 >= it->dpend))) 8667 && it->dpvec + it->current.dpvec_index + 1 >= it->dpend)))
8663 8668
8664 /* If there's a line-/wrap-prefix, handle it. */ 8669 if (it->hpos == 0)
8665 if (it->hpos == 0 && it->method == GET_FROM_BUFFER) 8670 {
8666 handle_line_prefix (it); 8671 /* If line numbers are being displayed, produce a line number. */
8672 if (should_produce_line_number (it)
8673 && it->current_x == it->first_visible_x)
8674 maybe_produce_line_number (it);
8675 /* If there's a line-/wrap-prefix, handle it. */
8676 if (it->method == GET_FROM_BUFFER)
8677 handle_line_prefix (it);
8678 }
8667 8679
8668 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos)) 8680 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
8669 SET_TEXT_POS (this_line_min_pos, IT_CHARPOS (*it), IT_BYTEPOS (*it)); 8681 SET_TEXT_POS (this_line_min_pos, IT_CHARPOS (*it), IT_BYTEPOS (*it));
@@ -13069,6 +13081,43 @@ hscroll_window_tree (Lisp_Object window)
13069 } 13081 }
13070 bool row_r2l_p = cursor_row->reversed_p; 13082 bool row_r2l_p = cursor_row->reversed_p;
13071 bool hscl = hscrolling_current_line_p (w); 13083 bool hscl = hscrolling_current_line_p (w);
13084 int x_offset = 0;
13085 /* When line numbers are displayed, we need to account for
13086 the horizontal space they consume. */
13087 if (!NILP (Vdisplay_line_numbers))
13088 {
13089 struct glyph *g;
13090 if (!row_r2l_p)
13091 {
13092 for (g = cursor_row->glyphs[TEXT_AREA];
13093 g < cursor_row->glyphs[TEXT_AREA]
13094 + cursor_row->used[TEXT_AREA];
13095 g++)
13096 {
13097 if (!(NILP (g->object) && g->charpos < 0))
13098 break;
13099 x_offset += g->pixel_width;
13100 }
13101 }
13102 else
13103 {
13104 for (g = cursor_row->glyphs[TEXT_AREA]
13105 + cursor_row->used[TEXT_AREA];
13106 g > cursor_row->glyphs[TEXT_AREA];
13107 g--)
13108 {
13109 if (!(NILP ((g - 1)->object) && (g - 1)->charpos < 0))
13110 break;
13111 x_offset += (g - 1)->pixel_width;
13112 }
13113 }
13114 }
13115 if (cursor_row->truncated_on_left_p)
13116 {
13117 /* On TTY frames, don't count the left truncation glyph. */
13118 struct frame *f = XFRAME (WINDOW_FRAME (w));
13119 x_offset -= (FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f));
13120 }
13072 13121
13073 text_area_width = window_box_width (w, TEXT_AREA); 13122 text_area_width = window_box_width (w, TEXT_AREA);
13074 13123
@@ -13101,7 +13150,7 @@ hscroll_window_tree (Lisp_Object window)
13101 inside the left margin and the window is already 13150 inside the left margin and the window is already
13102 hscrolled. */ 13151 hscrolled. */
13103 && ((!row_r2l_p 13152 && ((!row_r2l_p
13104 && ((w->hscroll && w->cursor.x <= h_margin) 13153 && ((w->hscroll && w->cursor.x <= h_margin + x_offset)
13105 || (cursor_row->enabled_p 13154 || (cursor_row->enabled_p
13106 && cursor_row->truncated_on_right_p 13155 && cursor_row->truncated_on_right_p
13107 && (w->cursor.x >= text_area_width - h_margin)))) 13156 && (w->cursor.x >= text_area_width - h_margin))))
@@ -13119,7 +13168,8 @@ hscroll_window_tree (Lisp_Object window)
13119 && cursor_row->truncated_on_right_p 13168 && cursor_row->truncated_on_right_p
13120 && w->cursor.x <= h_margin) 13169 && w->cursor.x <= h_margin)
13121 || (w->hscroll 13170 || (w->hscroll
13122 && (w->cursor.x >= text_area_width - h_margin)))) 13171 && (w->cursor.x >= (text_area_width - h_margin
13172 - x_offset)))))
13123 /* This last condition is needed when moving 13173 /* This last condition is needed when moving
13124 vertically from an hscrolled line to a short line 13174 vertically from an hscrolled line to a short line
13125 that doesn't need to be hscrolled. If we omit 13175 that doesn't need to be hscrolled. If we omit
@@ -13150,7 +13200,7 @@ hscroll_window_tree (Lisp_Object window)
13150 if (hscl) 13200 if (hscl)
13151 it.first_visible_x = window_hscroll_limited (w, it.f) 13201 it.first_visible_x = window_hscroll_limited (w, it.f)
13152 * FRAME_COLUMN_WIDTH (it.f); 13202 * FRAME_COLUMN_WIDTH (it.f);
13153 it.last_visible_x = INFINITY; 13203 it.last_visible_x = DISP_INFINITY;
13154 move_it_in_display_line_to (&it, pt, -1, MOVE_TO_POS); 13204 move_it_in_display_line_to (&it, pt, -1, MOVE_TO_POS);
13155 /* If the line ends in an overlay string with a newline, 13205 /* If the line ends in an overlay string with a newline,
13156 we might infloop, because displaying the window will 13206 we might infloop, because displaying the window will
@@ -14796,15 +14846,12 @@ set_cursor_from_row (struct window *w, struct glyph_row *row,
14796 while (glyph > end + 1 14846 while (glyph > end + 1
14797 && NILP (glyph->object) 14847 && NILP (glyph->object)
14798 && glyph->charpos < 0) 14848 && glyph->charpos < 0)
14799 { 14849 --glyph;
14800 --glyph;
14801 x -= glyph->pixel_width;
14802 }
14803 if (NILP (glyph->object) && glyph->charpos < 0) 14850 if (NILP (glyph->object) && glyph->charpos < 0)
14804 --glyph; 14851 --glyph;
14805 /* By default, in reversed rows we put the cursor on the 14852 /* By default, in reversed rows we put the cursor on the
14806 rightmost (first in the reading order) glyph. */ 14853 rightmost (first in the reading order) glyph. */
14807 for (g = end + 1; g < glyph; g++) 14854 for (x = 0, g = end + 1; g < glyph; g++)
14808 x += g->pixel_width; 14855 x += g->pixel_width;
14809 while (end < glyph 14856 while (end < glyph
14810 && NILP ((end + 1)->object) 14857 && NILP ((end + 1)->object)
@@ -15835,7 +15882,7 @@ compute_window_start_on_continuation_line (struct window *w)
15835 So, we're looking for the display line start with the 15882 So, we're looking for the display line start with the
15836 minimum distance from the old window start. */ 15883 minimum distance from the old window start. */
15837 pos_before_pt = pos = it.current.pos; 15884 pos_before_pt = pos = it.current.pos;
15838 min_distance = INFINITY; 15885 min_distance = DISP_INFINITY;
15839 while ((distance = eabs (CHARPOS (start_pos) - IT_CHARPOS (it))), 15886 while ((distance = eabs (CHARPOS (start_pos) - IT_CHARPOS (it))),
15840 distance < min_distance) 15887 distance < min_distance)
15841 { 15888 {
@@ -15941,6 +15988,17 @@ try_cursor_movement (Lisp_Object window, struct text_pos startp,
15941 && !windows_or_buffers_changed 15988 && !windows_or_buffers_changed
15942 && !f->cursor_type_changed 15989 && !f->cursor_type_changed
15943 && NILP (Vshow_trailing_whitespace) 15990 && NILP (Vshow_trailing_whitespace)
15991 /* When display-line-numbers is in relative mode, moving point
15992 requires to redraw the entire window. */
15993 && !EQ (Vdisplay_line_numbers, Qrelative)
15994 && !EQ (Vdisplay_line_numbers, Qvisual)
15995 /* When the current line number should be displayed in a
15996 distinct face, moving point cannot be handled in optimized
15997 way as below. */
15998 && !(!NILP (Vdisplay_line_numbers)
15999 && NILP (Finternal_lisp_face_equal_p (Qline_number,
16000 Qline_number_current_line,
16001 w->frame)))
15944 /* This code is not used for mini-buffer for the sake of the case 16002 /* This code is not used for mini-buffer for the sake of the case
15945 of redisplaying to replace an echo area message; since in 16003 of redisplaying to replace an echo area message; since in
15946 that case the mini-buffer contents per se are usually 16004 that case the mini-buffer contents per se are usually
@@ -16788,10 +16846,15 @@ redisplay_window (Lisp_Object window, bool just_this_one_p)
16788 XBUFFER (w->contents)->text->redisplay = false; 16846 XBUFFER (w->contents)->text->redisplay = false;
16789 safe__call1 (true, Vpre_redisplay_function, Fcons (window, Qnil)); 16847 safe__call1 (true, Vpre_redisplay_function, Fcons (window, Qnil));
16790 16848
16791 if (w->redisplay || XBUFFER (w->contents)->text->redisplay) 16849 if (w->redisplay || XBUFFER (w->contents)->text->redisplay
16850 || ((EQ (Vdisplay_line_numbers, Qrelative)
16851 || EQ (Vdisplay_line_numbers, Qvisual))
16852 && row != MATRIX_FIRST_TEXT_ROW (w->desired_matrix)))
16792 { 16853 {
16793 /* pre-redisplay-function made changes (e.g. move the region) 16854 /* Either pre-redisplay-function made changes (e.g. move
16794 that require another round of redisplay. */ 16855 the region), or we moved point in a window that is
16856 under display-line-numbers = relative mode. We need
16857 another round of redisplay. */
16795 clear_glyph_matrix (w->desired_matrix); 16858 clear_glyph_matrix (w->desired_matrix);
16796 if (!try_window (window, startp, 0)) 16859 if (!try_window (window, startp, 0))
16797 goto need_larger_matrices; 16860 goto need_larger_matrices;
@@ -17592,6 +17655,12 @@ try_window_reusing_current_matrix (struct window *w)
17592 if (w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row)) 17655 if (w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row))
17593 return false; 17656 return false;
17594 17657
17658 /* Give up if line numbers are being displayed, because reusing the
17659 current matrix might use the wrong width for line-number
17660 display. */
17661 if (!NILP (Vdisplay_line_numbers))
17662 return false;
17663
17595 /* The variable new_start now holds the new window start. The old 17664 /* The variable new_start now holds the new window start. The old
17596 start `start' can be determined from the current matrix. */ 17665 start `start' can be determined from the current matrix. */
17597 SET_TEXT_POS_FROM_MARKER (new_start, w->start); 17666 SET_TEXT_POS_FROM_MARKER (new_start, w->start);
@@ -18423,6 +18492,16 @@ try_window_id (struct window *w)
18423 if (!NILP (BVAR (XBUFFER (w->contents), extra_line_spacing))) 18492 if (!NILP (BVAR (XBUFFER (w->contents), extra_line_spacing)))
18424 GIVE_UP (23); 18493 GIVE_UP (23);
18425 18494
18495 /* Give up if display-line-numbers is in relative mode, or when the
18496 current line's number needs to be displayed in a distinct face. */
18497 if (EQ (Vdisplay_line_numbers, Qrelative)
18498 || EQ (Vdisplay_line_numbers, Qvisual)
18499 || (!NILP (Vdisplay_line_numbers)
18500 && NILP (Finternal_lisp_face_equal_p (Qline_number,
18501 Qline_number_current_line,
18502 w->frame))))
18503 GIVE_UP (24);
18504
18426 /* Make sure beg_unchanged and end_unchanged are up to date. Do it 18505 /* Make sure beg_unchanged and end_unchanged are up to date. Do it
18427 only if buffer has really changed. The reason is that the gap is 18506 only if buffer has really changed. The reason is that the gap is
18428 initially at Z for freshly visited files. The code below would 18507 initially at Z for freshly visited files. The code below would
@@ -20669,6 +20748,352 @@ find_row_edges (struct it *it, struct glyph_row *row,
20669 row->maxpos = it->current.pos; 20748 row->maxpos = it->current.pos;
20670} 20749}
20671 20750
20751/* Like display_count_lines, but capable of counting outside of the
20752 current narrowed region. */
20753static ptrdiff_t
20754display_count_lines_logically (ptrdiff_t start_byte, ptrdiff_t limit_byte,
20755 ptrdiff_t count, ptrdiff_t *byte_pos_ptr)
20756{
20757 if (!display_line_numbers_widen || (BEGV == BEG && ZV == Z))
20758 return display_count_lines (start_byte, limit_byte, count, byte_pos_ptr);
20759
20760 ptrdiff_t val;
20761 ptrdiff_t pdl_count = SPECPDL_INDEX ();
20762 record_unwind_protect (save_restriction_restore, save_restriction_save ());
20763 Fwiden ();
20764 val = display_count_lines (start_byte, limit_byte, count, byte_pos_ptr);
20765 unbind_to (pdl_count, Qnil);
20766 return val;
20767}
20768
20769/* Count the number of screen lines in window IT->w between character
20770 position IT_CHARPOS(*IT) and the line showing that window's point. */
20771static ptrdiff_t
20772display_count_lines_visually (struct it *it)
20773{
20774 struct it tem_it;
20775 ptrdiff_t to;
20776 struct text_pos from;
20777
20778 /* If we already calculated a relative line number, use that. This
20779 trick relies on the fact that visual lines (a.k.a. "glyph rows")
20780 are laid out sequentially, one by one, for each sequence of calls
20781 to display_line or other similar function that follows a call to
20782 init_iterator. */
20783 if (it->lnum_bytepos > 0)
20784 return it->lnum + 1;
20785 else
20786 {
20787 ptrdiff_t count = SPECPDL_INDEX ();
20788
20789 if (IT_CHARPOS (*it) <= PT)
20790 {
20791 from = it->current.pos;
20792 to = PT;
20793 }
20794 else
20795 {
20796 SET_TEXT_POS (from, PT, PT_BYTE);
20797 to = IT_CHARPOS (*it);
20798 }
20799 start_display (&tem_it, it->w, from);
20800 /* Need to disable visual mode temporarily, since otherwise the
20801 call to move_it_to will cause infinite recursion. */
20802 specbind (Qdisplay_line_numbers, Qrelative);
20803 /* Some redisplay optimizations could invoke us very far from
20804 PT, which will make the caller painfully slow. There should
20805 be no need to go too far beyond the window's bottom, as any
20806 such optimization will fail to show point anyway. */
20807 move_it_to (&tem_it, to, -1,
20808 tem_it.last_visible_y
20809 + (SCROLL_LIMIT + 10) * FRAME_LINE_HEIGHT (tem_it.f),
20810 -1, MOVE_TO_POS | MOVE_TO_Y);
20811 unbind_to (count, Qnil);
20812 return IT_CHARPOS (*it) <= PT ? -tem_it.vpos : tem_it.vpos;
20813 }
20814}
20815
20816/* Produce the line-number glyphs for the current glyph_row. If
20817 IT->glyph_row is non-NULL, populate the row with the produced
20818 glyphs. */
20819static void
20820maybe_produce_line_number (struct it *it)
20821{
20822 ptrdiff_t last_line = it->lnum;
20823 ptrdiff_t start_from, bytepos;
20824 ptrdiff_t this_line;
20825 bool first_time = false;
20826 ptrdiff_t beg = display_line_numbers_widen ? BEG : BEGV;
20827 ptrdiff_t beg_byte = display_line_numbers_widen ? BEG_BYTE : BEGV_BYTE;
20828 ptrdiff_t z_byte = display_line_numbers_widen ? Z_BYTE : ZV_BYTE;
20829 void *itdata = bidi_shelve_cache ();
20830
20831 if (EQ (Vdisplay_line_numbers, Qvisual))
20832 this_line = display_count_lines_visually (it);
20833 else
20834 {
20835 if (!last_line)
20836 {
20837 /* FIXME: Maybe reuse the data in it->w->base_line_number. */
20838 start_from = beg;
20839 if (!it->lnum_bytepos)
20840 first_time = true;
20841 }
20842 else
20843 start_from = it->lnum_bytepos;
20844
20845 /* Paranoia: what if someone changes the narrowing since the
20846 last time display_line was called? Shouldn't really happen,
20847 but who knows what some crazy Lisp invoked by :eval could do? */
20848 if (!(beg_byte <= start_from && start_from < z_byte))
20849 {
20850 last_line = 0;
20851 start_from = beg_byte;
20852 }
20853
20854 this_line =
20855 last_line + display_count_lines_logically (start_from,
20856 IT_BYTEPOS (*it),
20857 IT_CHARPOS (*it), &bytepos);
20858 eassert (this_line > 0 || (this_line == 0 && start_from == beg_byte));
20859 eassert (bytepos == IT_BYTEPOS (*it));
20860 }
20861
20862 /* Record the line number information. */
20863 if (this_line != last_line || !it->lnum_bytepos)
20864 {
20865 it->lnum = this_line;
20866 it->lnum_bytepos = IT_BYTEPOS (*it);
20867 }
20868
20869 /* Produce the glyphs for the line number. */
20870 struct it tem_it;
20871 char lnum_buf[INT_STRLEN_BOUND (ptrdiff_t) + 1];
20872 bool beyond_zv = IT_BYTEPOS (*it) >= ZV_BYTE ? true : false;
20873 ptrdiff_t lnum_offset = -1; /* to produce 1-based line numbers */
20874 int lnum_face_id = merge_faces (it->f, Qline_number, 0, DEFAULT_FACE_ID);
20875 int current_lnum_face_id
20876 = merge_faces (it->f, Qline_number_current_line, 0, DEFAULT_FACE_ID);
20877 /* Compute point's line number if needed. */
20878 if ((EQ (Vdisplay_line_numbers, Qrelative)
20879 || EQ (Vdisplay_line_numbers, Qvisual)
20880 || lnum_face_id != current_lnum_face_id)
20881 && !it->pt_lnum)
20882 {
20883 ptrdiff_t ignored;
20884 if (PT_BYTE > it->lnum_bytepos && !EQ (Vdisplay_line_numbers, Qvisual))
20885 it->pt_lnum =
20886 this_line + display_count_lines_logically (it->lnum_bytepos, PT_BYTE,
20887 PT, &ignored);
20888 else
20889 it->pt_lnum = display_count_lines_logically (beg_byte, PT_BYTE, PT,
20890 &ignored);
20891 }
20892 /* Compute the required width if needed. */
20893 if (!it->lnum_width)
20894 {
20895 if (NATNUMP (Vdisplay_line_number_width))
20896 it->lnum_width = XFASTINT (Vdisplay_line_number_width);
20897
20898 /* Max line number to be displayed cannot be more than the one
20899 corresponding to the last row of the desired matrix. */
20900 ptrdiff_t max_lnum;
20901
20902 if (NILP (Vdisplay_line_numbers_current_absolute)
20903 && (EQ (Vdisplay_line_numbers, Qrelative)
20904 || EQ (Vdisplay_line_numbers, Qvisual)))
20905 /* We subtract one more because the current line is always
20906 zero in this mode. */
20907 max_lnum = it->w->desired_matrix->nrows - 2;
20908 else if (EQ (Vdisplay_line_numbers, Qvisual))
20909 max_lnum = it->pt_lnum + it->w->desired_matrix->nrows - 1;
20910 else
20911 max_lnum = this_line + it->w->desired_matrix->nrows - 1 - it->vpos;
20912 max_lnum = max (1, max_lnum);
20913 it->lnum_width = max (it->lnum_width, log10 (max_lnum) + 1);
20914 eassert (it->lnum_width > 0);
20915 }
20916 if (EQ (Vdisplay_line_numbers, Qrelative))
20917 lnum_offset = it->pt_lnum;
20918 else if (EQ (Vdisplay_line_numbers, Qvisual))
20919 lnum_offset = 0;
20920
20921 /* Under 'relative', display the absolute line number for the
20922 current line, unless the user requests otherwise. */
20923 ptrdiff_t lnum_to_display = eabs (this_line - lnum_offset);
20924 if ((EQ (Vdisplay_line_numbers, Qrelative)
20925 || EQ (Vdisplay_line_numbers, Qvisual))
20926 && lnum_to_display == 0
20927 && !NILP (Vdisplay_line_numbers_current_absolute))
20928 lnum_to_display = it->pt_lnum + 1;
20929 /* In L2R rows we need to append the blank separator, in R2L
20930 rows we need to prepend it. But this function is usually
20931 called when no display elements were produced from the
20932 following line, so the paragraph direction might be unknown.
20933 Therefore we cheat and add 2 blanks, one on either side. */
20934 pint2str (lnum_buf, it->lnum_width + 1, lnum_to_display);
20935 strcat (lnum_buf, " ");
20936
20937 /* Setup for producing the glyphs. */
20938 init_iterator (&tem_it, it->w, -1, -1, &scratch_glyph_row,
20939 /* FIXME: Use specialized face. */
20940 DEFAULT_FACE_ID);
20941 scratch_glyph_row.reversed_p = false;
20942 scratch_glyph_row.used[TEXT_AREA] = 0;
20943 SET_TEXT_POS (tem_it.position, 0, 0);
20944 tem_it.avoid_cursor_p = true;
20945 tem_it.bidi_p = true;
20946 tem_it.bidi_it.type = WEAK_EN;
20947 /* According to UAX#9, EN goes up 2 levels in L2R paragraph and
20948 1 level in R2L paragraphs. Emulate that, assuming we are in
20949 an L2R paragraph. */
20950 tem_it.bidi_it.resolved_level = 2;
20951
20952 /* Produce glyphs for the line number in a scratch glyph_row. */
20953 int n_glyphs_before;
20954 for (const char *p = lnum_buf; *p; p++)
20955 {
20956 /* For continuation lines and lines after ZV, instead of a line
20957 number, produce a blank prefix of the same width. Use the
20958 default face for the blank field beyond ZV. */
20959 if (beyond_zv)
20960 tem_it.face_id = it->base_face_id;
20961 else if (lnum_face_id != current_lnum_face_id
20962 && (EQ (Vdisplay_line_numbers, Qvisual)
20963 ? this_line == 0
20964 : this_line == it->pt_lnum))
20965 tem_it.face_id = current_lnum_face_id;
20966 else
20967 tem_it.face_id = lnum_face_id;
20968 if (beyond_zv
20969 /* Don't display the same line number more than once. */
20970 || (!EQ (Vdisplay_line_numbers, Qvisual)
20971 && (it->continuation_lines_width > 0
20972 || (this_line == last_line && !first_time))))
20973 tem_it.c = tem_it.char_to_display = ' ';
20974 else
20975 tem_it.c = tem_it.char_to_display = *p;
20976 tem_it.len = 1;
20977 n_glyphs_before = scratch_glyph_row.used[TEXT_AREA];
20978 /* Make sure these glyphs will have a "position" of -1. */
20979 SET_TEXT_POS (tem_it.position, -1, -1);
20980 PRODUCE_GLYPHS (&tem_it);
20981
20982 /* Stop producing glyphs if we don't have enough space on
20983 this line. FIXME: should we refrain from producing the
20984 line number at all in that case? */
20985 if (tem_it.current_x > tem_it.last_visible_x)
20986 {
20987 scratch_glyph_row.used[TEXT_AREA] = n_glyphs_before;
20988 break;
20989 }
20990 }
20991
20992 /* Record the width in pixels we need for the line number display. */
20993 it->lnum_pixel_width = tem_it.current_x;
20994 /* Copy the produced glyphs into IT's glyph_row. */
20995 struct glyph *g = scratch_glyph_row.glyphs[TEXT_AREA];
20996 struct glyph *e = g + scratch_glyph_row.used[TEXT_AREA];
20997 struct glyph *p = it->glyph_row ? it->glyph_row->glyphs[TEXT_AREA] : NULL;
20998 short *u = it->glyph_row ? &it->glyph_row->used[TEXT_AREA] : NULL;
20999
21000 for ( ; g < e; g++)
21001 {
21002 it->current_x += g->pixel_width;
21003 /* The following is important when this function is called
21004 from move_it_in_display_line_to: HPOS is incremented only
21005 when we are in the visible portion of the glyph row. */
21006 if (it->current_x > it->first_visible_x)
21007 it->hpos++;
21008 if (p)
21009 {
21010 *p++ = *g;
21011 (*u)++;
21012 }
21013 }
21014
21015 /* Update IT's metrics due to glyphs produced for line numbers. */
21016 if (it->glyph_row)
21017 {
21018 struct glyph_row *row = it->glyph_row;
21019
21020 it->max_ascent = max (row->ascent, tem_it.max_ascent);
21021 it->max_descent = max (row->height - row->ascent, tem_it.max_descent);
21022 it->max_phys_ascent = max (row->phys_ascent, tem_it.max_phys_ascent);
21023 it->max_phys_descent = max (row->phys_height - row->phys_ascent,
21024 tem_it.max_phys_descent);
21025 }
21026 else
21027 {
21028 it->max_ascent = max (it->max_ascent, tem_it.max_ascent);
21029 it->max_descent = max (it->max_descent, tem_it.max_descent);
21030 it->max_phys_ascent = max (it->max_phys_ascent, tem_it.max_phys_ascent);
21031 it->max_phys_descent = max (it->max_phys_descent, tem_it.max_phys_descent);
21032 }
21033
21034 bidi_unshelve_cache (itdata, false);
21035}
21036
21037/* Return true if this glyph row needs a line number to be produced
21038 for it. */
21039static bool
21040should_produce_line_number (struct it *it)
21041{
21042 if (NILP (Vdisplay_line_numbers))
21043 return false;
21044
21045 /* Don't display line numbers in minibuffer windows. */
21046 if (MINI_WINDOW_P (it->w))
21047 return false;
21048
21049#ifdef HAVE_WINDOW_SYSTEM
21050 /* Don't display line number in tooltip frames. */
21051 if (FRAMEP (tip_frame) && EQ (WINDOW_FRAME (it->w), tip_frame))
21052 return false;
21053#endif
21054
21055 /* If the character at current position has a non-nil special
21056 property, disable line numbers for this row. This is for
21057 packages such as company-mode, which need this for their tricky
21058 layout, where line numbers get in the way. */
21059 Lisp_Object val = Fget_char_property (make_number (IT_CHARPOS (*it)),
21060 Qdisplay_line_numbers_disable,
21061 it->window);
21062 /* For ZV, we need to also look in empty overlays at that point,
21063 because get-char-property always returns nil for ZV, except if
21064 the property is in 'default-text-properties'. */
21065 if (NILP (val) && IT_CHARPOS (*it) >= ZV)
21066 val = disable_line_numbers_overlay_at_eob ();
21067 return NILP (val) ? true : false;
21068}
21069
21070/* Return true if ROW has no glyphs except those inserted by the
21071 display engine. This is needed for indicate-empty-lines and
21072 similar features when the glyph row starts with glyphs which didn't
21073 come from buffer or string. */
21074static bool
21075row_text_area_empty (struct glyph_row *row)
21076{
21077 if (!row->reversed_p)
21078 {
21079 for (struct glyph *g = row->glyphs[TEXT_AREA];
21080 g < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
21081 g++)
21082 if (!NILP (g->object) || g->charpos > 0)
21083 return false;
21084 }
21085 else
21086 {
21087 for (struct glyph *g = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
21088 g > row->glyphs[TEXT_AREA];
21089 g--)
21090 if (!NILP ((g - 1)->object) || (g - 1)->charpos > 0)
21091 return false;
21092 }
21093
21094 return true;
21095}
21096
20672/* Construct the glyph row IT->glyph_row in the desired matrix of 21097/* Construct the glyph row IT->glyph_row in the desired matrix of
20673 IT->w from text at the current position of IT. See dispextern.h 21098 IT->w from text at the current position of IT. See dispextern.h
20674 for an overview of struct it. Value is true if 21099 for an overview of struct it. Value is true if
@@ -20739,6 +21164,8 @@ display_line (struct it *it, int cursor_vpos)
20739 (window_hscroll_limited (it->w, it->f) - it->w->min_hscroll) 21164 (window_hscroll_limited (it->w, it->f) - it->w->min_hscroll)
20740 * FRAME_COLUMN_WIDTH (it->f); 21165 * FRAME_COLUMN_WIDTH (it->f);
20741 21166
21167 bool line_number_needed = should_produce_line_number (it);
21168
20742 /* Move over display elements that are not visible because we are 21169 /* Move over display elements that are not visible because we are
20743 hscrolled. This may stop at an x-position < first_visible_x 21170 hscrolled. This may stop at an x-position < first_visible_x
20744 if the first glyph is partially visible or if we hit a line end. */ 21171 if the first glyph is partially visible or if we hit a line end. */
@@ -20774,9 +21201,17 @@ display_line (struct it *it, int cursor_vpos)
20774 are hscrolled to the left of the left edge of the window. */ 21201 are hscrolled to the left of the left edge of the window. */
20775 min_pos = CHARPOS (this_line_min_pos); 21202 min_pos = CHARPOS (this_line_min_pos);
20776 min_bpos = BYTEPOS (this_line_min_pos); 21203 min_bpos = BYTEPOS (this_line_min_pos);
21204
21205 /* Produce line number, if needed. */
21206 if (line_number_needed)
21207 maybe_produce_line_number (it);
20777 } 21208 }
20778 else if (it->area == TEXT_AREA) 21209 else if (it->area == TEXT_AREA)
20779 { 21210 {
21211 /* Line numbers should precede the line-prefix or wrap-prefix. */
21212 if (line_number_needed)
21213 maybe_produce_line_number (it);
21214
20780 /* We only do this when not calling move_it_in_display_line_to 21215 /* We only do this when not calling move_it_in_display_line_to
20781 above, because that function calls itself handle_line_prefix. */ 21216 above, because that function calls itself handle_line_prefix. */
20782 handle_line_prefix (it); 21217 handle_line_prefix (it);
@@ -20838,6 +21273,7 @@ display_line (struct it *it, int cursor_vpos)
20838 buffer reached. */ 21273 buffer reached. */
20839 if (!get_next_display_element (it)) 21274 if (!get_next_display_element (it))
20840 { 21275 {
21276 bool row_has_glyphs = false;
20841 /* Maybe add a space at the end of this line that is used to 21277 /* Maybe add a space at the end of this line that is used to
20842 display the cursor there under X. Set the charpos of the 21278 display the cursor there under X. Set the charpos of the
20843 first glyph of blank lines not corresponding to any text 21279 first glyph of blank lines not corresponding to any text
@@ -20846,14 +21282,17 @@ display_line (struct it *it, int cursor_vpos)
20846 row->exact_window_width_line_p = true; 21282 row->exact_window_width_line_p = true;
20847 else if ((append_space_for_newline (it, true) 21283 else if ((append_space_for_newline (it, true)
20848 && row->used[TEXT_AREA] == 1) 21284 && row->used[TEXT_AREA] == 1)
20849 || row->used[TEXT_AREA] == 0) 21285 || row->used[TEXT_AREA] == 0
21286 || (row_has_glyphs = row_text_area_empty (row)))
20850 { 21287 {
20851 row->glyphs[TEXT_AREA]->charpos = -1; 21288 row->glyphs[TEXT_AREA]->charpos = -1;
20852 row->displays_text_p = false; 21289 /* Don't reset the displays_text_p flag if we are
21290 displaying line numbers or line-prefix. */
21291 if (!row_has_glyphs)
21292 row->displays_text_p = false;
20853 21293
20854 if (!NILP (BVAR (XBUFFER (it->w->contents), indicate_empty_lines)) 21294 if (!NILP (BVAR (XBUFFER (it->w->contents), indicate_empty_lines))
20855 && (!MINI_WINDOW_P (it->w) 21295 && (!MINI_WINDOW_P (it->w)))
20856 || (minibuf_level && EQ (it->window, minibuf_window))))
20857 row->indicate_empty_line_p = true; 21296 row->indicate_empty_line_p = true;
20858 } 21297 }
20859 21298
@@ -20935,6 +21374,10 @@ display_line (struct it *it, int cursor_vpos)
20935 process the prefix now. */ 21374 process the prefix now. */
20936 if (it->area == TEXT_AREA && pending_handle_line_prefix) 21375 if (it->area == TEXT_AREA && pending_handle_line_prefix)
20937 { 21376 {
21377 /* Line numbers should precede the line-prefix or wrap-prefix. */
21378 if (line_number_needed)
21379 maybe_produce_line_number (it);
21380
20938 pending_handle_line_prefix = false; 21381 pending_handle_line_prefix = false;
20939 handle_line_prefix (it); 21382 handle_line_prefix (it);
20940 } 21383 }
@@ -22006,7 +22449,7 @@ Value is the new character position of point. */)
22006 reach point, in order to start from its X coordinate. So we 22449 reach point, in order to start from its X coordinate. So we
22007 need to disregard the window's horizontal extent in that case. */ 22450 need to disregard the window's horizontal extent in that case. */
22008 if (it.line_wrap == TRUNCATE) 22451 if (it.line_wrap == TRUNCATE)
22009 it.last_visible_x = INFINITY; 22452 it.last_visible_x = DISP_INFINITY;
22010 22453
22011 if (it.cmp_it.id < 0 22454 if (it.cmp_it.id < 0
22012 && it.method == GET_FROM_STRING 22455 && it.method == GET_FROM_STRING
@@ -22099,7 +22542,7 @@ Value is the new character position of point. */)
22099 { 22542 {
22100 start_display (&it, w, pt); 22543 start_display (&it, w, pt);
22101 if (it.line_wrap == TRUNCATE) 22544 if (it.line_wrap == TRUNCATE)
22102 it.last_visible_x = INFINITY; 22545 it.last_visible_x = DISP_INFINITY;
22103 reseat_at_previous_visible_line_start (&it); 22546 reseat_at_previous_visible_line_start (&it);
22104 it.current_x = it.current_y = it.hpos = 0; 22547 it.current_x = it.current_y = it.hpos = 0;
22105 if (pt_vpos != 0) 22548 if (pt_vpos != 0)
@@ -27616,15 +28059,23 @@ x_produce_glyphs (struct it *it)
27616 { 28059 {
27617 int tab_width = it->tab_width * font->space_width; 28060 int tab_width = it->tab_width * font->space_width;
27618 int x = it->current_x + it->continuation_lines_width; 28061 int x = it->current_x + it->continuation_lines_width;
28062 int x0 = x;
28063 /* Adjust for line numbers, if needed. */
28064 if (!NILP (Vdisplay_line_numbers) && x0 >= it->lnum_pixel_width)
28065 x -= it->lnum_pixel_width;
27619 int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width; 28066 int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width;
27620 28067
27621 /* If the distance from the current position to the next tab 28068 /* If the distance from the current position to the next tab
27622 stop is less than a space character width, use the 28069 stop is less than a space character width, use the
27623 tab stop after that. */ 28070 tab stop after that. */
27624 if (next_tab_x - x < font->space_width) 28071 if (next_tab_x - x0 < font->space_width)
27625 next_tab_x += tab_width; 28072 next_tab_x += tab_width;
28073 if (!NILP (Vdisplay_line_numbers) && x0 >= it->lnum_pixel_width)
28074 next_tab_x += (it->lnum_pixel_width
28075 - ((it->w->hscroll * font->space_width)
28076 % tab_width));
27626 28077
27627 it->pixel_width = next_tab_x - x; 28078 it->pixel_width = next_tab_x - x0;
27628 it->nglyphs = 1; 28079 it->nglyphs = 1;
27629 if (FONT_TOO_HIGH (font)) 28080 if (FONT_TOO_HIGH (font))
27630 { 28081 {
@@ -31708,6 +32159,12 @@ They are still logged to the *Messages* buffer. */);
31708 /* Name of the face used to highlight trailing whitespace. */ 32159 /* Name of the face used to highlight trailing whitespace. */
31709 DEFSYM (Qtrailing_whitespace, "trailing-whitespace"); 32160 DEFSYM (Qtrailing_whitespace, "trailing-whitespace");
31710 32161
32162 /* Names of the faces used to display line numbers. */
32163 DEFSYM (Qline_number, "line-number");
32164 DEFSYM (Qline_number_current_line, "line-number-current-line");
32165 /* Name of a text property which disables line-number display. */
32166 DEFSYM (Qdisplay_line_numbers_disable, "display-line-numbers-disable");
32167
31711 /* Name and number of the face used to highlight escape glyphs. */ 32168 /* Name and number of the face used to highlight escape glyphs. */
31712 DEFSYM (Qescape_glyph, "escape-glyph"); 32169 DEFSYM (Qescape_glyph, "escape-glyph");
31713 32170
@@ -32215,6 +32672,46 @@ To add a prefix to continuation lines, use `wrap-prefix'. */);
32215 DEFSYM (Qline_prefix, "line-prefix"); 32672 DEFSYM (Qline_prefix, "line-prefix");
32216 Fmake_variable_buffer_local (Qline_prefix); 32673 Fmake_variable_buffer_local (Qline_prefix);
32217 32674
32675 DEFVAR_LISP ("display-line-numbers", Vdisplay_line_numbers,
32676 doc: /* Non-nil means display line numbers.
32677By default, line numbers are displayed before each non-continuation
32678line that displays buffer text, i.e. after each newline that came
32679from buffer text. However, if the value is `visual', every screen
32680line will have a number.
32681
32682Lisp programs can disable display of a line number of a particular
32683screen line by putting the `display-line-numbers-disable' text
32684property or overlay property on the first visible character of
32685that line. */);
32686 Vdisplay_line_numbers = Qnil;
32687 DEFSYM (Qdisplay_line_numbers, "display-line-numbers");
32688 Fmake_variable_buffer_local (Qdisplay_line_numbers);
32689 DEFSYM (Qrelative, "relative");
32690 DEFSYM (Qvisual, "visual");
32691
32692 DEFVAR_LISP ("display-line-number-width", Vdisplay_line_number_width,
32693 doc: /* Minimum width of space reserved for line number display.
32694A positive number means reserve that many columns for line numbers,
32695even if the actual number needs less space.
32696The default value of nil means compute the space dynamically.
32697Any other value is treated as nil. */);
32698 Vdisplay_line_number_width = Qnil;
32699 DEFSYM (Qdisplay_line_number_width, "display-line-number-width");
32700 Fmake_variable_buffer_local (Qdisplay_line_number_width);
32701
32702 DEFVAR_LISP ("display-line-numbers-current-absolute",
32703 Vdisplay_line_numbers_current_absolute,
32704 doc: /* Non-nil means display absolute number of current line.
32705This variable has effect only when `display-line-numbers' is
32706either `relative' or `visual'. */);
32707 Vdisplay_line_numbers_current_absolute = Qt;
32708
32709 DEFVAR_BOOL ("display-line-numbers-widen", display_line_numbers_widen,
32710 doc: /* Non-nil means display line numbers disregarding any narrowing. */);
32711 display_line_numbers_widen = false;
32712 DEFSYM (Qdisplay_line_numbers_widen, "display-line-numbers-widen");
32713 Fmake_variable_buffer_local (Qdisplay_line_numbers_widen);
32714
32218 DEFVAR_BOOL ("inhibit-eval-during-redisplay", inhibit_eval_during_redisplay, 32715 DEFVAR_BOOL ("inhibit-eval-during-redisplay", inhibit_eval_during_redisplay,
32219 doc: /* Non-nil means don't eval Lisp during redisplay. */); 32716 doc: /* Non-nil means don't eval Lisp during redisplay. */);
32220 inhibit_eval_during_redisplay = false; 32717 inhibit_eval_during_redisplay = false;