Mercurial > emacs
changeset 8622:4ce43042e7ad
(display_scan_buffer): New function.
(display_count_lines): Use that.
author | Richard M. Stallman <rms@gnu.org> |
---|---|
date | Thu, 25 Aug 1994 01:25:55 +0000 |
parents | e292e9adde9b |
children | 428abda49671 |
files | src/xdisp.c |
diffstat | 1 files changed, 102 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- a/src/xdisp.c Thu Aug 25 00:39:13 1994 +0000 +++ b/src/xdisp.c Thu Aug 25 01:25:55 1994 +0000 @@ -3123,6 +3123,107 @@ else return ""; } + +/* Search for COUNT instances of a line boundary, which means either a + newline or (if selective display enabled) a carriage return. + Start at START. If COUNT is negative, search backwards. + + If we find COUNT instances, set *SHORTAGE to zero, and return the + position after the COUNTth match. Note that for reverse motion + this is not the same as the usual convention for Emacs motion commands. + + If we don't find COUNT instances before reaching the end of the + buffer (or the beginning, if scanning backwards), set *SHORTAGE to + the number of line boundaries left unfound, and return the end of the + buffer we bumped up against. */ + +static int +display_scan_buffer (start, count, shortage) + int *shortage, start; + register int count; +{ + int limit = ((count > 0) ? ZV - 1 : BEGV); + int direction = ((count > 0) ? 1 : -1); + + register unsigned char *cursor; + unsigned char *base; + + register int ceiling; + register unsigned char *ceiling_addr; + + /* If we are not in selective display mode, + check only for newlines. */ + if (! (!NILP (current_buffer->selective_display) + && !INTEGERP (current_buffer->selective_display))) + return scan_buffer ('\n', start, count, shortage, 0); + + /* The code that follows is like scan_buffer + but checks for either newline or carriage return. */ + + if (shortage != 0) + *shortage = 0; + + if (count > 0) + while (start != limit + 1) + { + ceiling = BUFFER_CEILING_OF (start); + ceiling = min (limit, ceiling); + ceiling_addr = &FETCH_CHAR (ceiling) + 1; + base = (cursor = &FETCH_CHAR (start)); + while (1) + { + while (*cursor != '\n' && *cursor != 015 && ++cursor != ceiling_addr) + ; + if (cursor != ceiling_addr) + { + if (--count == 0) + { + immediate_quit = 0; + return (start + cursor - base + 1); + } + else + if (++cursor == ceiling_addr) + break; + } + else + break; + } + start += cursor - base; + } + else + { + start--; /* first character we scan */ + while (start > limit - 1) + { /* we WILL scan under start */ + ceiling = BUFFER_FLOOR_OF (start); + ceiling = max (limit, ceiling); + ceiling_addr = &FETCH_CHAR (ceiling) - 1; + base = (cursor = &FETCH_CHAR (start)); + cursor++; + while (1) + { + while (--cursor != ceiling_addr + && *cursor != '\n' && *cursor != 015) + ; + if (cursor != ceiling_addr) + { + if (++count == 0) + { + immediate_quit = 0; + return (start + cursor - base + 1); + } + } + else + break; + } + start += cursor - base; + } + } + + if (shortage != 0) + *shortage = count * direction; + return (start + ((direction == 1 ? 0 : 1))); +} /* Count up to N lines starting from FROM. But don't go beyond LIMIT. @@ -3143,7 +3244,7 @@ else ZV = limit; - *pos_ptr = scan_buffer ('\n', from, n, &shortage, 0); + *pos_ptr = display_scan_buffer (from, n, &shortage); ZV = oldzv; BEGV = oldbegv;