aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard M. Stallman1993-03-21 23:04:18 +0000
committerRichard M. Stallman1993-03-21 23:04:18 +0000
commitaa6d10fafd1aa7680a5942d86d5de781e8b65e6a (patch)
treec96d5ca0acae9e1242a43aa883a3b8cad028a8f1
parent427aa35a107e1eb9cfd734ee9f51821f08f259b5 (diff)
downloademacs-aa6d10fafd1aa7680a5942d86d5de781e8b65e6a.tar.gz
emacs-aa6d10fafd1aa7680a5942d86d5de781e8b65e6a.zip
(decode_mode_spec): Handle `%l'.
(display_count_lines): New function. (redisplay_window): Update base_line_number and base_line_pos fields. Always update mode line if it's an integer.
-rw-r--r--src/xdisp.c165
1 files changed, 159 insertions, 6 deletions
diff --git a/src/xdisp.c b/src/xdisp.c
index ee8d744958e..5308e9d217b 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -129,6 +129,7 @@ static char *fmodetrunc ();
129static char *decode_mode_spec (); 129static char *decode_mode_spec ();
130static int display_string (); 130static int display_string ();
131static void display_menu_bar (); 131static void display_menu_bar ();
132static int display_count_lines ();
132 133
133/* Prompt to display in front of the minibuffer contents */ 134/* Prompt to display in front of the minibuffer contents */
134char *minibuf_prompt; 135char *minibuf_prompt;
@@ -168,6 +169,12 @@ int clip_changed;
168 since last redisplay that finished */ 169 since last redisplay that finished */
169int windows_or_buffers_changed; 170int windows_or_buffers_changed;
170 171
172/* Nonzero after display_mode_line if %l was used
173 and it displayed a line number. */
174int line_number_displayed;
175
176/* Maximum buffer size for which to display line numbers. */
177int line_number_display_limit;
171 178
172/* Specify m, a string, as a message in the minibuf. If m is 0, clear out 179/* Specify m, a string, as a message in the minibuf. If m is 0, clear out
173 any existing message, and let the minibuffer text show through. */ 180 any existing message, and let the minibuffer text show through. */
@@ -819,9 +826,11 @@ redisplay_window (window, just_this_one)
819 startp = marker_position (w->start); 826 startp = marker_position (w->start);
820 827
821 /* Handle case where place to start displaying has been specified, 828 /* Handle case where place to start displaying has been specified,
822 unless the specified location is outside the visible range. */ 829 unless the specified location is outside the accessible range. */
823 if (!NILP (w->force_start)) 830 if (!NILP (w->force_start))
824 { 831 {
832 /* Forget any recorded base line for line number display. */
833 w->base_line_number = Qnil;
825 w->update_mode_line = Qt; 834 w->update_mode_line = Qt;
826 w->force_start = Qnil; 835 w->force_start = Qnil;
827 XFASTINT (w->last_modified) = 0; 836 XFASTINT (w->last_modified) = 0;
@@ -928,7 +937,12 @@ redisplay_window (window, just_this_one)
928 /* If point has not moved off frame, accept the results */ 937 /* If point has not moved off frame, accept the results */
929 try_window (window, startp); 938 try_window (window, startp);
930 if (cursor_vpos >= 0) 939 if (cursor_vpos >= 0)
931 goto done; 940 {
941 if (!just_this_one || clip_changed || beg_unchanged < startp)
942 /* Forget any recorded base line for line number display. */
943 w->base_line_number = Qnil;
944 goto done;
945 }
932 else 946 else
933 cancel_my_columns (w); 947 cancel_my_columns (w);
934 } 948 }
@@ -955,7 +969,12 @@ redisplay_window (window, just_this_one)
955 { 969 {
956 try_window (window, pos.bufpos); 970 try_window (window, pos.bufpos);
957 if (cursor_vpos >= 0) 971 if (cursor_vpos >= 0)
958 goto done; 972 {
973 if (!just_this_one || clip_changed || beg_unchanged < startp)
974 /* Forget any recorded base line for line number display. */
975 w->base_line_number = Qnil;
976 goto done;
977 }
959 else 978 else
960 cancel_my_columns (w); 979 cancel_my_columns (w);
961 } 980 }
@@ -965,6 +984,9 @@ redisplay_window (window, just_this_one)
965 /* Finally, just choose place to start which centers point */ 984 /* Finally, just choose place to start which centers point */
966 985
967recenter: 986recenter:
987 /* Forget any previously recorded base line for line number display. */
988 w->base_line_number = Qnil;
989
968 pos = *vmotion (point, - height / 2, width, hscroll, window); 990 pos = *vmotion (point, - height / 2, width, hscroll, window);
969 try_window (window, pos.bufpos); 991 try_window (window, pos.bufpos);
970 992
@@ -973,12 +995,19 @@ recenter:
973 (startp == BEGV || FETCH_CHAR (startp - 1) == '\n') ? Qt : Qnil; 995 (startp == BEGV || FETCH_CHAR (startp - 1) == '\n') ? Qt : Qnil;
974 996
975done: 997done:
976 /* If window not full width, must redo its mode line
977 if the window to its side is being redone */
978 if ((!NILP (w->update_mode_line) 998 if ((!NILP (w->update_mode_line)
979 || (!just_this_one && width < FRAME_WIDTH (f) - 1)) 999 /* If window not full width, must redo its mode line
1000 if the window to its side is being redone */
1001 || (!just_this_one && width < FRAME_WIDTH (f) - 1)
1002 || INTEGERP (w->base_line_pos))
980 && height != XFASTINT (w->height)) 1003 && height != XFASTINT (w->height))
981 display_mode_line (w); 1004 display_mode_line (w);
1005 if (! line_number_displayed
1006 && ! BUFFERP (w->base_line_pos))
1007 {
1008 w->base_line_pos = Qnil;
1009 w->base_line_number = Qnil;
1010 }
982 1011
983 /* When we reach a frame's selected window, redo the frame's menu bar. */ 1012 /* When we reach a frame's selected window, redo the frame's menu bar. */
984 if (!NILP (w->update_mode_line) 1013 if (!NILP (w->update_mode_line)
@@ -1889,6 +1918,8 @@ display_mode_line (w)
1889 register int right = XFASTINT (w->width) + left; 1918 register int right = XFASTINT (w->width) + left;
1890 register FRAME_PTR f = XFRAME (WINDOW_FRAME (w)); 1919 register FRAME_PTR f = XFRAME (WINDOW_FRAME (w));
1891 1920
1921 line_number_displayed = 0;
1922
1892 get_display_line (f, vpos, left); 1923 get_display_line (f, vpos, left);
1893 display_mode_element (w, vpos, left, 0, right, right, 1924 display_mode_element (w, vpos, left, 0, right, right,
1894 current_buffer->mode_line_format); 1925 current_buffer->mode_line_format);
@@ -2181,6 +2212,93 @@ decode_mode_spec (w, c, maxwidth)
2181#endif 2212#endif
2182 break; 2213 break;
2183 2214
2215 case 'l':
2216 {
2217 int startpos = marker_position (w->start);
2218 int line, linepos, topline;
2219 int nlines, junk;
2220 Lisp_Object tem;
2221 int height = XFASTINT (w->height);
2222
2223 /* If we decided that this buffer isn't suitable for line numbers,
2224 don't forget that too fast. */
2225 if (EQ (w->base_line_pos, w->buffer))
2226 return "??";
2227
2228 /* If the buffer is very big, don't waste time. */
2229 if (ZV - BEGV > line_number_display_limit)
2230 {
2231 w->base_line_pos = Qnil;
2232 w->base_line_number = Qnil;
2233 return "??";
2234 }
2235
2236 if (!NILP (w->base_line_number)
2237 && !NILP (w->base_line_pos)
2238 && XFASTINT (w->base_line_pos) <= marker_position (w->start))
2239 {
2240 line = XFASTINT (w->base_line_number);
2241 linepos = XFASTINT (w->base_line_pos);
2242 }
2243 else
2244 {
2245 line = 1;
2246 linepos = BEGV;
2247 }
2248
2249 /* Count lines from base line to window start position. */
2250 nlines = display_count_lines (linepos, startpos, startpos, &junk);
2251
2252 topline = nlines + line;
2253
2254 /* Determine a new base line, if the old one is too close
2255 or too far away, or if we did not have one.
2256 "Too close" means it's plausible a scroll-down would
2257 go back past it. */
2258 if (startpos == BEGV)
2259 {
2260 XFASTINT (w->base_line_number) = topline;
2261 XFASTINT (w->base_line_pos) = BEGV;
2262 }
2263 else if (nlines < height + 25 || nlines > height * 3 + 50
2264 || linepos == BEGV)
2265 {
2266 int limit = BEGV;
2267 int position;
2268 int distance = (height * 2 + 30) * 200;
2269
2270 if (startpos - distance > limit)
2271 limit = startpos - distance;
2272
2273 nlines = display_count_lines (startpos, limit,
2274 -(height * 2 + 30),
2275 &position);
2276 /* If we couldn't find the lines we wanted within
2277 200 chars per line,
2278 give up on line numbers for this window. */
2279 if (position == startpos - distance)
2280 {
2281 w->base_line_pos = w->buffer;
2282 w->base_line_number = Qnil;
2283 return "??";
2284 }
2285
2286 XFASTINT (w->base_line_number) = topline - nlines;
2287 XFASTINT (w->base_line_pos) = position;
2288 }
2289
2290 /* Now count lines from the start pos to point. */
2291 nlines = display_count_lines (startpos, PT, PT, &junk);
2292
2293 /* Record that we did display the line number. */
2294 line_number_displayed = 1;
2295
2296 /* Make the string to show. */
2297 sprintf (decode_mode_spec_buf, "%d", topline + nlines);
2298 return decode_mode_spec_buf;
2299 }
2300 break;
2301
2184 case 'm': 2302 case 'm':
2185 obj = current_buffer->mode_name; 2303 obj = current_buffer->mode_name;
2186 break; 2304 break;
@@ -2284,6 +2402,37 @@ decode_mode_spec (w, c, maxwidth)
2284 else 2402 else
2285 return ""; 2403 return "";
2286} 2404}
2405
2406/* Count up to N lines starting from FROM.
2407 But don't go beyond LIMIT.
2408 Return the number of lines thus found (always positive).
2409 Store the position after what was found into *POS_PTR. */
2410
2411static int
2412display_count_lines (from, limit, n, pos_ptr)
2413 int from, limit, n;
2414 int *pos_ptr;
2415{
2416 int oldbegv = BEGV;
2417 int oldzv = ZV;
2418 int shortage = 0;
2419
2420 if (limit < from)
2421 BEGV = limit;
2422 else
2423 ZV = limit;
2424
2425 *pos_ptr = scan_buffer ('\n', from, n, &shortage);
2426
2427 ZV = oldzv;
2428 BEGV = oldbegv;
2429
2430 if (n < 0)
2431 /* When scanning backwards, scan_buffer stops *after* the last newline
2432 it finds, but does count it. Compensate for that. */
2433 return - n - shortage - (*pos_ptr != limit);
2434 return n - shortage;
2435}
2287 2436
2288/* Display STRING on one line of window W, starting at HPOS. 2437/* Display STRING on one line of window W, starting at HPOS.
2289 Display at position VPOS. Caller should have done get_display_line. 2438 Display at position VPOS. Caller should have done get_display_line.
@@ -2462,6 +2611,10 @@ If this is zero, point is always centered after it moves off frame.");
2462 DEFVAR_BOOL ("mode-line-inverse-video", &mode_line_inverse_video, 2611 DEFVAR_BOOL ("mode-line-inverse-video", &mode_line_inverse_video,
2463 "*Non-nil means use inverse video for the mode line."); 2612 "*Non-nil means use inverse video for the mode line.");
2464 mode_line_inverse_video = 1; 2613 mode_line_inverse_video = 1;
2614
2615 DEFVAR_INT ("line-number-display-limit", &line_number_display_limit,
2616 "*Maximum buffer size for which line number should be displayed.");
2617 line_number_display_limit = 1000000;
2465} 2618}
2466 2619
2467/* initialize the window system */ 2620/* initialize the window system */