diff options
| author | Joakim Verona | 2013-02-13 00:04:17 +0100 |
|---|---|---|
| committer | Joakim Verona | 2013-02-13 00:04:17 +0100 |
| commit | e46029ad6dda065541c8de40de0fe9d5800ac770 (patch) | |
| tree | 891ff36967b0ef02459ee46b6363b75bf810d524 /src | |
| parent | e0444a0966fa001953bb97cfb60451c42220be8e (diff) | |
| parent | c4131562319d3529841136d236ac39fb1e3d2b7c (diff) | |
| download | emacs-e46029ad6dda065541c8de40de0fe9d5800ac770.tar.gz emacs-e46029ad6dda065541c8de40de0fe9d5800ac770.zip | |
auto upstream
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 24 | ||||
| -rw-r--r-- | src/doc.c | 5 | ||||
| -rw-r--r-- | src/editfns.c | 5 | ||||
| -rw-r--r-- | src/fileio.c | 10 | ||||
| -rw-r--r-- | src/lisp.h | 4 | ||||
| -rw-r--r-- | src/region-cache.h | 2 | ||||
| -rw-r--r-- | src/search.c | 172 | ||||
| -rw-r--r-- | src/window.h | 3 | ||||
| -rw-r--r-- | src/xdisp.c | 118 |
9 files changed, 180 insertions, 163 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index b3d3958853b..05737bb1194 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,5 +1,29 @@ | |||
| 1 | 2013-02-12 Eli Zaretskii <eliz@gnu.org> | ||
| 2 | |||
| 3 | * xdisp.c (redisplay_internal): Don't set w->region_showing to the | ||
| 4 | marker's position. | ||
| 5 | (display_line): Set w->region_showing to the value of | ||
| 6 | it->region_beg_charpos, not to -1. This fixes redisplay | ||
| 7 | optimization when cursor is moved up after M->. (Bug#13623) | ||
| 8 | (Bug#13626) | ||
| 9 | (try_scrolling): Scroll text up more if point is too close to ZV | ||
| 10 | and inside the scroll margin. This makes sure point is moved | ||
| 11 | outside the scroll margin in these cases. | ||
| 12 | |||
| 13 | * window.h (struct window): region_showing can no longer be | ||
| 14 | negative. | ||
| 15 | |||
| 1 | 2013-02-11 Paul Eggert <eggert@cs.ucla.edu> | 16 | 2013-02-11 Paul Eggert <eggert@cs.ucla.edu> |
| 2 | 17 | ||
| 18 | Tune by using memchr and memrchr. | ||
| 19 | * doc.c (Fsnarf_documentation): | ||
| 20 | * fileio.c (Fsubstitute_in_file_name): | ||
| 21 | * search.c (find_newline, scan_newline): | ||
| 22 | * xdisp.c (pos_visible_p, display_count_lines): | ||
| 23 | Use memchr and memrchr rather than scanning byte-by-byte. | ||
| 24 | * search.c (find_newline): Rename from scan_buffer. | ||
| 25 | Omit first arg TARGET, as it's always '\n'. All callers changed. | ||
| 26 | |||
| 3 | Clean up read_key_sequence a tiny bit more. | 27 | Clean up read_key_sequence a tiny bit more. |
| 4 | * keyboard.c (read_char_x_menu_prompt) [HAVE_MENUS]: | 28 | * keyboard.c (read_char_x_menu_prompt) [HAVE_MENUS]: |
| 5 | (read_key_sequence): Remove unused locals. | 29 | (read_key_sequence): Remove unused locals. |
| @@ -630,11 +630,10 @@ the same file name is found in the `doc-directory'. */) | |||
| 630 | break; | 630 | break; |
| 631 | 631 | ||
| 632 | buf[filled] = 0; | 632 | buf[filled] = 0; |
| 633 | p = buf; | ||
| 634 | end = buf + (filled < 512 ? filled : filled - 128); | 633 | end = buf + (filled < 512 ? filled : filled - 128); |
| 635 | while (p != end && *p != '\037') p++; | 634 | p = memchr (buf, '\037', end - buf); |
| 636 | /* p points to ^_Ffunctionname\n or ^_Vvarname\n or ^_Sfilename\n. */ | 635 | /* p points to ^_Ffunctionname\n or ^_Vvarname\n or ^_Sfilename\n. */ |
| 637 | if (p != end) | 636 | if (p) |
| 638 | { | 637 | { |
| 639 | end = strchr (p, '\n'); | 638 | end = strchr (p, '\n'); |
| 640 | 639 | ||
diff --git a/src/editfns.c b/src/editfns.c index 0f88a781b88..c5cd8b0b725 100644 --- a/src/editfns.c +++ b/src/editfns.c | |||
| @@ -735,9 +735,8 @@ Field boundaries are not noticed if `inhibit-field-text-motion' is non-nil. */) | |||
| 735 | /* This is the ONLY_IN_LINE case, check that NEW_POS and | 735 | /* This is the ONLY_IN_LINE case, check that NEW_POS and |
| 736 | FIELD_BOUND are on the same line by seeing whether | 736 | FIELD_BOUND are on the same line by seeing whether |
| 737 | there's an intervening newline or not. */ | 737 | there's an intervening newline or not. */ |
| 738 | || (scan_buffer ('\n', | 738 | || (find_newline (XFASTINT (new_pos), XFASTINT (field_bound), |
| 739 | XFASTINT (new_pos), XFASTINT (field_bound), | 739 | fwd ? -1 : 1, &shortage, 1), |
| 740 | fwd ? -1 : 1, &shortage, 1), | ||
| 741 | shortage != 0))) | 740 | shortage != 0))) |
| 742 | /* Constrain NEW_POS to FIELD_BOUND. */ | 741 | /* Constrain NEW_POS to FIELD_BOUND. */ |
| 743 | new_pos = field_bound; | 742 | new_pos = field_bound; |
diff --git a/src/fileio.c b/src/fileio.c index 98a9b32ea91..89ad3396464 100644 --- a/src/fileio.c +++ b/src/fileio.c | |||
| @@ -1710,8 +1710,9 @@ those `/' is discarded. */) | |||
| 1710 | else if (*p == '{') | 1710 | else if (*p == '{') |
| 1711 | { | 1711 | { |
| 1712 | o = ++p; | 1712 | o = ++p; |
| 1713 | while (p != endp && *p != '}') p++; | 1713 | p = memchr (p, '}', endp - p); |
| 1714 | if (*p != '}') goto missingclose; | 1714 | if (! p) |
| 1715 | goto missingclose; | ||
| 1715 | s = p; | 1716 | s = p; |
| 1716 | } | 1717 | } |
| 1717 | else | 1718 | else |
| @@ -1779,8 +1780,9 @@ those `/' is discarded. */) | |||
| 1779 | else if (*p == '{') | 1780 | else if (*p == '{') |
| 1780 | { | 1781 | { |
| 1781 | o = ++p; | 1782 | o = ++p; |
| 1782 | while (p != endp && *p != '}') p++; | 1783 | p = memchr (p, '}', endp - p); |
| 1783 | if (*p != '}') goto missingclose; | 1784 | if (! p) |
| 1785 | goto missingclose; | ||
| 1784 | s = p++; | 1786 | s = p++; |
| 1785 | } | 1787 | } |
| 1786 | else | 1788 | else |
diff --git a/src/lisp.h b/src/lisp.h index 997ef458ec5..154f1ec5e5f 100644 --- a/src/lisp.h +++ b/src/lisp.h | |||
| @@ -3351,8 +3351,8 @@ extern ptrdiff_t fast_c_string_match_ignore_case (Lisp_Object, const char *, | |||
| 3351 | extern ptrdiff_t fast_string_match_ignore_case (Lisp_Object, Lisp_Object); | 3351 | extern ptrdiff_t fast_string_match_ignore_case (Lisp_Object, Lisp_Object); |
| 3352 | extern ptrdiff_t fast_looking_at (Lisp_Object, ptrdiff_t, ptrdiff_t, | 3352 | extern ptrdiff_t fast_looking_at (Lisp_Object, ptrdiff_t, ptrdiff_t, |
| 3353 | ptrdiff_t, ptrdiff_t, Lisp_Object); | 3353 | ptrdiff_t, ptrdiff_t, Lisp_Object); |
| 3354 | extern ptrdiff_t scan_buffer (int, ptrdiff_t, ptrdiff_t, ptrdiff_t, | 3354 | extern ptrdiff_t find_newline (ptrdiff_t, ptrdiff_t, ptrdiff_t, |
| 3355 | ptrdiff_t *, bool); | 3355 | ptrdiff_t *, bool); |
| 3356 | extern EMACS_INT scan_newline (ptrdiff_t, ptrdiff_t, ptrdiff_t, ptrdiff_t, | 3356 | extern EMACS_INT scan_newline (ptrdiff_t, ptrdiff_t, ptrdiff_t, ptrdiff_t, |
| 3357 | EMACS_INT, bool); | 3357 | EMACS_INT, bool); |
| 3358 | extern ptrdiff_t find_next_newline (ptrdiff_t, int); | 3358 | extern ptrdiff_t find_next_newline (ptrdiff_t, int); |
diff --git a/src/region-cache.h b/src/region-cache.h index 697ae1c791f..e4c6b59ee95 100644 --- a/src/region-cache.h +++ b/src/region-cache.h | |||
| @@ -40,7 +40,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 40 | existing data structure, and disturb as little of the existing code | 40 | existing data structure, and disturb as little of the existing code |
| 41 | as possible. | 41 | as possible. |
| 42 | 42 | ||
| 43 | So here's the tack. We add some caching to the scan_buffer | 43 | So here's the tack. We add some caching to the find_newline |
| 44 | function, so that when it searches for a newline, it notes that the | 44 | function, so that when it searches for a newline, it notes that the |
| 45 | region between the start and end of the search contained no | 45 | region between the start and end of the search contained no |
| 46 | newlines; then, the next time around, it consults this cache to see | 46 | newlines; then, the next time around, it consults this cache to see |
diff --git a/src/search.c b/src/search.c index c4ccf6c257b..c25d2441018 100644 --- a/src/search.c +++ b/src/search.c | |||
| @@ -619,7 +619,7 @@ newline_cache_on_off (struct buffer *buf) | |||
| 619 | } | 619 | } |
| 620 | 620 | ||
| 621 | 621 | ||
| 622 | /* Search for COUNT instances of the character TARGET between START and END. | 622 | /* Search for COUNT newlines between START and END. |
| 623 | 623 | ||
| 624 | If COUNT is positive, search forwards; END must be >= START. | 624 | If COUNT is positive, search forwards; END must be >= START. |
| 625 | If COUNT is negative, search backwards for the -COUNTth instance; | 625 | If COUNT is negative, search backwards for the -COUNTth instance; |
| @@ -634,14 +634,14 @@ newline_cache_on_off (struct buffer *buf) | |||
| 634 | this is not the same as the usual convention for Emacs motion commands. | 634 | this is not the same as the usual convention for Emacs motion commands. |
| 635 | 635 | ||
| 636 | If we don't find COUNT instances before reaching END, set *SHORTAGE | 636 | If we don't find COUNT instances before reaching END, set *SHORTAGE |
| 637 | to the number of TARGETs left unfound, and return END. | 637 | to the number of newlines left unfound, and return END. |
| 638 | 638 | ||
| 639 | If ALLOW_QUIT, set immediate_quit. That's good to do | 639 | If ALLOW_QUIT, set immediate_quit. That's good to do |
| 640 | except when inside redisplay. */ | 640 | except when inside redisplay. */ |
| 641 | 641 | ||
| 642 | ptrdiff_t | 642 | ptrdiff_t |
| 643 | scan_buffer (int target, ptrdiff_t start, ptrdiff_t end, | 643 | find_newline (ptrdiff_t start, ptrdiff_t end, |
| 644 | ptrdiff_t count, ptrdiff_t *shortage, bool allow_quit) | 644 | ptrdiff_t count, ptrdiff_t *shortage, bool allow_quit) |
| 645 | { | 645 | { |
| 646 | struct region_cache *newline_cache; | 646 | struct region_cache *newline_cache; |
| 647 | ptrdiff_t end_byte = -1; | 647 | ptrdiff_t end_byte = -1; |
| @@ -656,7 +656,7 @@ scan_buffer (int target, ptrdiff_t start, ptrdiff_t end, | |||
| 656 | else | 656 | else |
| 657 | { | 657 | { |
| 658 | direction = -1; | 658 | direction = -1; |
| 659 | if (!end) | 659 | if (!end) |
| 660 | end = BEGV, end_byte = BEGV_BYTE; | 660 | end = BEGV, end_byte = BEGV_BYTE; |
| 661 | } | 661 | } |
| 662 | if (end_byte == -1) | 662 | if (end_byte == -1) |
| @@ -684,7 +684,7 @@ scan_buffer (int target, ptrdiff_t start, ptrdiff_t end, | |||
| 684 | 684 | ||
| 685 | /* If we're looking for a newline, consult the newline cache | 685 | /* If we're looking for a newline, consult the newline cache |
| 686 | to see where we can avoid some scanning. */ | 686 | to see where we can avoid some scanning. */ |
| 687 | if (target == '\n' && newline_cache) | 687 | if (newline_cache) |
| 688 | { | 688 | { |
| 689 | ptrdiff_t next_change; | 689 | ptrdiff_t next_change; |
| 690 | immediate_quit = 0; | 690 | immediate_quit = 0; |
| @@ -723,32 +723,32 @@ scan_buffer (int target, ptrdiff_t start, ptrdiff_t end, | |||
| 723 | 723 | ||
| 724 | while (cursor < ceiling_addr) | 724 | while (cursor < ceiling_addr) |
| 725 | { | 725 | { |
| 726 | unsigned char *scan_start = cursor; | ||
| 727 | |||
| 728 | /* The dumb loop. */ | 726 | /* The dumb loop. */ |
| 729 | while (*cursor != target && ++cursor < ceiling_addr) | 727 | unsigned char *nl = memchr (cursor, '\n', ceiling_addr - cursor); |
| 730 | ; | ||
| 731 | 728 | ||
| 732 | /* If we're looking for newlines, cache the fact that | 729 | /* If we're looking for newlines, cache the fact that |
| 733 | the region from start to cursor is free of them. */ | 730 | the region from start to cursor is free of them. */ |
| 734 | if (target == '\n' && newline_cache) | 731 | if (newline_cache) |
| 735 | know_region_cache (current_buffer, newline_cache, | 732 | { |
| 736 | BYTE_TO_CHAR (start_byte + scan_start - base), | 733 | unsigned char *low = cursor; |
| 737 | BYTE_TO_CHAR (start_byte + cursor - base)); | 734 | unsigned char *lim = nl ? nl : ceiling_addr; |
| 738 | 735 | know_region_cache (current_buffer, newline_cache, | |
| 739 | /* Did we find the target character? */ | 736 | BYTE_TO_CHAR (low - base + start_byte), |
| 740 | if (cursor < ceiling_addr) | 737 | BYTE_TO_CHAR (lim - base + start_byte)); |
| 741 | { | 738 | } |
| 742 | if (--count == 0) | 739 | |
| 743 | { | 740 | if (! nl) |
| 744 | immediate_quit = 0; | 741 | break; |
| 745 | return BYTE_TO_CHAR (start_byte + cursor - base + 1); | 742 | |
| 746 | } | 743 | if (--count == 0) |
| 747 | cursor++; | 744 | { |
| 748 | } | 745 | immediate_quit = 0; |
| 746 | return BYTE_TO_CHAR (nl + 1 - base + start_byte); | ||
| 747 | } | ||
| 748 | cursor = nl + 1; | ||
| 749 | } | 749 | } |
| 750 | 750 | ||
| 751 | start = BYTE_TO_CHAR (start_byte + cursor - base); | 751 | start = BYTE_TO_CHAR (ceiling_addr - base + start_byte); |
| 752 | } | 752 | } |
| 753 | } | 753 | } |
| 754 | else | 754 | else |
| @@ -760,7 +760,7 @@ scan_buffer (int target, ptrdiff_t start, ptrdiff_t end, | |||
| 760 | ptrdiff_t tem; | 760 | ptrdiff_t tem; |
| 761 | 761 | ||
| 762 | /* Consult the newline cache, if appropriate. */ | 762 | /* Consult the newline cache, if appropriate. */ |
| 763 | if (target == '\n' && newline_cache) | 763 | if (newline_cache) |
| 764 | { | 764 | { |
| 765 | ptrdiff_t next_change; | 765 | ptrdiff_t next_change; |
| 766 | immediate_quit = 0; | 766 | immediate_quit = 0; |
| @@ -794,31 +794,32 @@ scan_buffer (int target, ptrdiff_t start, ptrdiff_t end, | |||
| 794 | 794 | ||
| 795 | while (cursor >= ceiling_addr) | 795 | while (cursor >= ceiling_addr) |
| 796 | { | 796 | { |
| 797 | unsigned char *scan_start = cursor; | 797 | unsigned char *nl = memrchr (ceiling_addr, '\n', |
| 798 | 798 | cursor + 1 - ceiling_addr); | |
| 799 | while (*cursor != target && --cursor >= ceiling_addr) | ||
| 800 | ; | ||
| 801 | 799 | ||
| 802 | /* If we're looking for newlines, cache the fact that | 800 | /* If we're looking for newlines, cache the fact that |
| 803 | the region from after the cursor to start is free of them. */ | 801 | the region from after the cursor to start is free of them. */ |
| 804 | if (target == '\n' && newline_cache) | 802 | if (newline_cache) |
| 805 | know_region_cache (current_buffer, newline_cache, | 803 | { |
| 806 | BYTE_TO_CHAR (start_byte + cursor - base), | 804 | unsigned char *low = nl ? nl : ceiling_addr - 1; |
| 807 | BYTE_TO_CHAR (start_byte + scan_start - base)); | 805 | unsigned char *lim = cursor; |
| 808 | 806 | know_region_cache (current_buffer, newline_cache, | |
| 809 | /* Did we find the target character? */ | 807 | BYTE_TO_CHAR (low - base + start_byte), |
| 810 | if (cursor >= ceiling_addr) | 808 | BYTE_TO_CHAR (lim - base + start_byte)); |
| 811 | { | 809 | } |
| 812 | if (++count >= 0) | 810 | |
| 813 | { | 811 | if (! nl) |
| 814 | immediate_quit = 0; | 812 | break; |
| 815 | return BYTE_TO_CHAR (start_byte + cursor - base); | 813 | |
| 816 | } | 814 | if (++count >= 0) |
| 817 | cursor--; | 815 | { |
| 818 | } | 816 | immediate_quit = 0; |
| 817 | return BYTE_TO_CHAR (nl - base + start_byte); | ||
| 818 | } | ||
| 819 | cursor = nl - 1; | ||
| 819 | } | 820 | } |
| 820 | 821 | ||
| 821 | start = BYTE_TO_CHAR (start_byte + cursor - base); | 822 | start = BYTE_TO_CHAR (ceiling_addr - 1 - base + start_byte); |
| 822 | } | 823 | } |
| 823 | } | 824 | } |
| 824 | 825 | ||
| @@ -828,8 +829,7 @@ scan_buffer (int target, ptrdiff_t start, ptrdiff_t end, | |||
| 828 | return start; | 829 | return start; |
| 829 | } | 830 | } |
| 830 | 831 | ||
| 831 | /* Search for COUNT instances of a line boundary, which means either a | 832 | /* Search for COUNT instances of a line boundary. |
| 832 | newline or (if selective display enabled) a carriage return. | ||
| 833 | Start at START. If COUNT is negative, search backwards. | 833 | Start at START. If COUNT is negative, search backwards. |
| 834 | 834 | ||
| 835 | We report the resulting position by calling TEMP_SET_PT_BOTH. | 835 | We report the resulting position by calling TEMP_SET_PT_BOTH. |
| @@ -860,9 +860,6 @@ scan_newline (ptrdiff_t start, ptrdiff_t start_byte, | |||
| 860 | 860 | ||
| 861 | bool old_immediate_quit = immediate_quit; | 861 | bool old_immediate_quit = immediate_quit; |
| 862 | 862 | ||
| 863 | /* The code that follows is like scan_buffer | ||
| 864 | but checks for either newline or carriage return. */ | ||
| 865 | |||
| 866 | if (allow_quit) | 863 | if (allow_quit) |
| 867 | immediate_quit++; | 864 | immediate_quit++; |
| 868 | 865 | ||
| @@ -874,29 +871,25 @@ scan_newline (ptrdiff_t start, ptrdiff_t start_byte, | |||
| 874 | ceiling = min (limit_byte - 1, ceiling); | 871 | ceiling = min (limit_byte - 1, ceiling); |
| 875 | ceiling_addr = BYTE_POS_ADDR (ceiling) + 1; | 872 | ceiling_addr = BYTE_POS_ADDR (ceiling) + 1; |
| 876 | base = (cursor = BYTE_POS_ADDR (start_byte)); | 873 | base = (cursor = BYTE_POS_ADDR (start_byte)); |
| 877 | while (1) | ||
| 878 | { | ||
| 879 | while (*cursor != '\n' && ++cursor != ceiling_addr) | ||
| 880 | ; | ||
| 881 | 874 | ||
| 882 | if (cursor != ceiling_addr) | 875 | do |
| 876 | { | ||
| 877 | unsigned char *nl = memchr (cursor, '\n', ceiling_addr - cursor); | ||
| 878 | if (! nl) | ||
| 879 | break; | ||
| 880 | if (--count == 0) | ||
| 883 | { | 881 | { |
| 884 | if (--count == 0) | 882 | immediate_quit = old_immediate_quit; |
| 885 | { | 883 | start_byte += nl - base + 1; |
| 886 | immediate_quit = old_immediate_quit; | 884 | start = BYTE_TO_CHAR (start_byte); |
| 887 | start_byte = start_byte + cursor - base + 1; | 885 | TEMP_SET_PT_BOTH (start, start_byte); |
| 888 | start = BYTE_TO_CHAR (start_byte); | 886 | return 0; |
| 889 | TEMP_SET_PT_BOTH (start, start_byte); | ||
| 890 | return 0; | ||
| 891 | } | ||
| 892 | else | ||
| 893 | if (++cursor == ceiling_addr) | ||
| 894 | break; | ||
| 895 | } | 887 | } |
| 896 | else | 888 | cursor = nl + 1; |
| 897 | break; | ||
| 898 | } | 889 | } |
| 899 | start_byte += cursor - base; | 890 | while (cursor < ceiling_addr); |
| 891 | |||
| 892 | start_byte += ceiling_addr - base; | ||
| 900 | } | 893 | } |
| 901 | } | 894 | } |
| 902 | else | 895 | else |
| @@ -905,31 +898,28 @@ scan_newline (ptrdiff_t start, ptrdiff_t start_byte, | |||
| 905 | { | 898 | { |
| 906 | ceiling = BUFFER_FLOOR_OF (start_byte - 1); | 899 | ceiling = BUFFER_FLOOR_OF (start_byte - 1); |
| 907 | ceiling = max (limit_byte, ceiling); | 900 | ceiling = max (limit_byte, ceiling); |
| 908 | ceiling_addr = BYTE_POS_ADDR (ceiling) - 1; | 901 | ceiling_addr = BYTE_POS_ADDR (ceiling); |
| 909 | base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1); | 902 | base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1); |
| 910 | while (1) | 903 | while (1) |
| 911 | { | 904 | { |
| 912 | while (--cursor != ceiling_addr && *cursor != '\n') | 905 | unsigned char *nl = memrchr (ceiling_addr, '\n', |
| 913 | ; | 906 | cursor - ceiling_addr); |
| 907 | if (! nl) | ||
| 908 | break; | ||
| 914 | 909 | ||
| 915 | if (cursor != ceiling_addr) | 910 | if (++count == 0) |
| 916 | { | 911 | { |
| 917 | if (++count == 0) | 912 | immediate_quit = old_immediate_quit; |
| 918 | { | 913 | /* Return the position AFTER the match we found. */ |
| 919 | immediate_quit = old_immediate_quit; | 914 | start_byte += nl - base + 1; |
| 920 | /* Return the position AFTER the match we found. */ | 915 | start = BYTE_TO_CHAR (start_byte); |
| 921 | start_byte = start_byte + cursor - base + 1; | 916 | TEMP_SET_PT_BOTH (start, start_byte); |
| 922 | start = BYTE_TO_CHAR (start_byte); | 917 | return 0; |
| 923 | TEMP_SET_PT_BOTH (start, start_byte); | ||
| 924 | return 0; | ||
| 925 | } | ||
| 926 | } | 918 | } |
| 927 | else | 919 | |
| 928 | break; | 920 | cursor = nl; |
| 929 | } | 921 | } |
| 930 | /* Here we add 1 to compensate for the last decrement | 922 | start_byte += ceiling_addr - base; |
| 931 | of CURSOR, which took it past the valid range. */ | ||
| 932 | start_byte += cursor - base + 1; | ||
| 933 | } | 923 | } |
| 934 | } | 924 | } |
| 935 | 925 | ||
| @@ -942,7 +932,7 @@ scan_newline (ptrdiff_t start, ptrdiff_t start_byte, | |||
| 942 | ptrdiff_t | 932 | ptrdiff_t |
| 943 | find_next_newline_no_quit (ptrdiff_t from, ptrdiff_t cnt) | 933 | find_next_newline_no_quit (ptrdiff_t from, ptrdiff_t cnt) |
| 944 | { | 934 | { |
| 945 | return scan_buffer ('\n', from, 0, cnt, (ptrdiff_t *) 0, 0); | 935 | return find_newline (from, 0, cnt, (ptrdiff_t *) 0, 0); |
| 946 | } | 936 | } |
| 947 | 937 | ||
| 948 | /* Like find_next_newline, but returns position before the newline, | 938 | /* Like find_next_newline, but returns position before the newline, |
| @@ -953,7 +943,7 @@ ptrdiff_t | |||
| 953 | find_before_next_newline (ptrdiff_t from, ptrdiff_t to, ptrdiff_t cnt) | 943 | find_before_next_newline (ptrdiff_t from, ptrdiff_t to, ptrdiff_t cnt) |
| 954 | { | 944 | { |
| 955 | ptrdiff_t shortage; | 945 | ptrdiff_t shortage; |
| 956 | ptrdiff_t pos = scan_buffer ('\n', from, to, cnt, &shortage, 1); | 946 | ptrdiff_t pos = find_newline (from, to, cnt, &shortage, 1); |
| 957 | 947 | ||
| 958 | if (shortage == 0) | 948 | if (shortage == 0) |
| 959 | pos--; | 949 | pos--; |
diff --git a/src/window.h b/src/window.h index 0f4f242641e..dcef37abb4c 100644 --- a/src/window.h +++ b/src/window.h | |||
| @@ -338,8 +338,7 @@ struct window | |||
| 338 | int vscroll; | 338 | int vscroll; |
| 339 | 339 | ||
| 340 | /* If we have highlighted the region (or any part of it), the mark | 340 | /* If we have highlighted the region (or any part of it), the mark |
| 341 | position or -1 (the latter is used by the iterator for internal | 341 | (region start) position; otherwise zero. */ |
| 342 | purposes); otherwise zero. */ | ||
| 343 | ptrdiff_t region_showing; | 342 | ptrdiff_t region_showing; |
| 344 | 343 | ||
| 345 | /* Z_BYTE - buffer position of the last glyph in the current matrix of W. | 344 | /* Z_BYTE - buffer position of the last glyph in the current matrix of W. |
diff --git a/src/xdisp.c b/src/xdisp.c index 2e357a6e321..df0d55566e8 100644 --- a/src/xdisp.c +++ b/src/xdisp.c | |||
| @@ -1397,21 +1397,9 @@ pos_visible_p (struct window *w, ptrdiff_t charpos, int *x, int *y, | |||
| 1397 | Lisp_Object cpos = make_number (charpos); | 1397 | Lisp_Object cpos = make_number (charpos); |
| 1398 | Lisp_Object spec = Fget_char_property (cpos, Qdisplay, Qnil); | 1398 | Lisp_Object spec = Fget_char_property (cpos, Qdisplay, Qnil); |
| 1399 | Lisp_Object string = string_from_display_spec (spec); | 1399 | Lisp_Object string = string_from_display_spec (spec); |
| 1400 | int newline_in_string = 0; | 1400 | bool newline_in_string |
| 1401 | 1401 | = (STRINGP (string) | |
| 1402 | if (STRINGP (string)) | 1402 | && memchr (SDATA (string), '\n', SBYTES (string))); |
| 1403 | { | ||
| 1404 | const char *s = SSDATA (string); | ||
| 1405 | const char *e = s + SBYTES (string); | ||
| 1406 | while (s < e) | ||
| 1407 | { | ||
| 1408 | if (*s++ == '\n') | ||
| 1409 | { | ||
| 1410 | newline_in_string = 1; | ||
| 1411 | break; | ||
| 1412 | } | ||
| 1413 | } | ||
| 1414 | } | ||
| 1415 | /* The tricky code below is needed because there's a | 1403 | /* The tricky code below is needed because there's a |
| 1416 | discrepancy between move_it_to and how we set cursor | 1404 | discrepancy between move_it_to and how we set cursor |
| 1417 | when the display line ends in a newline from a | 1405 | when the display line ends in a newline from a |
| @@ -13317,8 +13305,6 @@ redisplay_internal (void) | |||
| 13317 | ++clear_image_cache_count; | 13305 | ++clear_image_cache_count; |
| 13318 | #endif | 13306 | #endif |
| 13319 | 13307 | ||
| 13320 | w->region_showing = XINT (Fmarker_position (BVAR (XBUFFER (w->buffer), mark))); | ||
| 13321 | |||
| 13322 | /* Build desired matrices, and update the display. If | 13308 | /* Build desired matrices, and update the display. If |
| 13323 | consider_all_windows_p is non-zero, do it for all windows on all | 13309 | consider_all_windows_p is non-zero, do it for all windows on all |
| 13324 | frames. Otherwise do it for selected_window, only. */ | 13310 | frames. Otherwise do it for selected_window, only. */ |
| @@ -14679,14 +14665,24 @@ try_scrolling (Lisp_Object window, int just_this_one_p, | |||
| 14679 | else | 14665 | else |
| 14680 | { | 14666 | { |
| 14681 | struct text_pos scroll_margin_pos = startp; | 14667 | struct text_pos scroll_margin_pos = startp; |
| 14668 | int y_offset = 0; | ||
| 14682 | 14669 | ||
| 14683 | /* See if point is inside the scroll margin at the top of the | 14670 | /* See if point is inside the scroll margin at the top of the |
| 14684 | window. */ | 14671 | window. */ |
| 14685 | if (this_scroll_margin) | 14672 | if (this_scroll_margin) |
| 14686 | { | 14673 | { |
| 14674 | int y_start; | ||
| 14675 | |||
| 14687 | start_display (&it, w, startp); | 14676 | start_display (&it, w, startp); |
| 14677 | y_start = it.current_y; | ||
| 14688 | move_it_vertically (&it, this_scroll_margin); | 14678 | move_it_vertically (&it, this_scroll_margin); |
| 14689 | scroll_margin_pos = it.current.pos; | 14679 | scroll_margin_pos = it.current.pos; |
| 14680 | /* If we didn't move enough before hitting ZV, request | ||
| 14681 | additional amount of scroll, to move point out of the | ||
| 14682 | scroll margin. */ | ||
| 14683 | if (IT_CHARPOS (it) == ZV | ||
| 14684 | && it.current_y - y_start < this_scroll_margin) | ||
| 14685 | y_offset = this_scroll_margin - (it.current_y - y_start); | ||
| 14690 | } | 14686 | } |
| 14691 | 14687 | ||
| 14692 | if (PT < CHARPOS (scroll_margin_pos)) | 14688 | if (PT < CHARPOS (scroll_margin_pos)) |
| @@ -14713,6 +14709,9 @@ try_scrolling (Lisp_Object window, int just_this_one_p, | |||
| 14713 | || IT_CHARPOS (it) < CHARPOS (scroll_margin_pos)) | 14709 | || IT_CHARPOS (it) < CHARPOS (scroll_margin_pos)) |
| 14714 | return SCROLLING_FAILED; | 14710 | return SCROLLING_FAILED; |
| 14715 | 14711 | ||
| 14712 | /* Additional scroll for when ZV was too close to point. */ | ||
| 14713 | dy += y_offset; | ||
| 14714 | |||
| 14716 | /* Compute new window start. */ | 14715 | /* Compute new window start. */ |
| 14717 | start_display (&it, w, startp); | 14716 | start_display (&it, w, startp); |
| 14718 | 14717 | ||
| @@ -14820,7 +14819,7 @@ compute_window_start_on_continuation_line (struct window *w) | |||
| 14820 | SET_TEXT_POS (start_pos, ZV, ZV_BYTE); | 14819 | SET_TEXT_POS (start_pos, ZV, ZV_BYTE); |
| 14821 | 14820 | ||
| 14822 | /* Find the start of the continued line. This should be fast | 14821 | /* Find the start of the continued line. This should be fast |
| 14823 | because scan_buffer is fast (newline cache). */ | 14822 | because find_newline is fast (newline cache). */ |
| 14824 | row = w->desired_matrix->rows + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0); | 14823 | row = w->desired_matrix->rows + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0); |
| 14825 | init_iterator (&it, w, CHARPOS (start_pos), BYTEPOS (start_pos), | 14824 | init_iterator (&it, w, CHARPOS (start_pos), BYTEPOS (start_pos), |
| 14826 | row, DEFAULT_FACE_ID); | 14825 | row, DEFAULT_FACE_ID); |
| @@ -19255,7 +19254,7 @@ display_line (struct it *it) | |||
| 19255 | } | 19254 | } |
| 19256 | 19255 | ||
| 19257 | /* Is IT->w showing the region? */ | 19256 | /* Is IT->w showing the region? */ |
| 19258 | it->w->region_showing = it->region_beg_charpos > 0 ? -1 : 0; | 19257 | it->w->region_showing = it->region_beg_charpos > 0 ? it->region_beg_charpos : 0; |
| 19259 | 19258 | ||
| 19260 | /* Clear the result glyph row and enable it. */ | 19259 | /* Clear the result glyph row and enable it. */ |
| 19261 | prepare_desired_row (row); | 19260 | prepare_desired_row (row); |
| @@ -21731,31 +21730,36 @@ display_count_lines (ptrdiff_t start_byte, | |||
| 21731 | ceiling = min (limit_byte - 1, ceiling); | 21730 | ceiling = min (limit_byte - 1, ceiling); |
| 21732 | ceiling_addr = BYTE_POS_ADDR (ceiling) + 1; | 21731 | ceiling_addr = BYTE_POS_ADDR (ceiling) + 1; |
| 21733 | base = (cursor = BYTE_POS_ADDR (start_byte)); | 21732 | base = (cursor = BYTE_POS_ADDR (start_byte)); |
| 21734 | while (1) | 21733 | |
| 21734 | do | ||
| 21735 | { | 21735 | { |
| 21736 | if (selective_display) | 21736 | if (selective_display) |
| 21737 | while (*cursor != '\n' && *cursor != 015 && ++cursor != ceiling_addr) | 21737 | { |
| 21738 | ; | 21738 | while (*cursor != '\n' && *cursor != 015 |
| 21739 | && ++cursor != ceiling_addr) | ||
| 21740 | continue; | ||
| 21741 | if (cursor == ceiling_addr) | ||
| 21742 | break; | ||
| 21743 | } | ||
| 21739 | else | 21744 | else |
| 21740 | while (*cursor != '\n' && ++cursor != ceiling_addr) | 21745 | { |
| 21741 | ; | 21746 | cursor = memchr (cursor, '\n', ceiling_addr - cursor); |
| 21747 | if (! cursor) | ||
| 21748 | break; | ||
| 21749 | } | ||
| 21750 | |||
| 21751 | cursor++; | ||
| 21742 | 21752 | ||
| 21743 | if (cursor != ceiling_addr) | 21753 | if (--count == 0) |
| 21744 | { | 21754 | { |
| 21745 | if (--count == 0) | 21755 | start_byte += cursor - base; |
| 21746 | { | 21756 | *byte_pos_ptr = start_byte; |
| 21747 | start_byte += cursor - base + 1; | 21757 | return orig_count; |
| 21748 | *byte_pos_ptr = start_byte; | ||
| 21749 | return orig_count; | ||
| 21750 | } | ||
| 21751 | else | ||
| 21752 | if (++cursor == ceiling_addr) | ||
| 21753 | break; | ||
| 21754 | } | 21758 | } |
| 21755 | else | ||
| 21756 | break; | ||
| 21757 | } | 21759 | } |
| 21758 | start_byte += cursor - base; | 21760 | while (cursor < ceiling_addr); |
| 21761 | |||
| 21762 | start_byte += ceiling_addr - base; | ||
| 21759 | } | 21763 | } |
| 21760 | } | 21764 | } |
| 21761 | else | 21765 | else |
| @@ -21764,35 +21768,35 @@ display_count_lines (ptrdiff_t start_byte, | |||
| 21764 | { | 21768 | { |
| 21765 | ceiling = BUFFER_FLOOR_OF (start_byte - 1); | 21769 | ceiling = BUFFER_FLOOR_OF (start_byte - 1); |
| 21766 | ceiling = max (limit_byte, ceiling); | 21770 | ceiling = max (limit_byte, ceiling); |
| 21767 | ceiling_addr = BYTE_POS_ADDR (ceiling) - 1; | 21771 | ceiling_addr = BYTE_POS_ADDR (ceiling); |
| 21768 | base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1); | 21772 | base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1); |
| 21769 | while (1) | 21773 | while (1) |
| 21770 | { | 21774 | { |
| 21771 | if (selective_display) | 21775 | if (selective_display) |
| 21772 | while (--cursor != ceiling_addr | 21776 | { |
| 21773 | && *cursor != '\n' && *cursor != 015) | 21777 | while (--cursor >= ceiling_addr |
| 21774 | ; | 21778 | && *cursor != '\n' && *cursor != 015) |
| 21779 | continue; | ||
| 21780 | if (cursor < ceiling_addr) | ||
| 21781 | break; | ||
| 21782 | } | ||
| 21775 | else | 21783 | else |
| 21776 | while (--cursor != ceiling_addr && *cursor != '\n') | 21784 | { |
| 21777 | ; | 21785 | cursor = memrchr (ceiling_addr, '\n', cursor - ceiling_addr); |
| 21786 | if (! cursor) | ||
| 21787 | break; | ||
| 21788 | } | ||
| 21778 | 21789 | ||
| 21779 | if (cursor != ceiling_addr) | 21790 | if (++count == 0) |
| 21780 | { | 21791 | { |
| 21781 | if (++count == 0) | 21792 | start_byte += cursor - base + 1; |
| 21782 | { | 21793 | *byte_pos_ptr = start_byte; |
| 21783 | start_byte += cursor - base + 1; | 21794 | /* When scanning backwards, we should |
| 21784 | *byte_pos_ptr = start_byte; | 21795 | not count the newline posterior to which we stop. */ |
| 21785 | /* When scanning backwards, we should | 21796 | return - orig_count - 1; |
| 21786 | not count the newline posterior to which we stop. */ | ||
| 21787 | return - orig_count - 1; | ||
| 21788 | } | ||
| 21789 | } | 21797 | } |
| 21790 | else | ||
| 21791 | break; | ||
| 21792 | } | 21798 | } |
| 21793 | /* Here we add 1 to compensate for the last decrement | 21799 | start_byte += ceiling_addr - base; |
| 21794 | of CURSOR, which took it past the valid range. */ | ||
| 21795 | start_byte += cursor - base + 1; | ||
| 21796 | } | 21800 | } |
| 21797 | } | 21801 | } |
| 21798 | 21802 | ||