aboutsummaryrefslogtreecommitdiffstats
path: root/src/indent.c
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/indent.c
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/indent.c')
-rw-r--r--src/indent.c70
1 files changed, 69 insertions, 1 deletions
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}