aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorRichard M. Stallman1998-01-01 02:27:27 +0000
committerRichard M. Stallman1998-01-01 02:27:27 +0000
commit12adba3450a05ca94bb250094275fc601c35aa57 (patch)
treea6639cd4a649257c89de61b0f1451ffae7de575f /src
parentb73ea88edf86ce4878ad3f9d27c9dc9dcac0bb59 (diff)
downloademacs-12adba3450a05ca94bb250094275fc601c35aa57.tar.gz
emacs-12adba3450a05ca94bb250094275fc601c35aa57.zip
(redisplay_internal): Use scan_newline.
(try_window_id): Use scan_newline. (display_text_line): Use scan_newline. (pos_tab_indent): Moved from indent,c. Now static. Take POS in bytes and chars. Callers changed. (redisplay_window): Handle byte and char positions. (try_window): Don't move W->start if it's already at right place. (display_count_lines): Several changes in args. Do the work directly. (display_scan_buffer): Function deleted. (decode_mode_spec): Pass new arg. (message_log_check_duplicate): Take charpos and bytepos args. (message_dolog): Use markers to update old PT, BEGV, ZV. Use scan_newline. Handle positions in bytes and chars. (try_window): Pass bytepos to and from display_text_line. (try_window_id): Likewise. Use byte pos as well as charpos. (redisplay_internal): Handle bytepos for tlbufpos. (message): Cast last arg to doprnt.
Diffstat (limited to 'src')
-rw-r--r--src/xdisp.c597
1 files changed, 366 insertions, 231 deletions
diff --git a/src/xdisp.c b/src/xdisp.c
index 0a4033729a4..03157e30c46 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -262,6 +262,8 @@ Lisp_Object Vmessage_log_max;
262 262
263#define COERCE_MARKER(X) \ 263#define COERCE_MARKER(X) \
264 (MARKERP ((X)) ? Fmarker_position (X) : (X)) 264 (MARKERP ((X)) ? Fmarker_position (X) : (X))
265
266static int pos_tab_offset P_ ((struct window *, int, int));
265 267
266/* Output a newline in the *Messages* buffer if "needs" one. */ 268/* Output a newline in the *Messages* buffer if "needs" one. */
267 269
@@ -285,7 +287,7 @@ message_dolog (m, len, nlflag)
285 if (!NILP (Vmessage_log_max)) 287 if (!NILP (Vmessage_log_max))
286 { 288 {
287 struct buffer *oldbuf; 289 struct buffer *oldbuf;
288 int oldpoint, oldbegv, oldzv; 290 Lisp_Object oldpoint, oldbegv, oldzv;
289 int old_windows_or_buffers_changed = windows_or_buffers_changed; 291 int old_windows_or_buffers_changed = windows_or_buffers_changed;
290 int point_at_end = 0; 292 int point_at_end = 0;
291 int zv_at_end = 0; 293 int zv_at_end = 0;
@@ -293,16 +295,21 @@ message_dolog (m, len, nlflag)
293 oldbuf = current_buffer; 295 oldbuf = current_buffer;
294 Fset_buffer (Fget_buffer_create (build_string ("*Messages*"))); 296 Fset_buffer (Fget_buffer_create (build_string ("*Messages*")));
295 current_buffer->undo_list = Qt; 297 current_buffer->undo_list = Qt;
296 oldpoint = PT; 298
297 oldbegv = BEGV; 299 oldpoint = Fpoint_marker ();
298 oldzv = ZV; 300 oldbegv = Fpoint_min_marker ();
299 BEGV = BEG; 301 oldzv = Fpoint_max_marker ();
300 ZV = Z; 302
301 if (oldpoint == Z) 303 if (oldpoint == Z)
302 point_at_end = 1; 304 point_at_end = 1;
303 if (oldzv == Z) 305 if (oldzv == Z)
304 zv_at_end = 1; 306 zv_at_end = 1;
305 TEMP_SET_PT (Z); 307
308 BEGV = BEG;
309 BEGV_BYTE = BEG_BYTE;
310 ZV = Z;
311 ZV_BYTE = Z_BYTE;
312 TEMP_SET_PT_BOTH (Z, Z_BYTE);
306 313
307 /* Insert the string--maybe converting multibyte to single byte 314 /* Insert the string--maybe converting multibyte to single byte
308 or vice versa, so that all the text fits the buffer. */ 315 or vice versa, so that all the text fits the buffer. */
@@ -339,27 +346,29 @@ message_dolog (m, len, nlflag)
339 } 346 }
340 } 347 }
341 else if (len) 348 else if (len)
342 insert_1 (m, len, 1, 0); 349 insert_1 (m, len, 1, 0, 0);
343 350
344 if (nlflag) 351 if (nlflag)
345 { 352 {
346 int this_bol, prev_bol, dup; 353 int this_bol, this_bol_byte, prev_bol, prev_bol_byte, dup;
347 insert_1 ("\n", 1, 1, 0); 354 insert_1 ("\n", 1, 1, 0, 0);
355
356 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE, -2, 0);
357 this_bol = PT;
358 this_bol_byte = PT_BYTE;
348 359
349 this_bol = scan_buffer ('\n', Z, 0, -2, 0, 0);
350 if (this_bol > BEG) 360 if (this_bol > BEG)
351 { 361 {
352 prev_bol = scan_buffer ('\n', this_bol, 0, -2, 0, 0); 362 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE, -2, 0);
353 dup = message_log_check_duplicate (prev_bol, this_bol); 363 prev_bol = PT;
364 prev_bol_byte = PT_BYTE;
365
366 dup = message_log_check_duplicate (prev_bol, this_bol,
367 prev_bol_byte, this_bol_byte);
354 if (dup) 368 if (dup)
355 { 369 {
356 if (oldpoint > prev_bol) 370 del_range_both (prev_bol, prev_bol_byte,
357 oldpoint -= min (this_bol, oldpoint) - prev_bol; 371 this_bol, this_bol_byte, 0);
358 if (oldbegv > prev_bol)
359 oldbegv -= min (this_bol, oldbegv) - prev_bol;
360 if (oldzv > prev_bol)
361 oldzv -= min (this_bol, oldzv) - prev_bol;
362 del_range_1 (prev_bol, this_bol, 0);
363 if (dup > 1) 372 if (dup > 1)
364 { 373 {
365 char dupstr[40]; 374 char dupstr[40];
@@ -369,35 +378,42 @@ message_dolog (m, len, nlflag)
369 change message_log_check_duplicate. */ 378 change message_log_check_duplicate. */
370 sprintf (dupstr, " [%d times]", dup); 379 sprintf (dupstr, " [%d times]", dup);
371 duplen = strlen (dupstr); 380 duplen = strlen (dupstr);
372 TEMP_SET_PT (Z-1); 381 TEMP_SET_PT_BOTH (Z - 1, Z_BYTE - 1);
373 if (oldpoint == Z) 382 insert_1 (dupstr, duplen, 1, 0, 1);
374 oldpoint += duplen;
375 if (oldzv == Z)
376 oldzv += duplen;
377 insert_1 (dupstr, duplen, 1, 0);
378 } 383 }
379 } 384 }
380 } 385 }
381 386
382 if (NATNUMP (Vmessage_log_max)) 387 if (NATNUMP (Vmessage_log_max))
383 { 388 {
384 int pos = scan_buffer ('\n', Z, 0, 389 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE,
385 -XFASTINT (Vmessage_log_max) - 1, 0, 0); 390 -XFASTINT (Vmessage_log_max) - 1, 0);
386 oldpoint -= min (pos, oldpoint) - BEG; 391 del_range_both (BEG, BEG_BYTE, PT, PT_BYTE, 0);
387 oldbegv -= min (pos, oldbegv) - BEG;
388 oldzv -= min (pos, oldzv) - BEG;
389 del_range_1 (BEG, pos, 0);
390 } 392 }
391 } 393 }
392 BEGV = oldbegv; 394 BEGV = XMARKER (oldbegv)->charpos;
395 BEGV_BYTE = marker_byte_position (oldbegv);
396
393 if (zv_at_end) 397 if (zv_at_end)
394 ZV = Z; 398 {
399 ZV = Z;
400 ZV_BYTE = Z_BYTE;
401 }
395 else 402 else
396 ZV = oldzv; 403 {
404 ZV = XMARKER (oldzv)->charpos;
405 ZV_BYTE = marker_byte_position (oldzv);
406 }
407
397 if (point_at_end) 408 if (point_at_end)
398 TEMP_SET_PT (Z); 409 TEMP_SET_PT_BOTH (Z, Z_BYTE);
399 else 410 else
400 TEMP_SET_PT (oldpoint); 411 Fgoto_char (oldpoint);
412
413 free_marker (oldpoint);
414 free_marker (oldbegv);
415 free_marker (oldzv);
416
401 set_buffer_internal (oldbuf); 417 set_buffer_internal (oldbuf);
402 windows_or_buffers_changed = old_windows_or_buffers_changed; 418 windows_or_buffers_changed = old_windows_or_buffers_changed;
403 message_log_need_newline = !nlflag; 419 message_log_need_newline = !nlflag;
@@ -411,14 +427,15 @@ message_dolog (m, len, nlflag)
411 value N > 1 if we should also append " [N times]". */ 427 value N > 1 if we should also append " [N times]". */
412 428
413static int 429static int
414message_log_check_duplicate (prev_bol, this_bol) 430message_log_check_duplicate (prev_bol, prev_bol_byte, this_bol, this_bol_byte)
415 int prev_bol, this_bol; 431 int prev_bol, this_bol;
432 int prev_bol_byte, this_bol_byte;
416{ 433{
417 int i; 434 int i;
418 int len = Z - 1 - this_bol; 435 int len = Z - 1 - this_bol;
419 int seen_dots = 0; 436 int seen_dots = 0;
420 unsigned char *p1 = BUF_CHAR_ADDRESS (current_buffer, prev_bol); 437 unsigned char *p1 = BUF_BYTE_ADDRESS (current_buffer, prev_bol_byte);
421 unsigned char *p2 = BUF_CHAR_ADDRESS (current_buffer, this_bol); 438 unsigned char *p2 = BUF_BYTE_ADDRESS (current_buffer, this_bol_byte);
422 439
423 for (i = 0; i < len; i++) 440 for (i = 0; i < len; i++)
424 { 441 {
@@ -619,7 +636,8 @@ message (m, a1, a2, a3)
619 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3, a); 636 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3, a);
620#else 637#else
621 len = doprnt (FRAME_MESSAGE_BUF (f), 638 len = doprnt (FRAME_MESSAGE_BUF (f),
622 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3, &a1); 639 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3,
640 (char **) &a1);
623#endif /* NO_ARG_ARRAY */ 641#endif /* NO_ARG_ARRAY */
624 642
625 message2 (FRAME_MESSAGE_BUF (f), len); 643 message2 (FRAME_MESSAGE_BUF (f), len);
@@ -1070,9 +1088,10 @@ redisplay_internal (preserve_echo_area)
1070 && end_unchanged >= tlendpos 1088 && end_unchanged >= tlendpos
1071 && Z - GPT >= tlendpos))) 1089 && Z - GPT >= tlendpos)))
1072 { 1090 {
1073 if (tlbufpos > BEGV && FETCH_BYTE (tlbufpos - 1) != '\n' 1091 int tlbufpos_byte = CHAR_TO_BYTE (tlbufpos);
1092 if (tlbufpos > BEGV && FETCH_BYTE (tlbufpos_byte - 1) != '\n'
1074 && (tlbufpos == ZV 1093 && (tlbufpos == ZV
1075 || FETCH_BYTE (tlbufpos) == '\n')) 1094 || FETCH_BYTE (tlbufpos_byte) == '\n'))
1076 /* Former continuation line has disappeared by becoming empty */ 1095 /* Former continuation line has disappeared by becoming empty */
1077 goto cancel; 1096 goto cancel;
1078 else if (XFASTINT (w->last_modified) < MODIFF 1097 else if (XFASTINT (w->last_modified) < MODIFF
@@ -1095,9 +1114,11 @@ redisplay_internal (preserve_echo_area)
1095 1114
1096 struct position val; 1115 struct position val;
1097 int prevline; 1116 int prevline;
1117 int opoint = PT, opoint_byte = PT_BYTE;
1098 1118
1099 prevline = find_next_newline (tlbufpos, -1); 1119 scan_newline (tlbufpos, tlbufpos_byte, BEGV, BEGV_BYTE, -1, 1);
1100 val = *compute_motion (prevline, 0, 1120
1121 val = *compute_motion (PT, 0,
1101 XINT (w->hscroll) ? 1 - XINT (w->hscroll) : 0, 1122 XINT (w->hscroll) ? 1 - XINT (w->hscroll) : 0,
1102 0, 1123 0,
1103 tlbufpos, 1124 tlbufpos,
@@ -1105,14 +1126,16 @@ redisplay_internal (preserve_echo_area)
1105 1 << (BITS_PER_SHORT - 1), 1126 1 << (BITS_PER_SHORT - 1),
1106 window_internal_width (w) - 1, 1127 window_internal_width (w) - 1,
1107 XINT (w->hscroll), 0, w); 1128 XINT (w->hscroll), 0, w);
1129 SET_PT_BOTH (opoint, opoint_byte);
1108 if (val.hpos != this_line_start_hpos) 1130 if (val.hpos != this_line_start_hpos)
1109 goto cancel; 1131 goto cancel;
1110 1132
1111 cursor_vpos = -1; 1133 cursor_vpos = -1;
1112 overlay_arrow_seen = 0; 1134 overlay_arrow_seen = 0;
1113 zv_strings_seen = 0; 1135 zv_strings_seen = 0;
1114 display_text_line (w, tlbufpos, this_line_vpos, this_line_start_hpos, 1136 display_text_line (w, tlbufpos, tlbufpos_byte,
1115 pos_tab_offset (w, tlbufpos), 0); 1137 this_line_vpos, this_line_start_hpos,
1138 pos_tab_offset (w, tlbufpos, tlbufpos_byte), 0);
1116 /* If line contains point, is not continued, 1139 /* If line contains point, is not continued,
1117 and ends at same distance from eob as before, we win */ 1140 and ends at same distance from eob as before, we win */
1118 if (cursor_vpos >= 0 && this_line_bufpos 1141 if (cursor_vpos >= 0 && this_line_bufpos
@@ -1177,7 +1200,8 @@ redisplay_internal (preserve_echo_area)
1177 PT, 2, - (1 << (BITS_PER_SHORT - 1)), 1200 PT, 2, - (1 << (BITS_PER_SHORT - 1)),
1178 window_internal_width (w) - 1, 1201 window_internal_width (w) - 1,
1179 XINT (w->hscroll), 1202 XINT (w->hscroll),
1180 pos_tab_offset (w, tlbufpos), w); 1203 pos_tab_offset (w, tlbufpos, tlbufpos_byte),
1204 w);
1181 if (pos.vpos < 1) 1205 if (pos.vpos < 1)
1182 { 1206 {
1183 int width = window_internal_width (w) - 1; 1207 int width = window_internal_width (w) - 1;
@@ -1641,17 +1665,24 @@ redisplay_window (window, just_this_one, preserve_echo_area)
1641 register struct window *w = XWINDOW (window); 1665 register struct window *w = XWINDOW (window);
1642 FRAME_PTR f = XFRAME (WINDOW_FRAME (w)); 1666 FRAME_PTR f = XFRAME (WINDOW_FRAME (w));
1643 int height; 1667 int height;
1644 register int lpoint = PT; 1668 int lpoint = PT;
1669 int lpoint_byte = PT_BYTE;
1645 struct buffer *old = current_buffer; 1670 struct buffer *old = current_buffer;
1646 register int width = window_internal_width (w) - 1; 1671 register int width = window_internal_width (w) - 1;
1647 register int startp; 1672 register int startp, startp_byte;
1648 register int hscroll = XINT (w->hscroll); 1673 register int hscroll = XINT (w->hscroll);
1649 struct position pos; 1674 struct position pos;
1650 int opoint = PT; 1675 int opoint = PT;
1676 int opoint_byte = PT_BYTE;
1651 int tem; 1677 int tem;
1652 int update_mode_line; 1678 int update_mode_line;
1653 struct Lisp_Char_Table *dp = window_display_table (w); 1679 struct Lisp_Char_Table *dp = window_display_table (w);
1654 1680
1681 if (Z == Z_BYTE && lpoint != lpoint_byte)
1682 abort ();
1683 if (lpoint_byte < lpoint)
1684 abort ();
1685
1655 if (FRAME_HEIGHT (f) == 0) abort (); /* Some bug zeros some core */ 1686 if (FRAME_HEIGHT (f) == 0) abort (); /* Some bug zeros some core */
1656 1687
1657 /* If this is a combination window, do its children; that's all. */ 1688 /* If this is a combination window, do its children; that's all. */
@@ -1706,6 +1737,12 @@ redisplay_window (window, just_this_one, preserve_echo_area)
1706 set_buffer_temp (XBUFFER (w->buffer)); 1737 set_buffer_temp (XBUFFER (w->buffer));
1707 1738
1708 opoint = PT; 1739 opoint = PT;
1740 opoint_byte = PT_BYTE;
1741
1742 if (Z == Z_BYTE && opoint != opoint_byte)
1743 abort ();
1744 if (opoint_byte < opoint)
1745 abort ();
1709 1746
1710 /* If %c is in mode line, update it if needed. */ 1747 /* If %c is in mode line, update it if needed. */
1711 if (!NILP (w->column_number_displayed) 1748 if (!NILP (w->column_number_displayed)
@@ -1738,19 +1775,22 @@ redisplay_window (window, just_this_one, preserve_echo_area)
1738 1775
1739 if (!EQ (window, selected_window)) 1776 if (!EQ (window, selected_window))
1740 { 1777 {
1741 int new_pt = marker_position (w->pointm); 1778 int new_pt = XMARKER (w->pointm)->charpos;
1779 int new_pt_byte = marker_byte_position (w->pointm);
1742 if (new_pt < BEGV) 1780 if (new_pt < BEGV)
1743 { 1781 {
1744 new_pt = BEGV; 1782 new_pt = BEGV;
1745 Fset_marker (w->pointm, make_number (new_pt), Qnil); 1783 new_pt_byte = BEGV_BYTE;
1784 set_marker_both (w->pointm, Qnil, BEGV, BEGV_BYTE);
1746 } 1785 }
1747 else if (new_pt > (ZV - 1)) 1786 else if (new_pt > (ZV - 1))
1748 { 1787 {
1749 new_pt = ZV; 1788 new_pt = ZV;
1750 Fset_marker (w->pointm, make_number (new_pt), Qnil); 1789 new_pt_byte = ZV_BYTE;
1790 set_marker_both (w->pointm, Qnil, ZV, ZV_BYTE);
1751 } 1791 }
1752 /* We don't use SET_PT so that the point-motion hooks don't run. */ 1792 /* We don't use SET_PT so that the point-motion hooks don't run. */
1753 BUF_PT (current_buffer) = new_pt; 1793 TEMP_SET_PT_BOTH (new_pt, new_pt_byte);
1754 } 1794 }
1755 1795
1756 /* If any of the character widths specified in the display table 1796 /* If any of the character widths specified in the display table
@@ -1777,6 +1817,7 @@ redisplay_window (window, just_this_one, preserve_echo_area)
1777 goto recenter; 1817 goto recenter;
1778 1818
1779 startp = marker_position (w->start); 1819 startp = marker_position (w->start);
1820 startp_byte = marker_byte_position (w->start);
1780 1821
1781 /* If someone specified a new starting point but did not insist, 1822 /* If someone specified a new starting point but did not insist,
1782 check whether it can be used. */ 1823 check whether it can be used. */
@@ -1795,7 +1836,8 @@ redisplay_window (window, just_this_one, preserve_echo_area)
1795 /* BUG FIX: See the comment of 1836 /* BUG FIX: See the comment of
1796 Fpos_visible_in_window_p (window.c). */ 1837 Fpos_visible_in_window_p (window.c). */
1797 - (1 << (BITS_PER_SHORT - 1)), 1838 - (1 << (BITS_PER_SHORT - 1)),
1798 width, hscroll, pos_tab_offset (w, startp), w); 1839 width, hscroll,
1840 pos_tab_offset (w, startp, startp_byte), w);
1799 /* If PT does fit on the screen, we will use this start pos, 1841 /* If PT does fit on the screen, we will use this start pos,
1800 so do so by setting force_start. */ 1842 so do so by setting force_start. */
1801 if (pos.bufpos == PT) 1843 if (pos.bufpos == PT)
@@ -1834,8 +1876,8 @@ redisplay_window (window, just_this_one, preserve_echo_area)
1834 } 1876 }
1835 XSETFASTINT (w->last_modified, 0); 1877 XSETFASTINT (w->last_modified, 0);
1836 XSETFASTINT (w->last_overlay_modified, 0); 1878 XSETFASTINT (w->last_overlay_modified, 0);
1837 if (startp < BEGV) startp = BEGV; 1879 if (startp < BEGV) startp = BEGV, startp_byte = BEGV_BYTE;
1838 if (startp > ZV) startp = ZV; 1880 if (startp > ZV) startp = ZV, startp = ZV_BYTE;
1839 try_window (window, startp); 1881 try_window (window, startp);
1840 if (cursor_vpos < 0) 1882 if (cursor_vpos < 0)
1841 { 1883 {
@@ -1848,14 +1890,19 @@ redisplay_window (window, just_this_one, preserve_echo_area)
1848 0, 1890 0,
1849 ZV, height / 2, 1891 ZV, height / 2,
1850 - (1 << (BITS_PER_SHORT - 1)), 1892 - (1 << (BITS_PER_SHORT - 1)),
1851 width, hscroll, pos_tab_offset (w, startp), w); 1893 width, hscroll,
1852 BUF_PT (current_buffer) = pos.bufpos; 1894 pos_tab_offset (w, startp, startp_byte),
1895 w);
1896 TEMP_SET_PT_BOTH (pos.bufpos, pos.bytepos);
1853 if (w != XWINDOW (selected_window)) 1897 if (w != XWINDOW (selected_window))
1854 Fset_marker (w->pointm, make_number (PT), Qnil); 1898 set_marker_both (w->pointm, Qnil, PT, PT_BYTE);
1855 else 1899 else
1856 { 1900 {
1857 if (current_buffer == old) 1901 if (current_buffer == old)
1858 lpoint = PT; 1902 {
1903 lpoint = PT;
1904 lpoint_byte = PT_BYTE;
1905 }
1859 FRAME_CURSOR_X (f) = (WINDOW_LEFT_MARGIN (w) 1906 FRAME_CURSOR_X (f) = (WINDOW_LEFT_MARGIN (w)
1860 + minmax (0, pos.hpos, width)); 1907 + minmax (0, pos.hpos, width));
1861 FRAME_CURSOR_Y (f) = pos.vpos + XFASTINT (w->top); 1908 FRAME_CURSOR_Y (f) = pos.vpos + XFASTINT (w->top);
@@ -1929,7 +1976,8 @@ redisplay_window (window, just_this_one, preserve_echo_area)
1929 Fpos_visible_in_window_p (window.c). */ 1976 Fpos_visible_in_window_p (window.c). */
1930 - (1 << (BITS_PER_SHORT - 1)), 1977 - (1 << (BITS_PER_SHORT - 1)),
1931 width, hscroll, 1978 width, hscroll,
1932 pos_tab_offset (w, startp), w); 1979 pos_tab_offset (w, startp, startp_byte),
1980 w);
1933 } 1981 }
1934 else 1982 else
1935 { 1983 {
@@ -1939,7 +1987,8 @@ redisplay_window (window, just_this_one, preserve_echo_area)
1939 Fpos_visible_in_window_p (window.c). */ 1987 Fpos_visible_in_window_p (window.c). */
1940 - (1 << (BITS_PER_SHORT - 1)), 1988 - (1 << (BITS_PER_SHORT - 1)),
1941 width, hscroll, 1989 width, hscroll,
1942 pos_tab_offset (w, startp), w); 1990 pos_tab_offset (w, startp, startp_byte),
1991 w);
1943 } 1992 }
1944 1993
1945 /* Don't use a scroll margin that is negative or too large. */ 1994 /* Don't use a scroll margin that is negative or too large. */
@@ -1983,7 +2032,7 @@ redisplay_window (window, just_this_one, preserve_echo_area)
1983 but no longer is, find a new starting point. */ 2032 but no longer is, find a new starting point. */
1984 else if (!NILP (w->start_at_line_beg) 2033 else if (!NILP (w->start_at_line_beg)
1985 && !(startp <= BEGV 2034 && !(startp <= BEGV
1986 || FETCH_BYTE (startp - 1) == '\n')) 2035 || FETCH_BYTE (startp_byte - 1) == '\n'))
1987 { 2036 {
1988 goto recenter; 2037 goto recenter;
1989 } 2038 }
@@ -2088,7 +2137,8 @@ redisplay_window (window, just_this_one, preserve_echo_area)
2088 pos = *compute_motion (scroll_margin_pos, 0, 0, 0, 2137 pos = *compute_motion (scroll_margin_pos, 0, 0, 0,
2089 PT, XFASTINT (w->height), 0, 2138 PT, XFASTINT (w->height), 0,
2090 XFASTINT (w->width), XFASTINT (w->hscroll), 2139 XFASTINT (w->width), XFASTINT (w->hscroll),
2091 pos_tab_offset (w, startp), w); 2140 pos_tab_offset (w, startp, startp_byte),
2141 w);
2092 if (pos.vpos > scroll_conservatively) 2142 if (pos.vpos > scroll_conservatively)
2093 goto scroll_fail_1; 2143 goto scroll_fail_1;
2094 2144
@@ -2096,7 +2146,7 @@ redisplay_window (window, just_this_one, preserve_echo_area)
2096 2146
2097 if (! NILP (Vwindow_scroll_functions)) 2147 if (! NILP (Vwindow_scroll_functions))
2098 { 2148 {
2099 Fset_marker (w->start, make_number (pos.bufpos), Qnil); 2149 set_marker_both (w->start, Qnil, pos.bufpos, pos.bytepos);
2100 run_hook_with_args_2 (Qwindow_scroll_functions, window, 2150 run_hook_with_args_2 (Qwindow_scroll_functions, window,
2101 make_number (pos.bufpos)); 2151 make_number (pos.bufpos));
2102 pos.bufpos = marker_position (w->start); 2152 pos.bufpos = marker_position (w->start);
@@ -2126,7 +2176,8 @@ redisplay_window (window, just_this_one, preserve_echo_area)
2126 pos = *compute_motion (PT, 0, 0, 0, 2176 pos = *compute_motion (PT, 0, 0, 0,
2127 scroll_margin_pos, XFASTINT (w->height), 0, 2177 scroll_margin_pos, XFASTINT (w->height), 0,
2128 XFASTINT (w->width), XFASTINT (w->hscroll), 2178 XFASTINT (w->width), XFASTINT (w->hscroll),
2129 pos_tab_offset (w, startp), w); 2179 pos_tab_offset (w, startp, startp_byte),
2180 w);
2130 if (pos.vpos > scroll_conservatively) 2181 if (pos.vpos > scroll_conservatively)
2131 goto scroll_fail_1; 2182 goto scroll_fail_1;
2132 2183
@@ -2134,7 +2185,7 @@ redisplay_window (window, just_this_one, preserve_echo_area)
2134 2185
2135 if (! NILP (Vwindow_scroll_functions)) 2186 if (! NILP (Vwindow_scroll_functions))
2136 { 2187 {
2137 Fset_marker (w->start, make_number (pos.bufpos), Qnil); 2188 set_marker_both (w->start, Qnil, pos.bufpos, pos.bytepos);
2138 run_hook_with_args_2 (Qwindow_scroll_functions, window, 2189 run_hook_with_args_2 (Qwindow_scroll_functions, window,
2139 make_number (pos.bufpos)); 2190 make_number (pos.bufpos));
2140 pos.bufpos = marker_position (w->start); 2191 pos.bufpos = marker_position (w->start);
@@ -2170,7 +2221,7 @@ redisplay_window (window, just_this_one, preserve_echo_area)
2170 { 2221 {
2171 if (! NILP (Vwindow_scroll_functions)) 2222 if (! NILP (Vwindow_scroll_functions))
2172 { 2223 {
2173 Fset_marker (w->start, make_number (pos.bufpos), Qnil); 2224 set_marker_both (w->start, Qnil, pos.bufpos, pos.bytepos);
2174 run_hook_with_args_2 (Qwindow_scroll_functions, window, 2225 run_hook_with_args_2 (Qwindow_scroll_functions, window,
2175 make_number (pos.bufpos)); 2226 make_number (pos.bufpos));
2176 pos.bufpos = marker_position (w->start); 2227 pos.bufpos = marker_position (w->start);
@@ -2208,12 +2259,12 @@ recenter:
2208 && PT > BEGV + minibuffer_scroll_overlap 2259 && PT > BEGV + minibuffer_scroll_overlap
2209 /* If we scrolled to an actual line boundary, 2260 /* If we scrolled to an actual line boundary,
2210 that's different; don't ignore line boundaries. */ 2261 that's different; don't ignore line boundaries. */
2211 && FETCH_CHAR (pos.bufpos - 1) != '\n') 2262 && FETCH_BYTE (pos.bufpos - 1) != '\n')
2212 pos.bufpos = PT - minibuffer_scroll_overlap; 2263 pos.bufpos = PT - minibuffer_scroll_overlap;
2213 2264
2214 /* Set startp here explicitly in case that helps avoid an infinite loop 2265 /* Set startp here explicitly in case that helps avoid an infinite loop
2215 in case the window-scroll-functions functions get errors. */ 2266 in case the window-scroll-functions functions get errors. */
2216 Fset_marker (w->start, make_number (pos.bufpos), Qnil); 2267 set_marker_both (w->start, Qnil, pos.bufpos, pos.bytepos);
2217 if (! NILP (Vwindow_scroll_functions)) 2268 if (! NILP (Vwindow_scroll_functions))
2218 { 2269 {
2219 run_hook_with_args_2 (Qwindow_scroll_functions, window, 2270 run_hook_with_args_2 (Qwindow_scroll_functions, window,
@@ -2223,8 +2274,9 @@ recenter:
2223 try_window (window, pos.bufpos); 2274 try_window (window, pos.bufpos);
2224 2275
2225 startp = marker_position (w->start); 2276 startp = marker_position (w->start);
2277 startp_byte = marker_byte_position (w->start);
2226 w->start_at_line_beg 2278 w->start_at_line_beg
2227 = (startp == BEGV || FETCH_BYTE (startp - 1) == '\n') ? Qt : Qnil; 2279 = (startp == BEGV || FETCH_BYTE (startp_byte - 1) == '\n') ? Qt : Qnil;
2228 2280
2229done: 2281done:
2230 if ((update_mode_line 2282 if ((update_mode_line
@@ -2291,12 +2343,12 @@ done:
2291 (*redeem_scroll_bar_hook) (w); 2343 (*redeem_scroll_bar_hook) (w);
2292 } 2344 }
2293 2345
2294 BUF_PT (current_buffer) = opoint; 2346 TEMP_SET_PT_BOTH (opoint, opoint_byte);
2295 if (update_mode_line) 2347 if (update_mode_line)
2296 set_buffer_internal_1 (old); 2348 set_buffer_internal_1 (old);
2297 else 2349 else
2298 set_buffer_temp (old); 2350 set_buffer_temp (old);
2299 BUF_PT (current_buffer) = lpoint; 2351 TEMP_SET_PT_BOTH (lpoint, lpoint_byte);
2300} 2352}
2301 2353
2302/* Do full redisplay on one window, starting at position `pos'. */ 2354/* Do full redisplay on one window, starting at position `pos'. */
@@ -2319,17 +2371,21 @@ try_window (window, pos)
2319 || pos > XBUFFER (w->buffer)->zv) 2371 || pos > XBUFFER (w->buffer)->zv)
2320 abort (); 2372 abort ();
2321 2373
2322 Fset_marker (w->start, make_number (pos), Qnil); 2374 if (XMARKER (w->start)->charpos != pos)
2375 Fset_marker (w->start, make_number (pos), Qnil);
2376
2323 cursor_vpos = -1; 2377 cursor_vpos = -1;
2324 overlay_arrow_seen = 0; 2378 overlay_arrow_seen = 0;
2325 zv_strings_seen = 0; 2379 zv_strings_seen = 0;
2326 val.hpos = XINT (w->hscroll) ? 1 - XINT (w->hscroll) : 0; 2380 val.hpos = XINT (w->hscroll) ? 1 - XINT (w->hscroll) : 0;
2327 val.ovstring_chars_done = 0; 2381 val.ovstring_chars_done = 0;
2328 val.tab_offset = pos_tab_offset (w, pos); 2382 val.bytepos = marker_byte_position (w->start);
2383 val.tab_offset = pos_tab_offset (w, pos, val.bytepos);
2329 2384
2330 while (--height >= 0) 2385 while (--height >= 0)
2331 { 2386 {
2332 val = *display_text_line (w, pos, vpos, val.hpos, val.tab_offset, 2387 val = *display_text_line (w, pos, val.bytepos, vpos,
2388 val.hpos, val.tab_offset,
2333 val.ovstring_chars_done); 2389 val.ovstring_chars_done);
2334 /* The following code is omitted because we maintain tab_offset 2390 /* The following code is omitted because we maintain tab_offset
2335 in VAL. */ 2391 in VAL. */
@@ -2350,7 +2406,7 @@ try_window (window, pos)
2350 last_text_vpos 2406 last_text_vpos
2351 /* Next line, unless prev line ended in end of buffer with no cr */ 2407 /* Next line, unless prev line ended in end of buffer with no cr */
2352 = vpos - (val.vpos 2408 = vpos - (val.vpos
2353 && (FETCH_BYTE (val.bufpos - 1) != '\n' || invis)); 2409 && (FETCH_BYTE (val.bytepos - 1) != '\n' || invis));
2354 } 2410 }
2355 pos = val.bufpos; 2411 pos = val.bufpos;
2356 } 2412 }
@@ -2383,7 +2439,8 @@ static int
2383try_window_id (window) 2439try_window_id (window)
2384 Lisp_Object window; 2440 Lisp_Object window;
2385{ 2441{
2386 int pos; 2442 int pos, pos_byte;
2443 int opoint, opoint_byte;
2387 register struct window *w = XWINDOW (window); 2444 register struct window *w = XWINDOW (window);
2388 register int height = window_internal_height (w); 2445 register int height = window_internal_height (w);
2389 FRAME_PTR f = XFRAME (w->frame); 2446 FRAME_PTR f = XFRAME (w->frame);
@@ -2406,6 +2463,8 @@ try_window_id (window)
2406 int delta; 2463 int delta;
2407 int epto, old_tick; 2464 int epto, old_tick;
2408 2465
2466 int start_byte = marker_byte_position (w->start);
2467
2409 if (GPT - BEG < beg_unchanged) 2468 if (GPT - BEG < beg_unchanged)
2410 beg_unchanged = GPT - BEG; 2469 beg_unchanged = GPT - BEG;
2411 if (Z - GPT < end_unchanged) 2470 if (Z - GPT < end_unchanged)
@@ -2418,9 +2477,11 @@ try_window_id (window)
2418 bp = *compute_motion (start, 0, lmargin, 0, 2477 bp = *compute_motion (start, 0, lmargin, 0,
2419 min (ZV, beg_unchanged + BEG), height, 2478 min (ZV, beg_unchanged + BEG), height,
2420 /* BUG FIX: See the comment of 2479 /* BUG FIX: See the comment of
2421 Fpos_visible_in_window_p() (window.c). */ 2480 Fpos_visible_in_window_p (window.c). */
2422 - (1 << (BITS_PER_SHORT - 1)), 2481 - (1 << (BITS_PER_SHORT - 1)),
2423 width, hscroll, pos_tab_offset (w, start), w); 2482 width, hscroll,
2483 pos_tab_offset (w, start, start_byte),
2484 w);
2424 if (bp.vpos >= height) 2485 if (bp.vpos >= height)
2425 { 2486 {
2426 if (PT < bp.bufpos) 2487 if (PT < bp.bufpos)
@@ -2434,7 +2495,8 @@ try_window_id (window)
2434 /* BUG FIX: See the comment of 2495 /* BUG FIX: See the comment of
2435 Fpos_visible_in_window_p() (window.c). */ 2496 Fpos_visible_in_window_p() (window.c). */
2436 - (1 << (BITS_PER_SHORT - 1)), 2497 - (1 << (BITS_PER_SHORT - 1)),
2437 width, hscroll, pos_tab_offset (w, start), w); 2498 width, hscroll,
2499 pos_tab_offset (w, start, start_byte), w);
2438 XSETFASTINT (w->window_end_vpos, height); 2500 XSETFASTINT (w->window_end_vpos, height);
2439 XSETFASTINT (w->window_end_pos, Z - bp.bufpos); 2501 XSETFASTINT (w->window_end_pos, Z - bp.bufpos);
2440 goto findpoint; 2502 goto findpoint;
@@ -2448,6 +2510,7 @@ try_window_id (window)
2448 bp = *vmotion (bp.bufpos, 0, w); 2510 bp = *vmotion (bp.bufpos, 0, w);
2449 2511
2450 pos = bp.bufpos; 2512 pos = bp.bufpos;
2513 pos_byte = bp.bytepos;
2451 val.hpos = lmargin; 2514 val.hpos = lmargin;
2452 if (pos < start) 2515 if (pos < start)
2453 return -1; 2516 return -1;
@@ -2464,6 +2527,7 @@ try_window_id (window)
2464 bp = *vmotion (bp.bufpos, -1, w); 2527 bp = *vmotion (bp.bufpos, -1, w);
2465 --vpos; 2528 --vpos;
2466 pos = bp.bufpos; 2529 pos = bp.bufpos;
2530 pos_byte = bp.bytepos;
2467 } 2531 }
2468 val.tab_offset = bp.tab_offset; /* Update tab offset. */ 2532 val.tab_offset = bp.tab_offset; /* Update tab offset. */
2469 2533
@@ -2472,16 +2536,21 @@ try_window_id (window)
2472 val.hpos = bp.prevhpos - width + lmargin; 2536 val.hpos = bp.prevhpos - width + lmargin;
2473 val.tab_offset = bp.tab_offset + bp.prevhpos - width; 2537 val.tab_offset = bp.tab_offset + bp.prevhpos - width;
2474 did_motion = 1; 2538 did_motion = 1;
2475 DEC_POS (pos); 2539 pos--;
2540 DEC_POS (pos_byte);
2476 } 2541 }
2477 2542
2478 bp.vpos = vpos; 2543 bp.vpos = vpos;
2479 2544
2480 /* Find first visible newline after which no more is changed. */ 2545 /* Find first visible newline after which no more is changed. */
2481 tem = find_next_newline (Z - max (end_unchanged, Z - ZV), 1); 2546 opoint = PT, opoint_byte = PT_BYTE;
2547 SET_PT (Z - max (end_unchanged, Z - ZV));
2548 scan_newline (PT, PT_BYTE, ZV, ZV_BYTE, 1, 1);
2482 if (selective > 0) 2549 if (selective > 0)
2483 while (tem < ZV - 1 && (indented_beyond_p (tem, selective))) 2550 while (PT < ZV - 1 && indented_beyond_p (PT, PT_BYTE, selective))
2484 tem = find_next_newline (tem, 1); 2551 scan_newline (PT, PT_BYTE, ZV, ZV_BYTE, 1, 1);
2552 tem = PT;
2553 SET_PT_BOTH (opoint, opoint_byte);
2485 2554
2486 /* Compute the cursor position after that newline. */ 2555 /* Compute the cursor position after that newline. */
2487 ep = *compute_motion (pos, vpos, val.hpos, did_motion, tem, 2556 ep = *compute_motion (pos, vpos, val.hpos, did_motion, tem,
@@ -2658,12 +2727,14 @@ try_window_id (window)
2658 if (vpos == 0 && pos < marker_position (w->start)) 2727 if (vpos == 0 && pos < marker_position (w->start))
2659 Fset_marker (w->start, make_number (pos), Qnil); 2728 Fset_marker (w->start, make_number (pos), Qnil);
2660 2729
2730 val.bytepos = pos_byte;
2731
2661 /* Redisplay the lines where the text was changed */ 2732 /* Redisplay the lines where the text was changed */
2662 last_text_vpos = vpos; 2733 last_text_vpos = vpos;
2663 /* The following code is omitted because we maintain tab offset in 2734 /* The following code is omitted because we maintain tab offset in
2664 val.tab_offset. */ 2735 val.tab_offset. */
2665#if 0 2736#if 0
2666 tab_offset = pos_tab_offset (w, pos); 2737 tab_offset = pos_tab_offset (w, pos, pos_byte);
2667 /* If we are starting display in mid-character, correct tab_offset 2738 /* If we are starting display in mid-character, correct tab_offset
2668 to account for passing the line that that character really starts in. */ 2739 to account for passing the line that that character really starts in. */
2669 if (val.hpos < lmargin) 2740 if (val.hpos < lmargin)
@@ -2672,7 +2743,8 @@ try_window_id (window)
2672 old_tick = MODIFF; 2743 old_tick = MODIFF;
2673 while (vpos < stop_vpos) 2744 while (vpos < stop_vpos)
2674 { 2745 {
2675 val = *display_text_line (w, pos, top + vpos++, val.hpos, val.tab_offset, 2746 val = *display_text_line (w, pos, val.bytepos, top + vpos++,
2747 val.hpos, val.tab_offset,
2676 val.ovstring_chars_done); 2748 val.ovstring_chars_done);
2677 /* If display_text_line ran a hook and changed some text, 2749 /* If display_text_line ran a hook and changed some text,
2678 redisplay all the way to bottom of buffer 2750 redisplay all the way to bottom of buffer
@@ -2715,6 +2787,7 @@ try_window_id (window)
2715 FRAME_SCROLL_BOTTOM_VPOS (f) = xp.vpos; 2787 FRAME_SCROLL_BOTTOM_VPOS (f) = xp.vpos;
2716 vpos = xp.vpos; 2788 vpos = xp.vpos;
2717 pos = xp.bufpos; 2789 pos = xp.bufpos;
2790 pos_byte = xp.bytepos;
2718 val.hpos = xp.hpos; 2791 val.hpos = xp.hpos;
2719 val.tab_offset = xp.tab_offset; 2792 val.tab_offset = xp.tab_offset;
2720 if (pos == ZV) 2793 if (pos == ZV)
@@ -2727,22 +2800,25 @@ try_window_id (window)
2727 { 2800 {
2728 val.hpos = xp.prevhpos - width + lmargin; 2801 val.hpos = xp.prevhpos - width + lmargin;
2729 val.tab_offset = xp.tab_offset + bp.prevhpos - width; 2802 val.tab_offset = xp.tab_offset + bp.prevhpos - width;
2730 DEC_POS (pos); 2803 pos--;
2804 DEC_POS (pos_byte);
2731 } 2805 }
2732 2806
2733 blank_end_of_window = 1; 2807 blank_end_of_window = 1;
2734 /* The following code is omitted because we maintain tab offset 2808 /* The following code is omitted because we maintain tab offset
2735 in val.tab_offset. */ 2809 in val.tab_offset. */
2736#if 0 2810#if 0
2737 tab_offset = pos_tab_offset (w, pos); 2811 tab_offset = pos_tab_offset (w, pos, pos_byte);
2738 /* If we are starting display in mid-character, correct tab_offset 2812 /* If we are starting display in mid-character, correct tab_offset
2739 to account for passing the line that that character starts in. */ 2813 to account for passing the line that that character starts in. */
2740 if (val.hpos < lmargin) 2814 if (val.hpos < lmargin)
2741 tab_offset += width; 2815 tab_offset += width;
2742#endif 2816#endif
2817 val.bytepos = pos;
2743 while (vpos < height) 2818 while (vpos < height)
2744 { 2819 {
2745 val = *display_text_line (w, pos, top + vpos++, val.hpos, 2820 val = *display_text_line (w, pos, val.bytepos,
2821 top + vpos++, val.hpos,
2746 val.tab_offset, val.ovstring_chars_done); 2822 val.tab_offset, val.ovstring_chars_done);
2747 /* The following code is omitted because we maintain tab 2823 /* The following code is omitted because we maintain tab
2748 offset in val.tab_offset. */ 2824 offset in val.tab_offset. */
@@ -2791,7 +2867,9 @@ try_window_id (window)
2791 1 << (BITS_PER_SHORT - 1), 2867 1 << (BITS_PER_SHORT - 1),
2792 /* ... nor HPOS. */ 2868 /* ... nor HPOS. */
2793 1 << (BITS_PER_SHORT - 1), 2869 1 << (BITS_PER_SHORT - 1),
2794 width, hscroll, pos_tab_offset (w, start), w); 2870 width, hscroll,
2871 pos_tab_offset (w, start, start_byte),
2872 w);
2795 /* Admit failure if point is off frame now */ 2873 /* Admit failure if point is off frame now */
2796 if (val.vpos >= height) 2874 if (val.vpos >= height)
2797 { 2875 {
@@ -2810,7 +2888,9 @@ try_window_id (window)
2810 { 2888 {
2811 val = *compute_motion (start, 0, lmargin, 0, ZV, 2889 val = *compute_motion (start, 0, lmargin, 0, ZV,
2812 height, - (1 << (BITS_PER_SHORT - 1)), 2890 height, - (1 << (BITS_PER_SHORT - 1)),
2813 width, hscroll, pos_tab_offset (w, start), w); 2891 width, hscroll,
2892 pos_tab_offset (w, start, start_byte),
2893 w);
2814 if (val.vpos != XFASTINT (w->window_end_vpos)) 2894 if (val.vpos != XFASTINT (w->window_end_vpos))
2815 abort (); 2895 abort ();
2816 if (XFASTINT (w->window_end_pos) 2896 if (XFASTINT (w->window_end_pos)
@@ -2902,7 +2982,36 @@ fix_glyph (f, glyph, cface)
2902 return glyph; 2982 return glyph;
2903} 2983}
2904 2984
2905/* Display one line of window W, starting at position START in W's buffer. 2985/* Return the column of position POS / POS_BYTE in window W's buffer.
2986 The result is rounded down to a multiple of the internal width of W.
2987 This is the amount of indentation of position POS
2988 that is not visible in its horizontal position in the window. */
2989
2990static int
2991pos_tab_offset (w, pos, pos_byte)
2992 struct window *w;
2993 register int pos, pos_byte;
2994{
2995 int opoint = PT;
2996 int opoint_byte = PT_BYTE;
2997 int col;
2998 int width = window_internal_width (w) - 1;
2999
3000 if (pos == BEGV)
3001 return MINI_WINDOW_P (w) ? -minibuf_prompt_width : 0;
3002
3003 if (FETCH_BYTE (pos_byte - 1) == '\n')
3004 return 0;
3005
3006 TEMP_SET_PT_BOTH (pos, pos_byte);
3007 col = current_column ();
3008 TEMP_SET_PT_BOTH (opoint, opoint_byte);
3009
3010 return col;
3011}
3012
3013/* Display one line of window W, starting at char position START in W's buffer.
3014 START_BYTE is the corresponding byte position.
2906 3015
2907 Display starting at horizontal position HPOS, expressed relative to 3016 Display starting at horizontal position HPOS, expressed relative to
2908 W's left edge. In situations where the text at START shouldn't 3017 W's left edge. In situations where the text at START shouldn't
@@ -2927,7 +3036,7 @@ fix_glyph (f, glyph, cface)
2927struct position val_display_text_line; 3036struct position val_display_text_line;
2928 3037
2929static struct position * 3038static struct position *
2930display_text_line (w, start, vpos, hpos, taboffset, ovstr_done) 3039display_text_line (w, start, start_byte, vpos, hpos, taboffset, ovstr_done)
2931 struct window *w; 3040 struct window *w;
2932 int start; 3041 int start;
2933 int vpos; 3042 int vpos;
@@ -2936,22 +3045,23 @@ display_text_line (w, start, vpos, hpos, taboffset, ovstr_done)
2936 int ovstr_done; 3045 int ovstr_done;
2937{ 3046{
2938 register int pos = start; 3047 register int pos = start;
3048 int pos_byte = start_byte;
2939 register int c; 3049 register int c;
2940 register GLYPH *p1; 3050 register GLYPH *p1;
2941 register int pause; 3051 int pause, limit_byte;
2942 register unsigned char *p; 3052 register unsigned char *p;
2943 GLYPH *endp; 3053 GLYPH *endp;
2944 register GLYPH *leftmargin; 3054 register GLYPH *leftmargin;
2945 register GLYPH *p1prev; 3055 register GLYPH *p1prev;
2946 register GLYPH *p1start; 3056 register GLYPH *p1start;
2947 int prevpos; 3057 int prevpos, prevpos_byte;
2948 int *charstart; 3058 int *charstart;
2949 FRAME_PTR f = XFRAME (w->frame); 3059 FRAME_PTR f = XFRAME (w->frame);
2950 int tab_width = XINT (current_buffer->tab_width); 3060 int tab_width = XINT (current_buffer->tab_width);
2951 int ctl_arrow = !NILP (current_buffer->ctl_arrow); 3061 int ctl_arrow = !NILP (current_buffer->ctl_arrow);
2952 int width = window_internal_width (w) - 1; 3062 int width = window_internal_width (w) - 1;
2953 struct position val; 3063 struct position val;
2954 int lastpos; 3064 int lastpos, lastpos_byte;
2955 int invis; 3065 int invis;
2956 int last_invis_skip = 0; 3066 int last_invis_skip = 0;
2957 Lisp_Object last_invis_prop; 3067 Lisp_Object last_invis_prop;
@@ -3101,11 +3211,13 @@ display_text_line (w, start, vpos, hpos, taboffset, ovstr_done)
3101 /* Since this should not be a valid multibyte character, we 3211 /* Since this should not be a valid multibyte character, we
3102 can decrease POS by 1. */ 3212 can decrease POS by 1. */
3103 pos--; 3213 pos--;
3214 pos_byte = left_edge->bytepos - 1;
3104 hpos = left_edge->prevhpos; 3215 hpos = left_edge->prevhpos;
3105 } 3216 }
3106 else 3217 else
3107 { 3218 {
3108 pos = left_edge->bufpos; 3219 pos = left_edge->bufpos;
3220 pos_byte = left_edge->bytepos;
3109 hpos = left_edge->hpos; 3221 hpos = left_edge->hpos;
3110 } 3222 }
3111 } 3223 }
@@ -3133,10 +3245,12 @@ display_text_line (w, start, vpos, hpos, taboffset, ovstr_done)
3133 if reach or pass continuation column, 3245 if reach or pass continuation column,
3134 or at face change. */ 3246 or at face change. */
3135 pause = pos; 3247 pause = pos;
3248 limit_byte = pos_byte;
3136 next_face_change = pos; 3249 next_face_change = pos;
3137 next_boundary = pos; 3250 next_boundary = pos;
3138 p1prev = p1; 3251 p1prev = p1;
3139 prevpos = pos; 3252 prevpos = pos;
3253 prevpos_byte = pos_byte;
3140 3254
3141 /* If the window is hscrolled and point is in the invisible part of the 3255 /* If the window is hscrolled and point is in the invisible part of the
3142 current line beyond the left margin we can record the cursor location 3256 current line beyond the left margin we can record the cursor location
@@ -3225,8 +3339,6 @@ display_text_line (w, start, vpos, hpos, taboffset, ovstr_done)
3225 if (XFASTINT (limit) > pos + 50) 3339 if (XFASTINT (limit) > pos + 50)
3226 { 3340 {
3227 int limitpos = pos + 50; 3341 int limitpos = pos + 50;
3228 if (limitpos < Z)
3229 INC_POS (limitpos); /* Adjust to character boundary. */
3230 XSETFASTINT (limit, limitpos); 3342 XSETFASTINT (limit, limitpos);
3231 } 3343 }
3232 limit = Fnext_single_property_change (position, Qinvisible, 3344 limit = Fnext_single_property_change (position, Qinvisible,
@@ -3312,8 +3424,6 @@ display_text_line (w, start, vpos, hpos, taboffset, ovstr_done)
3312 { 3424 {
3313 int limit = pos + 50; 3425 int limit = pos + 50;
3314 3426
3315 if (limit < Z && !CHAR_HEAD_P (POS_ADDR (limit)))
3316 INC_POS (limit); /* Adjust to character boundary. */
3317 current_face = compute_char_face (f, w, pos, 3427 current_face = compute_char_face (f, w, pos,
3318 region_beg, region_end, 3428 region_beg, region_end,
3319 &next_face_change, limit, 0); 3429 &next_face_change, limit, 0);
@@ -3340,7 +3450,17 @@ display_text_line (w, start, vpos, hpos, taboffset, ovstr_done)
3340 if (pos < GPT && GPT < pause) 3450 if (pos < GPT && GPT < pause)
3341 pause = GPT; 3451 pause = GPT;
3342 3452
3343 p = POS_ADDR (pos); 3453 /* LIMIT_BYTE is not the same place in the buffer as PAUSE.
3454 It is a limit on valid characters.
3455 We use it to bound STRING_CHAR_AND_LENGTH. */
3456 limit_byte = ZV_BYTE;
3457 if (pos < GPT && GPT_BYTE < limit_byte)
3458 limit_byte = GPT_BYTE;
3459
3460 {
3461 int temp = CHAR_TO_BYTE (pos);
3462 p = BYTE_POS_ADDR (temp);
3463 }
3344 } 3464 }
3345 3465
3346 if (p1 >= endp) 3466 if (p1 >= endp)
@@ -3349,8 +3469,7 @@ display_text_line (w, start, vpos, hpos, taboffset, ovstr_done)
3349 p1prev = p1; 3469 p1prev = p1;
3350 3470
3351 if (multibyte) 3471 if (multibyte)
3352 /* PAUSE is surely at character boundary. */ 3472 c = STRING_CHAR_AND_LENGTH (p, limit_byte - pos_byte, len), p += len;
3353 c = STRING_CHAR_AND_LENGTH (p, pause - pos, len), p += len;
3354 else 3473 else
3355 c = *p++, len = 1; 3474 c = *p++, len = 1;
3356 /* Let a display table override all standard display methods. */ 3475 /* Let a display table override all standard display methods. */
@@ -3381,12 +3500,22 @@ display_text_line (w, start, vpos, hpos, taboffset, ovstr_done)
3381 invis = 1; 3500 invis = 1;
3382 while (pos + 1 < ZV 3501 while (pos + 1 < ZV
3383 && selective > 0 3502 && selective > 0
3384 && indented_beyond_p (pos + 1, selective)) 3503 && indented_beyond_p (pos + 1, pos_byte + 1, selective))
3385 { 3504 {
3505 int opoint = PT, opoint_byte = PT_BYTE;
3506
3386 invis = 1; 3507 invis = 1;
3387 pos = find_next_newline (pos + 1, 1); 3508 if (! NILP (current_buffer->enable_multibyte_characters))
3388 if (FETCH_BYTE (pos - 1) == '\n') 3509 INC_BOTH (pos, pos_byte);
3389 pos--; 3510 else
3511 pos++, pos_byte++;
3512 scan_newline (pos, pos_byte, ZV, ZV_BYTE, 1, 1);
3513 if (FETCH_BYTE (pos_byte - 1) == '\n')
3514 {
3515 pos--;
3516 pos_byte--;
3517 }
3518 SET_PT_BOTH (opoint, opoint_byte);
3390 } 3519 }
3391 if (invis && selective_rlen > 0 && p1 >= leftmargin) 3520 if (invis && selective_rlen > 0 && p1 >= leftmargin)
3392 { 3521 {
@@ -3459,9 +3588,13 @@ display_text_line (w, start, vpos, hpos, taboffset, ovstr_done)
3459 } 3588 }
3460 else if (c == Ctl ('M') && selective == -1) 3589 else if (c == Ctl ('M') && selective == -1)
3461 { 3590 {
3462 pos = find_next_newline (pos, 1); 3591 int opoint = PT, opoint_byte = PT_BYTE;
3463 if (FETCH_BYTE (pos - 1) == '\n') 3592 scan_newline (pos, pos_byte, ZV, ZV_BYTE, 1, 1);
3464 pos--; 3593 pos = PT, pos_byte = PT_BYTE;
3594 SET_PT_BOTH (opoint, opoint_byte);
3595
3596 if (FETCH_BYTE (pos_byte - 1) == '\n')
3597 pos--, pos_byte--;
3465 if (selective_rlen > 0) 3598 if (selective_rlen > 0)
3466 { 3599 {
3467 p1 += selective_rlen; 3600 p1 += selective_rlen;
@@ -3555,7 +3688,9 @@ display_text_line (w, start, vpos, hpos, taboffset, ovstr_done)
3555 } 3688 }
3556 3689
3557 prevpos = pos; 3690 prevpos = pos;
3558 pos += len; 3691 prevpos_byte = pos_byte;
3692 pos++;
3693 pos_byte += len;
3559 3694
3560 /* Update charstarts for the character just output. */ 3695 /* Update charstarts for the character just output. */
3561 3696
@@ -3587,6 +3722,7 @@ display_text_line (w, start, vpos, hpos, taboffset, ovstr_done)
3587 val.vpos = 1; 3722 val.vpos = 1;
3588 3723
3589 lastpos = pos; 3724 lastpos = pos;
3725 lastpos_byte = pos_byte;
3590 3726
3591 /* Store 0 in this charstart line for the positions where 3727 /* Store 0 in this charstart line for the positions where
3592 there is no character. But do leave what was recorded 3728 there is no character. But do leave what was recorded
@@ -3612,6 +3748,7 @@ display_text_line (w, start, vpos, hpos, taboffset, ovstr_done)
3612 character code is C and the length of multi-byte form is 3748 character code is C and the length of multi-byte form is
3613 LEN. */ 3749 LEN. */
3614 pos = prevpos; 3750 pos = prevpos;
3751 pos_byte = prevpos_byte;
3615 3752
3616 if (len == 1) 3753 if (len == 1)
3617 /* C is not a multi-byte character. We can break it and 3754 /* C is not a multi-byte character. We can break it and
@@ -3636,6 +3773,7 @@ display_text_line (w, start, vpos, hpos, taboffset, ovstr_done)
3636 } 3773 }
3637 /* If POINT is at POS, cursor should not on this line. */ 3774 /* If POINT is at POS, cursor should not on this line. */
3638 lastpos = pos; 3775 lastpos = pos;
3776 lastpos_byte = pos_byte;
3639 if (PT == pos) 3777 if (PT == pos)
3640 cursor_vpos = -1; 3778 cursor_vpos = -1;
3641 } 3779 }
@@ -3652,33 +3790,45 @@ display_text_line (w, start, vpos, hpos, taboffset, ovstr_done)
3652 3790
3653 if (pos < ZV) 3791 if (pos < ZV)
3654 { 3792 {
3655 if (FETCH_BYTE (pos) == '\n') 3793 if (FETCH_BYTE (pos_byte) == '\n')
3656 { 3794 {
3795 int opoint = PT, opoint_byte = PT_BYTE;
3796
3657 /* If stopped due to a newline, start next line after it */ 3797 /* If stopped due to a newline, start next line after it */
3658 pos++; 3798 SET_PT_BOTH (pos + 1, pos_byte + 1);
3799
3659 val.tab_offset = 0; 3800 val.tab_offset = 0;
3660 /* Check again for hidden lines, in case the newline occurred exactly 3801 /* Check again for hidden lines, in case the newline occurred exactly
3661 at the right margin. */ 3802 at the right margin. */
3662 while (pos < ZV && selective > 0 3803 while (PT < ZV && selective > 0
3663 && indented_beyond_p (pos, selective)) 3804 && indented_beyond_p (PT, PT_BYTE, selective))
3664 pos = find_next_newline (pos, 1); 3805 scan_newline (PT, PT_BYTE, ZV, ZV_BYTE, 1, 1);
3806
3807 pos = PT, pos_byte = PT_BYTE;
3808 SET_PT_BOTH (opoint, opoint_byte);
3665 } 3809 }
3666 else 3810 else
3667 /* Stopped due to right margin of window */ 3811 /* Stopped due to right margin of window */
3668 { 3812 {
3669 if (truncate) 3813 if (truncate)
3670 { 3814 {
3815 int opoint = PT, opoint_byte = PT_BYTE;
3816
3817 SET_PT_BOTH (pos, pos_byte);
3671 *p1++ = fix_glyph (f, truncator, 0); 3818 *p1++ = fix_glyph (f, truncator, 0);
3672 /* Truncating => start next line after next newline, 3819 /* Truncating => start next line after next newline,
3673 and point is on this line if it is before the newline, 3820 and point is on this line if it is before the newline,
3674 and skip none of first char of next line */ 3821 and skip none of first char of next line */
3675 do 3822 do
3676 pos = find_next_newline (pos, 1); 3823 scan_newline (PT, PT_BYTE, ZV, ZV_BYTE, 1, 1);
3677 while (pos < ZV && selective > 0 3824 while (PT < ZV && selective > 0
3678 && indented_beyond_p (pos, selective)); 3825 && indented_beyond_p (PT, PT_BYTE, selective));
3826 pos = PT, pos_byte = PT_BYTE;
3679 val.hpos = XINT (w->hscroll) ? 1 - XINT (w->hscroll) : 0; 3827 val.hpos = XINT (w->hscroll) ? 1 - XINT (w->hscroll) : 0;
3828 SET_PT_BOTH (opoint, opoint_byte);
3680 3829
3681 lastpos = pos - (FETCH_BYTE (pos - 1) == '\n'); 3830 lastpos = pos - (FETCH_BYTE (pos_byte - 1) == '\n');
3831 lastpos_byte = CHAR_TO_BYTE (lastpos);
3682 val.tab_offset = 0; 3832 val.tab_offset = 0;
3683 } 3833 }
3684 else 3834 else
@@ -3686,6 +3836,7 @@ display_text_line (w, start, vpos, hpos, taboffset, ovstr_done)
3686 *p1++ = fix_glyph (f, continuer, 0); 3836 *p1++ = fix_glyph (f, continuer, 0);
3687 val.vpos = 0; 3837 val.vpos = 0;
3688 lastpos--; 3838 lastpos--;
3839 DEC_POS (lastpos_byte);
3689 val.tab_offset = taboffset + width; 3840 val.tab_offset = taboffset + width;
3690 } 3841 }
3691 } 3842 }
@@ -3824,6 +3975,7 @@ display_text_line (w, start, vpos, hpos, taboffset, ovstr_done)
3824 } 3975 }
3825 3976
3826 val.bufpos = pos; 3977 val.bufpos = pos;
3978 val.bytepos = pos_byte;
3827 val.ovstring_chars_done = ovstr_done; 3979 val.ovstring_chars_done = ovstr_done;
3828 val_display_text_line = val; 3980 val_display_text_line = val;
3829 return &val_display_text_line; 3981 return &val_display_text_line;
@@ -4413,8 +4565,9 @@ decode_mode_spec (w, c, spec_width, maxwidth)
4413 4565
4414 case 'l': 4566 case 'l':
4415 { 4567 {
4416 int startpos = marker_position (w->start); 4568 int startpos = XMARKER (w->start)->charpos;
4417 int line, linepos, topline; 4569 int startpos_byte = marker_byte_position (w->start);
4570 int line, linepos, linepos_byte, topline;
4418 int nlines, junk; 4571 int nlines, junk;
4419 Lisp_Object tem; 4572 Lisp_Object tem;
4420 int height = XFASTINT (w->height); 4573 int height = XFASTINT (w->height);
@@ -4437,19 +4590,23 @@ decode_mode_spec (w, c, spec_width, maxwidth)
4437 4590
4438 if (!NILP (w->base_line_number) 4591 if (!NILP (w->base_line_number)
4439 && !NILP (w->base_line_pos) 4592 && !NILP (w->base_line_pos)
4440 && XFASTINT (w->base_line_pos) <= marker_position (w->start)) 4593 && XFASTINT (w->base_line_pos) <= startpos)
4441 { 4594 {
4442 line = XFASTINT (w->base_line_number); 4595 line = XFASTINT (w->base_line_number);
4443 linepos = XFASTINT (w->base_line_pos); 4596 linepos = XFASTINT (w->base_line_pos);
4597 linepos_byte = buf_charpos_to_bytepos (b, linepos);
4444 } 4598 }
4445 else 4599 else
4446 { 4600 {
4447 line = 1; 4601 line = 1;
4448 linepos = BUF_BEGV (b); 4602 linepos = BUF_BEGV (b);
4603 linepos_byte = BUF_BEGV_BYTE (b);
4449 } 4604 }
4450 4605
4451 /* Count lines from base line to window start position. */ 4606 /* Count lines from base line to window start position. */
4452 nlines = display_count_lines (linepos, startpos, startpos, &junk); 4607 nlines = display_count_lines (linepos, linepos_byte,
4608 startpos_byte,
4609 startpos, &junk);
4453 4610
4454 topline = nlines + line; 4611 topline = nlines + line;
4455 4612
@@ -4466,19 +4623,24 @@ decode_mode_spec (w, c, spec_width, maxwidth)
4466 || linepos == BUF_BEGV (b)) 4623 || linepos == BUF_BEGV (b))
4467 { 4624 {
4468 int limit = BUF_BEGV (b); 4625 int limit = BUF_BEGV (b);
4626 int limit_byte = BUF_BEGV_BYTE (b);
4469 int position; 4627 int position;
4470 int distance = (height * 2 + 30) * 200; 4628 int distance = (height * 2 + 30) * 200;
4471 4629
4472 if (startpos - distance > limit) 4630 if (startpos - distance > limit)
4473 limit = startpos - distance; 4631 {
4632 limit = startpos - distance;
4633 limit_byte = CHAR_TO_BYTE (limit);
4634 }
4474 4635
4475 nlines = display_count_lines (startpos, limit, 4636 nlines = display_count_lines (startpos, startpos_byte,
4476 -(height * 2 + 30), 4637 limit_byte,
4638 - (height * 2 + 30),
4477 &position); 4639 &position);
4478 /* If we couldn't find the lines we wanted within 4640 /* If we couldn't find the lines we wanted within
4479 200 chars per line, 4641 200 chars per line,
4480 give up on line numbers for this window. */ 4642 give up on line numbers for this window. */
4481 if (position == startpos - distance) 4643 if (position == limit_byte && limit == startpos - distance)
4482 { 4644 {
4483 w->base_line_pos = w->buffer; 4645 w->base_line_pos = w->buffer;
4484 w->base_line_number = Qnil; 4646 w->base_line_number = Qnil;
@@ -4486,11 +4648,12 @@ decode_mode_spec (w, c, spec_width, maxwidth)
4486 } 4648 }
4487 4649
4488 XSETFASTINT (w->base_line_number, topline - nlines); 4650 XSETFASTINT (w->base_line_number, topline - nlines);
4489 XSETFASTINT (w->base_line_pos, position); 4651 XSETFASTINT (w->base_line_pos, BYTE_TO_CHAR (position));
4490 } 4652 }
4491 4653
4492 /* Now count lines from the start pos to point. */ 4654 /* Now count lines from the start pos to point. */
4493 nlines = display_count_lines (startpos, PT, PT, &junk); 4655 nlines = display_count_lines (startpos, startpos_byte,
4656 PT_BYTE, PT, &junk);
4494 4657
4495 /* Record that we did display the line number. */ 4658 /* Record that we did display the line number. */
4496 line_number_displayed = 1; 4659 line_number_displayed = 1;
@@ -4638,137 +4801,109 @@ decode_mode_spec (w, c, spec_width, maxwidth)
4638 return ""; 4801 return "";
4639} 4802}
4640 4803
4641/* Search for COUNT instances of a line boundary, which means either a 4804/* Count up to COUNT lines starting from START / START_BYTE.
4642 newline or (if selective display enabled) a carriage return. 4805 But don't go beyond LIMIT_BYTE.
4643 Start at START. If COUNT is negative, search backwards. 4806 Return the number of lines thus found (always nonnegative).
4644 4807
4645 If we find COUNT instances, set *SHORTAGE to zero, and return the 4808 Set *BYTE_POS_PTR to 1 if we found COUNT lines, 0 if we hit LIMIT. */
4646 position after the COUNTth match. Note that for reverse motion
4647 this is not the same as the usual convention for Emacs motion commands.
4648
4649 If we don't find COUNT instances before reaching the end of the
4650 buffer (or the beginning, if scanning backwards), set *SHORTAGE to
4651 the number of line boundaries left unfound, and return the end of the
4652 buffer we bumped up against. */
4653 4809
4654static int 4810static int
4655display_scan_buffer (start, count, shortage) 4811display_count_lines (start, start_byte, limit_byte, count, byte_pos_ptr)
4656 int *shortage, start; 4812 int start, start_byte, limit_byte, count;
4657 register int count; 4813 int *byte_pos_ptr;
4658{ 4814{
4659 int limit = ((count > 0) ? ZV - 1 : BEGV);
4660 int direction = ((count > 0) ? 1 : -1);
4661
4662 register unsigned char *cursor; 4815 register unsigned char *cursor;
4663 unsigned char *base; 4816 unsigned char *base;
4664 4817
4665 register int ceiling; 4818 register int ceiling;
4666 register unsigned char *ceiling_addr; 4819 register unsigned char *ceiling_addr;
4820 int orig_count = count;
4667 4821
4668 /* If we are not in selective display mode, 4822 /* If we are not in selective display mode,
4669 check only for newlines. */ 4823 check only for newlines. */
4670 if (! (!NILP (current_buffer->selective_display) 4824 int selective_display = (!NILP (current_buffer->selective_display)
4671 && !INTEGERP (current_buffer->selective_display))) 4825 && !INTEGERP (current_buffer->selective_display));
4672 return scan_buffer ('\n', start, 0, count, shortage, 0);
4673
4674 /* The code that follows is like scan_buffer
4675 but checks for either newline or carriage return. */
4676
4677 if (shortage != 0)
4678 *shortage = 0;
4679 4826
4680 if (count > 0) 4827 if (count > 0)
4681 while (start != limit + 1) 4828 {
4682 { 4829 while (start_byte < limit_byte)
4683 ceiling = BUFFER_CEILING_OF (start); 4830 {
4684 ceiling = min (limit, ceiling); 4831 ceiling = BUFFER_CEILING_OF (start_byte);
4685 ceiling_addr = POS_ADDR (ceiling) + 1; 4832 ceiling = min (limit_byte - 1, ceiling);
4686 base = (cursor = POS_ADDR (start)); 4833 ceiling_addr = BYTE_POS_ADDR (ceiling) + 1;
4687 while (1) 4834 base = (cursor = BYTE_POS_ADDR (start_byte));
4688 { 4835 while (1)
4689 while (*cursor != '\n' && *cursor != 015 && ++cursor != ceiling_addr) 4836 {
4690 ; 4837 if (selective_display)
4691 if (cursor != ceiling_addr) 4838 while (*cursor != '\n' && *cursor != 015 && ++cursor != ceiling_addr)
4692 { 4839 ;
4693 if (--count == 0) 4840 else
4694 { 4841 while (*cursor != '\n' && ++cursor != ceiling_addr)
4695 immediate_quit = 0; 4842 ;
4696 return (start + cursor - base + 1); 4843
4697 } 4844 if (cursor != ceiling_addr)
4698 else 4845 {
4699 if (++cursor == ceiling_addr) 4846 if (--count == 0)
4700 break; 4847 {
4701 } 4848 start_byte += cursor - base + 1;
4702 else 4849 *byte_pos_ptr = start_byte;
4703 break; 4850 return orig_count;
4704 } 4851 }
4705 start += cursor - base; 4852 else
4706 } 4853 if (++cursor == ceiling_addr)
4854 break;
4855 }
4856 else
4857 break;
4858 }
4859 start_byte += cursor - base;
4860 }
4861 }
4707 else 4862 else
4708 { 4863 {
4709 start--; /* first character we scan */ 4864 while (start_byte > limit_byte)
4710 while (start > limit - 1) 4865 {
4711 { /* we WILL scan under start */ 4866 ceiling = BUFFER_FLOOR_OF (start_byte - 1);
4712 ceiling = BUFFER_FLOOR_OF (start); 4867 ceiling = max (limit_byte, ceiling);
4713 ceiling = max (limit, ceiling); 4868 ceiling_addr = BYTE_POS_ADDR (ceiling) - 1;
4714 ceiling_addr = POS_ADDR (ceiling) - 1; 4869 base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1);
4715 base = (cursor = POS_ADDR (start));
4716 cursor++;
4717 while (1) 4870 while (1)
4718 { 4871 {
4719 while (--cursor != ceiling_addr 4872 if (selective_display)
4720 && *cursor != '\n' && *cursor != 015) 4873 while (--cursor != ceiling_addr
4721 ; 4874 && *cursor != '\n' && *cursor != 015)
4875 ;
4876 else
4877 while (--cursor != ceiling_addr && *cursor != '\n')
4878 ;
4879
4722 if (cursor != ceiling_addr) 4880 if (cursor != ceiling_addr)
4723 { 4881 {
4724 if (++count == 0) 4882 if (++count == 0)
4725 { 4883 {
4726 immediate_quit = 0; 4884 start_byte += cursor - base + 1;
4727 return (start + cursor - base + 1); 4885 *byte_pos_ptr = start_byte;
4886 /* When scanning backwards, we should
4887 not count the newline posterior to which we stop. */
4888 return - orig_count - 1;
4728 } 4889 }
4729 } 4890 }
4730 else 4891 else
4731 break; 4892 break;
4732 } 4893 }
4733 start += cursor - base; 4894 /* Here we add 1 to compensate for the last decrement
4895 of CURSOR, which took it past the valid range. */
4896 start_byte += cursor - base + 1;
4734 } 4897 }
4735 } 4898 }
4736 4899
4737 if (shortage != 0) 4900 *byte_pos_ptr = limit_byte;
4738 *shortage = count * direction;
4739 return (start + ((direction == 1 ? 0 : 1)));
4740}
4741 4901
4742/* Count up to N lines starting from FROM. 4902 if (count < 0)
4743 But don't go beyond LIMIT. 4903 return - orig_count + count;
4744 Return the number of lines thus found (always positive). 4904 return orig_count - count;
4745 Store the position after what was found into *POS_PTR. */
4746 4905
4747static int 4906}
4748display_count_lines (from, limit, n, pos_ptr)
4749 int from, limit, n;
4750 int *pos_ptr;
4751{
4752 int oldbegv = BEGV;
4753 int oldzv = ZV;
4754 int shortage = 0;
4755
4756 if (limit < from)
4757 BEGV = limit;
4758 else
4759 ZV = limit;
4760
4761 *pos_ptr = display_scan_buffer (from, n, &shortage);
4762
4763 ZV = oldzv;
4764 BEGV = oldbegv;
4765
4766 if (n < 0)
4767 /* When scanning backwards, scan_buffer stops *after* the last newline
4768 it finds, but does count it. Compensate for that. */
4769 return - n - shortage - (*pos_ptr != limit);
4770 return n - shortage;
4771}
4772 4907
4773/* Display STRING on one line of window W, starting at HPOS. 4908/* Display STRING on one line of window W, starting at HPOS.
4774 Display at position VPOS. Caller should have done get_display_line. 4909 Display at position VPOS. Caller should have done get_display_line.