aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEli Zaretskii2017-07-07 12:21:10 +0300
committerEli Zaretskii2017-07-07 12:21:10 +0300
commit4caf65d4de591089c82ccf542a31ea5009a3c717 (patch)
tree540c37b0e457351a6840d1060692569b1e6ac2e3 /src
parent25bc3911615d1160d47287c023545c6e0587739f (diff)
downloademacs-4caf65d4de591089c82ccf542a31ea5009a3c717.tar.gz
emacs-4caf65d4de591089c82ccf542a31ea5009a3c717.zip
Fix vertical-motion across the place where line-number width changes
* 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. * doc/lispref/display.texi (Size of Displayed Text): Document line-number-display-width. * etc/NEWS: Mention line-number-display-width. * 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.
Diffstat (limited to 'src')
-rw-r--r--src/indent.c84
1 files changed, 62 insertions, 22 deletions
diff --git a/src/indent.c b/src/indent.c
index 70351f90466..ba936509934 100644
--- a/src/indent.c
+++ b/src/indent.c
@@ -1947,6 +1947,59 @@ 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 /* FIXME: The "+ 2" part knows that we add a blank on each side of
1999 the line number when producing glyphs for display. */
2000 return make_number (width + 2);
2001}
2002
1950/* In window W (derived from WINDOW), return x coordinate for column 2003/* In window W (derived from WINDOW), return x coordinate for column
1951 COL (derived from COLUMN). */ 2004 COL (derived from COLUMN). */
1952static int 2005static int
@@ -2073,30 +2126,10 @@ whether or not it is currently displayed in some window. */)
2073 that's what normal window redisplay does. Otherwise C-n/C-p 2126 that's what normal window redisplay does. Otherwise C-n/C-p
2074 will sometimes err by one column. */ 2127 will sometimes err by one column. */
2075 int lnum_width = 0; 2128 int lnum_width = 0;
2129 int lnum_pixel_width = 0;
2076 if (!NILP (Vdisplay_line_numbers) 2130 if (!NILP (Vdisplay_line_numbers)
2077 && !EQ (Vdisplay_line_numbers, Qvisual)) 2131 && !EQ (Vdisplay_line_numbers, Qvisual))
2078 { 2132 line_number_display_width (w, &lnum_width, &lnum_pixel_width);
2079 struct text_pos wstart;
2080 bool saved_restriction = false;
2081 ptrdiff_t count1 = SPECPDL_INDEX ();
2082 SET_TEXT_POS_FROM_MARKER (wstart, w->start);
2083 itdata = bidi_shelve_cache ();
2084 /* We must start from window's start point, but it could be
2085 outside the accessible region. */
2086 if (wstart.charpos < BEGV || wstart.charpos > ZV)
2087 {
2088 record_unwind_protect (save_restriction_restore,
2089 save_restriction_save ());
2090 Fwiden ();
2091 saved_restriction = true;
2092 }
2093 start_display (&it, w, wstart);
2094 move_it_by_lines (&it, 1);
2095 lnum_width = it.lnum_width;
2096 if (saved_restriction)
2097 unbind_to (count1, Qnil);
2098 bidi_unshelve_cache (itdata, 0);
2099 }
2100 SET_TEXT_POS (pt, PT, PT_BYTE); 2133 SET_TEXT_POS (pt, PT, PT_BYTE);
2101 itdata = bidi_shelve_cache (); 2134 itdata = bidi_shelve_cache ();
2102 start_display (&it, w, pt); 2135 start_display (&it, w, pt);
@@ -2277,6 +2310,12 @@ whether or not it is currently displayed in some window. */)
2277 an addition to the hscroll amount. */ 2310 an addition to the hscroll amount. */
2278 if (lcols_given) 2311 if (lcols_given)
2279 { 2312 {
2313 /* If we are displaying line numbers, we could cross the
2314 line where the width of the line-number display changes,
2315 in which case we need to fix up the pixel coordinate
2316 accordingly. */
2317 if (lnum_pixel_width > 0)
2318 to_x += it.lnum_pixel_width - lnum_pixel_width;
2280 move_it_in_display_line (&it, ZV, first_x + to_x, MOVE_TO_X); 2319 move_it_in_display_line (&it, ZV, first_x + to_x, MOVE_TO_X);
2281 /* If we find ourselves in the middle of an overlay string 2320 /* If we find ourselves in the middle of an overlay string
2282 which includes a newline after current string position, 2321 which includes a newline after current string position,
@@ -2322,6 +2361,7 @@ syms_of_indent (void)
2322 defsubr (&Sindent_to); 2361 defsubr (&Sindent_to);
2323 defsubr (&Scurrent_column); 2362 defsubr (&Scurrent_column);
2324 defsubr (&Smove_to_column); 2363 defsubr (&Smove_to_column);
2364 defsubr (&Sline_number_display_width);
2325 defsubr (&Svertical_motion); 2365 defsubr (&Svertical_motion);
2326 defsubr (&Scompute_motion); 2366 defsubr (&Scompute_motion);
2327} 2367}