comparison src/xdisp.c @ 2303:00e3cc81c1be

(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.
author Richard M. Stallman <rms@gnu.org>
date Sun, 21 Mar 1993 23:04:18 +0000
parents 9793d8654e23
children 24cd3df6f184
comparison
equal deleted inserted replaced
2302:560f7fcb759c 2303:00e3cc81c1be
127 static int display_mode_element (); 127 static int display_mode_element ();
128 static char *fmodetrunc (); 128 static char *fmodetrunc ();
129 static char *decode_mode_spec (); 129 static char *decode_mode_spec ();
130 static int display_string (); 130 static int display_string ();
131 static void display_menu_bar (); 131 static void display_menu_bar ();
132 static 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 */
134 char *minibuf_prompt; 135 char *minibuf_prompt;
135 136
136 /* Width in columns of current minibuffer prompt. */ 137 /* Width in columns of current minibuffer prompt. */
166 167
167 /* Nonzero if window sizes or contents have changed 168 /* Nonzero if window sizes or contents have changed
168 since last redisplay that finished */ 169 since last redisplay that finished */
169 int windows_or_buffers_changed; 170 int windows_or_buffers_changed;
170 171
172 /* Nonzero after display_mode_line if %l was used
173 and it displayed a line number. */
174 int line_number_displayed;
175
176 /* Maximum buffer size for which to display line numbers. */
177 int 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. */
174 void 181 void
175 message1 (m) 182 message1 (m)
817 goto recenter; 824 goto recenter;
818 825
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;
828 if (startp < BEGV) startp = BEGV; 837 if (startp < BEGV) startp = BEGV;
829 if (startp > ZV) startp = ZV; 838 if (startp > ZV) startp = ZV;
926 { 935 {
927 /* Try to redisplay starting at same place as before */ 936 /* Try to redisplay starting at same place as before */
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 }
935 949
936 XFASTINT (w->last_modified) = 0; 950 XFASTINT (w->last_modified) = 0;
953 967
954 if (point >= pos.bufpos) 968 if (point >= pos.bufpos)
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 }
962 scroll_fail: ; 981 scroll_fail: ;
963 } 982 }
964 983
965 /* Finally, just choose place to start which centers point */ 984 /* Finally, just choose place to start which centers point */
966 985
967 recenter: 986 recenter:
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
971 startp = marker_position (w->start); 993 startp = marker_position (w->start);
972 w->start_at_line_beg = 994 w->start_at_line_beg =
973 (startp == BEGV || FETCH_CHAR (startp - 1) == '\n') ? Qt : Qnil; 995 (startp == BEGV || FETCH_CHAR (startp - 1) == '\n') ? Qt : Qnil;
974 996
975 done: 997 done:
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)
985 && FRAME_MENU_BAR_LINES (f) > 0 1014 && FRAME_MENU_BAR_LINES (f) > 0
986 && EQ (FRAME_SELECTED_WINDOW (f), window)) 1015 && EQ (FRAME_SELECTED_WINDOW (f), window))
1886 { 1915 {
1887 register int vpos = XFASTINT (w->height) + XFASTINT (w->top) - 1; 1916 register int vpos = XFASTINT (w->height) + XFASTINT (w->top) - 1;
1888 register int left = XFASTINT (w->left); 1917 register int left = XFASTINT (w->left);
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));
1920
1921 line_number_displayed = 0;
1891 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);
1895 FRAME_DESIRED_GLYPHS (f)->bufp[vpos] = 0; 1926 FRAME_DESIRED_GLYPHS (f)->bufp[vpos] = 0;
2179 return decode_mode_spec_buf; 2210 return decode_mode_spec_buf;
2180 } 2211 }
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;
2187 2305
2188 case 'n': 2306 case 'n':
2282 if (XTYPE (obj) == Lisp_String) 2400 if (XTYPE (obj) == Lisp_String)
2283 return (char *) XSTRING (obj)->data; 2401 return (char *) XSTRING (obj)->data;
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
2411 static int
2412 display_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.
2290 If VPOS == -1, display it as the current frame's title. 2439 If VPOS == -1, display it as the current frame's title.
2291 2440
2460 truncate_partial_width_windows = 1; 2609 truncate_partial_width_windows = 1;
2461 2610
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 */
2468 init_xdisp () 2621 init_xdisp ()
2469 { 2622 {