aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJoakim Verona2013-02-13 00:04:17 +0100
committerJoakim Verona2013-02-13 00:04:17 +0100
commite46029ad6dda065541c8de40de0fe9d5800ac770 (patch)
tree891ff36967b0ef02459ee46b6363b75bf810d524 /src
parente0444a0966fa001953bb97cfb60451c42220be8e (diff)
parentc4131562319d3529841136d236ac39fb1e3d2b7c (diff)
downloademacs-e46029ad6dda065541c8de40de0fe9d5800ac770.tar.gz
emacs-e46029ad6dda065541c8de40de0fe9d5800ac770.zip
auto upstream
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog24
-rw-r--r--src/doc.c5
-rw-r--r--src/editfns.c5
-rw-r--r--src/fileio.c10
-rw-r--r--src/lisp.h4
-rw-r--r--src/region-cache.h2
-rw-r--r--src/search.c172
-rw-r--r--src/window.h3
-rw-r--r--src/xdisp.c118
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 @@
12013-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
12013-02-11 Paul Eggert <eggert@cs.ucla.edu> 162013-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.
diff --git a/src/doc.c b/src/doc.c
index fa2eca66a1d..7234fb38bf9 100644
--- a/src/doc.c
+++ b/src/doc.c
@@ -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 *,
3351extern ptrdiff_t fast_string_match_ignore_case (Lisp_Object, Lisp_Object); 3351extern ptrdiff_t fast_string_match_ignore_case (Lisp_Object, Lisp_Object);
3352extern ptrdiff_t fast_looking_at (Lisp_Object, ptrdiff_t, ptrdiff_t, 3352extern 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);
3354extern ptrdiff_t scan_buffer (int, ptrdiff_t, ptrdiff_t, ptrdiff_t, 3354extern ptrdiff_t find_newline (ptrdiff_t, ptrdiff_t, ptrdiff_t,
3355 ptrdiff_t *, bool); 3355 ptrdiff_t *, bool);
3356extern EMACS_INT scan_newline (ptrdiff_t, ptrdiff_t, ptrdiff_t, ptrdiff_t, 3356extern EMACS_INT scan_newline (ptrdiff_t, ptrdiff_t, ptrdiff_t, ptrdiff_t,
3357 EMACS_INT, bool); 3357 EMACS_INT, bool);
3358extern ptrdiff_t find_next_newline (ptrdiff_t, int); 3358extern 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
642ptrdiff_t 642ptrdiff_t
643scan_buffer (int target, ptrdiff_t start, ptrdiff_t end, 643find_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,
942ptrdiff_t 932ptrdiff_t
943find_next_newline_no_quit (ptrdiff_t from, ptrdiff_t cnt) 933find_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
953find_before_next_newline (ptrdiff_t from, ptrdiff_t to, ptrdiff_t cnt) 943find_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