diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/xdisp.c | 597 |
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 | |||
| 266 | static 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 | ||
| 413 | static int | 429 | static int |
| 414 | message_log_check_duplicate (prev_bol, this_bol) | 430 | message_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 | ||
| 2229 | done: | 2281 | done: |
| 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 | |||
| 2383 | try_window_id (window) | 2439 | try_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 | |||
| 2990 | static int | ||
| 2991 | pos_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) | |||
| 2927 | struct position val_display_text_line; | 3036 | struct position val_display_text_line; |
| 2928 | 3037 | ||
| 2929 | static struct position * | 3038 | static struct position * |
| 2930 | display_text_line (w, start, vpos, hpos, taboffset, ovstr_done) | 3039 | display_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 | ||
| 4654 | static int | 4810 | static int |
| 4655 | display_scan_buffer (start, count, shortage) | 4811 | display_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 | ||
| 4747 | static int | 4906 | } |
| 4748 | display_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. |