diff options
| author | Eli Zaretskii | 2017-07-08 10:49:36 +0300 |
|---|---|---|
| committer | Eli Zaretskii | 2017-07-08 10:49:36 +0300 |
| commit | 5df239fc6ffbbb16ea6e5546fbec1508bf2cb4b7 (patch) | |
| tree | 9b1b8baff1c3ca9c9c560460b34a7951723f621c /src/indent.c | |
| parent | b8ead34f5df92b771520f4d090ff6cde49ca5705 (diff) | |
| parent | 13786d5e7d0aa0a37d7f81d1a1b82eddd3472796 (diff) | |
| download | emacs-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.c | 70 |
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. */ | ||
| 1951 | static void | ||
| 1952 | line_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 | |||
| 1986 | DEFUN ("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. | ||
| 1989 | If optional argument PIXELWISE is non-nil, return the width in pixels, | ||
| 1990 | otherwise return the width in columns of the face used to display | ||
| 1991 | line 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). */ |
| 1952 | static int | 2003 | static 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 | } |