diff options
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 | } |