=== modified file 'src/buffer.c' --- src/buffer.c 2014-03-15 11:16:12 +0000 +++ src/buffer.c 2014-03-17 14:42:01 +0000 @@ -573,6 +573,7 @@ BUF_END_UNCHANGED (b) = 0; BUF_BEG_UNCHANGED (b) = 0; *(BUF_GPT_ADDR (b)) = *(BUF_Z_ADDR (b)) = 0; /* Put an anchor '\0'. */ + BUF_NL (b) = 0; b->text->inhibit_shrinking = false; b->text->redisplay = false; === modified file 'src/buffer.h' --- src/buffer.h 2014-01-01 07:43:34 +0000 +++ src/buffer.h 2014-03-17 14:42:01 +0000 @@ -91,6 +91,9 @@ /* Modification count as of last visit or save. */ #define SAVE_MODIFF (current_buffer->text->save_modiff) +/* How many '\n' in the buffer. */ +#define NL (current_buffer->text->nl) + /* BUFFER_CEILING_OF (resp. BUFFER_FLOOR_OF), when applied to n, return the max (resp. min) p such that @@ -183,6 +186,9 @@ /* FIXME: should we move this into ->text->auto_save_modiff? */ #define BUF_AUTOSAVE_MODIFF(buf) ((buf)->auto_save_modified) +/* How many '\n' in the buffer. */ +#define BUF_NL(buf) ((buf)->text->nl) + /* Compaction count. */ #define BUF_COMPACT(buf) ((buf)->text->compact) @@ -463,6 +469,9 @@ /* Properties of this buffer's text. */ INTERVAL intervals; + /* How many '\n' in this buffer's text. */ + ptrdiff_t nl; + /* The markers that refer to this buffer. This is actually a single marker --- successive elements in its marker `chain' === modified file 'src/insdel.c' --- src/insdel.c 2014-01-01 17:44:48 +0000 +++ src/insdel.c 2014-03-17 14:55:57 +0000 @@ -560,7 +560,20 @@ return to_addr - initial_to_addr; } } - + +/* Count '\n' in [PTR..PTR + NBYTES). */ + +static ptrdiff_t +count_newlines (const char *ptr, ptrdiff_t nbytes) +{ + const char *p = ptr; + ptrdiff_t count = 0, restbytes = nbytes; + + while (restbytes > 0 && (p = memchr (p, '\n', restbytes))) + p++, count++, restbytes = nbytes - (p - ptr); + return count; +} + /* Insert a string of specified length before point. This function judges multibyteness based on enable_multibyte_characters in the current buffer; @@ -814,6 +827,9 @@ MODIFF++; CHARS_MODIFF = MODIFF; + /* Count newlines in new text. */ + NL += count_newlines (string, nbytes); + memcpy (GPT_ADDR, string, nbytes); GAP_SIZE -= nbytes; @@ -924,6 +940,9 @@ make_gap (outgoing_nbytes - GAP_SIZE); UNGCPRO; + /* Count newlines in string text. */ + NL += count_newlines (SSDATA (string) + pos_byte, nbytes); + /* Copy the string text into the buffer, perhaps converting between single-byte and multibyte. */ copy_text (SDATA (string) + pos_byte, GPT_ADDR, nbytes, @@ -1001,6 +1020,11 @@ record_insert (GPT, nchars); MODIFF++; + /* Add newlines from new text. */ + NL += count_newlines (text_at_gap_tail + ? (char *) GAP_END_ADDR - nbytes + : (char *) GPT_ADDR, nbytes); + GAP_SIZE -= nbytes; if (! text_at_gap_tail) { @@ -1138,6 +1162,9 @@ emacs_abort (); #endif + /* Add newlines from gap. */ + NL += count_newlines ((char *) GPT_ADDR, outgoing_nbytes); + record_insert (PT, nchars); MODIFF++; CHARS_MODIFF = MODIFF; @@ -1340,6 +1367,9 @@ combining. */ if (! EQ (BVAR (current_buffer, undo_list), Qt)) deletion = make_buffer_string_both (from, from_byte, to, to_byte, 1); + + /* Do not count newlines from deleted text any more. */ + NL -= count_newlines ((char *) BYTE_POS_ADDR (from_byte), nbytes_del); GAP_SIZE += nbytes_del; ZV -= nchars_del; @@ -1360,6 +1390,9 @@ if (GAP_SIZE < outgoing_insbytes) make_gap (outgoing_insbytes - GAP_SIZE); + /* Add newlines from string text. */ + NL += count_newlines (SSDATA (new), insbytes); + /* Copy the string text into the buffer, perhaps converting between single-byte and multibyte. */ copy_text (SDATA (new), GPT_ADDR, insbytes, @@ -1470,6 +1503,9 @@ if (to < GPT) gap_left (to, to_byte, 0); + /* Do not count newlines from deleted text any more. */ + NL -= count_newlines ((char *) BYTE_POS_ADDR (from_byte), nbytes_del); + GAP_SIZE += nbytes_del; ZV -= nchars_del; Z -= nchars_del; @@ -1489,6 +1525,9 @@ if (GAP_SIZE < insbytes) make_gap (insbytes - GAP_SIZE); + /* Add newlines from replacement text. */ + NL += count_newlines (ins, insbytes); + /* Copy the replacement text into the buffer. */ memcpy (GPT_ADDR, ins, insbytes); @@ -1737,6 +1776,9 @@ adjusting the markers that bound the overlays. */ adjust_overlays_for_delete (from, nchars_del); + /* Do not count newlines from deleted text any more. */ + NL -= count_newlines ((char *) BYTE_POS_ADDR (from_byte), nbytes_del); + GAP_SIZE += nbytes_del; ZV_BYTE -= nbytes_del; Z_BYTE -= nbytes_del;