Mercurial > emacs
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 { |