# HG changeset patch # User Bram Moolenaar # Date 1392127843 -3600 # Node ID beb037a6c2708f539d50840637f70eed0811d93c # Parent e2140f8c3b206a638fd98605737251a41ab6e388 updated for version 7.4.171 Problem: Redo does not set v:count and v:count1. Solution: Use a separate buffer for redo, so that we can set the counts when performing redo. diff --git a/src/getchar.c b/src/getchar.c --- a/src/getchar.c +++ b/src/getchar.c @@ -40,13 +40,13 @@ #define MINIMAL_SIZE 20 /* minimal size for b_str */ -static struct buffheader redobuff = {{NULL, {NUL}}, NULL, 0, 0}; -static struct buffheader old_redobuff = {{NULL, {NUL}}, NULL, 0, 0}; +static buffheader_T redobuff = {{NULL, {NUL}}, NULL, 0, 0}; +static buffheader_T old_redobuff = {{NULL, {NUL}}, NULL, 0, 0}; #if defined(FEAT_AUTOCMD) || defined(FEAT_EVAL) || defined(PROTO) -static struct buffheader save_redobuff = {{NULL, {NUL}}, NULL, 0, 0}; -static struct buffheader save_old_redobuff = {{NULL, {NUL}}, NULL, 0, 0}; +static buffheader_T save_redobuff = {{NULL, {NUL}}, NULL, 0, 0}; +static buffheader_T save_old_redobuff = {{NULL, {NUL}}, NULL, 0, 0}; #endif -static struct buffheader recordbuff = {{NULL, {NUL}}, NULL, 0, 0}; +static buffheader_T recordbuff = {{NULL, {NUL}}, NULL, 0, 0}; static int typeahead_char = 0; /* typeahead char that's not flushed */ @@ -112,11 +112,12 @@ static char_u noremapbuf_init[TYPELEN_IN static int last_recorded_len = 0; /* number of last recorded chars */ -static char_u *get_buffcont __ARGS((struct buffheader *, int)); -static void add_buff __ARGS((struct buffheader *, char_u *, long n)); -static void add_num_buff __ARGS((struct buffheader *, long)); -static void add_char_buff __ARGS((struct buffheader *, int)); -static int read_stuff __ARGS((int advance)); +static char_u *get_buffcont __ARGS((buffheader_T *, int)); +static void add_buff __ARGS((buffheader_T *, char_u *, long n)); +static void add_num_buff __ARGS((buffheader_T *, long)); +static void add_char_buff __ARGS((buffheader_T *, int)); +static int read_readbuffers __ARGS((int advance)); +static int read_readbuf __ARGS((buffheader_T *buf, int advance)); static void start_stuff __ARGS((void)); static int read_redo __ARGS((int, int)); static void copy_redo __ARGS((int)); @@ -137,9 +138,9 @@ static char_u *eval_map_expr __ARGS((cha */ void free_buff(buf) - struct buffheader *buf; + buffheader_T *buf; { - struct buffblock *p, *np; + buffblock_T *p, *np; for (p = buf->bh_first.b_next; p != NULL; p = np) { @@ -155,14 +156,14 @@ free_buff(buf) */ static char_u * get_buffcont(buffer, dozero) - struct buffheader *buffer; + buffheader_T *buffer; int dozero; /* count == zero is not an error */ { long_u count = 0; char_u *p = NULL; char_u *p2; char_u *str; - struct buffblock *bp; + buffblock_T *bp; /* compute the total length of the string */ for (bp = buffer->bh_first.b_next; bp != NULL; bp = bp->b_next) @@ -230,11 +231,11 @@ get_inserted() */ static void add_buff(buf, s, slen) - struct buffheader *buf; + buffheader_T *buf; char_u *s; long slen; /* length of "s" or -1 */ { - struct buffblock *p; + buffblock_T *p; long_u len; if (slen < 0) @@ -270,7 +271,7 @@ add_buff(buf, s, slen) len = MINIMAL_SIZE; else len = slen; - p = (struct buffblock *)lalloc((long_u)(sizeof(struct buffblock) + len), + p = (buffblock_T *)lalloc((long_u)(sizeof(buffblock_T) + len), TRUE); if (p == NULL) return; /* no space, just forget it */ @@ -289,7 +290,7 @@ add_buff(buf, s, slen) */ static void add_num_buff(buf, n) - struct buffheader *buf; + buffheader_T *buf; long n; { char_u number[32]; @@ -304,7 +305,7 @@ add_num_buff(buf, n) */ static void add_char_buff(buf, c) - struct buffheader *buf; + buffheader_T *buf; int c; { #ifdef FEAT_MBYTE @@ -354,46 +355,71 @@ add_char_buff(buf, c) #endif } +/* First read ahead buffer. Used for translated commands. */ +static buffheader_T readbuf1 = {{NULL, {NUL}}, NULL, 0, 0}; + +/* Second read ahead buffer. Used for redo. */ +static buffheader_T readbuf2 = {{NULL, {NUL}}, NULL, 0, 0}; + /* - * Get one byte from the stuff buffer. + * Get one byte from the read buffers. Use readbuf1 one first, use readbuf2 + * if that one is empty. * If advance == TRUE go to the next char. * No translation is done K_SPECIAL and CSI are escaped. */ static int -read_stuff(advance) +read_readbuffers(advance) int advance; { - char_u c; - struct buffblock *curr; - - if (stuffbuff.bh_first.b_next == NULL) /* buffer is empty */ + int c; + + c = read_readbuf(&readbuf1, advance); + if (c == NUL) + c = read_readbuf(&readbuf2, advance); + return c; +} + + static int +read_readbuf(buf, advance) + buffheader_T *buf; + int advance; +{ + char_u c; + buffblock_T *curr; + + if (buf->bh_first.b_next == NULL) /* buffer is empty */ return NUL; - curr = stuffbuff.bh_first.b_next; - c = curr->b_str[stuffbuff.bh_index]; + curr = buf->bh_first.b_next; + c = curr->b_str[buf->bh_index]; if (advance) { - if (curr->b_str[++stuffbuff.bh_index] == NUL) + if (curr->b_str[++buf->bh_index] == NUL) { - stuffbuff.bh_first.b_next = curr->b_next; + buf->bh_first.b_next = curr->b_next; vim_free(curr); - stuffbuff.bh_index = 0; + buf->bh_index = 0; } } return c; } /* - * Prepare the stuff buffer for reading (if it contains something). + * Prepare the read buffers for reading (if they contains something). */ static void start_stuff() { - if (stuffbuff.bh_first.b_next != NULL) + if (readbuf1.bh_first.b_next != NULL) { - stuffbuff.bh_curr = &(stuffbuff.bh_first); - stuffbuff.bh_space = 0; + readbuf1.bh_curr = &(readbuf1.bh_first); + readbuf1.bh_space = 0; + } + if (readbuf2.bh_first.b_next != NULL) + { + readbuf2.bh_curr = &(readbuf2.bh_first); + readbuf2.bh_space = 0; } } @@ -403,7 +429,18 @@ start_stuff() int stuff_empty() { - return (stuffbuff.bh_first.b_next == NULL); + return (readbuf1.bh_first.b_next == NULL + && readbuf2.bh_first.b_next == NULL); +} + +/* + * Return TRUE if readbuf1 is empty. There may still be redo characters in + * redbuf2. + */ + int +readbuf1_empty() +{ + return (readbuf1.bh_first.b_next == NULL); } /* @@ -428,7 +465,7 @@ flush_buffers(flush_typeahead) init_typebuf(); start_stuff(); - while (read_stuff(TRUE) != NUL) + while (read_readbuffers(TRUE) != NUL) ; if (flush_typeahead) /* remove all typeahead */ @@ -483,7 +520,7 @@ CancelRedo() redobuff = old_redobuff; old_redobuff.bh_first.b_next = NULL; start_stuff(); - while (read_stuff(TRUE) != NUL) + while (read_readbuffers(TRUE) != NUL) ; } } @@ -638,7 +675,7 @@ AppendNumberToRedobuff(n) stuffReadbuff(s) char_u *s; { - add_buff(&stuffbuff, s, -1L); + add_buff(&readbuf1, s, -1L); } void @@ -646,7 +683,7 @@ stuffReadbuffLen(s, len) char_u *s; long len; { - add_buff(&stuffbuff, s, len); + add_buff(&readbuf1, s, len); } #if defined(FEAT_EVAL) || defined(PROTO) @@ -692,7 +729,7 @@ stuffReadbuffSpec(s) stuffcharReadbuff(c) int c; { - add_char_buff(&stuffbuff, c); + add_char_buff(&readbuf1, c); } /* @@ -702,7 +739,7 @@ stuffcharReadbuff(c) stuffnumReadbuff(n) long n; { - add_num_buff(&stuffbuff, n); + add_num_buff(&readbuf1, n); } /* @@ -718,13 +755,13 @@ read_redo(init, old_redo) int init; int old_redo; { - static struct buffblock *bp; - static char_u *p; - int c; + static buffblock_T *bp; + static char_u *p; + int c; #ifdef FEAT_MBYTE - int n; - char_u buf[MB_MAXBYTES + 1]; - int i; + int n; + char_u buf[MB_MAXBYTES + 1]; + int i; #endif if (init) @@ -795,11 +832,11 @@ copy_redo(old_redo) int c; while ((c = read_redo(FALSE, old_redo)) != NUL) - stuffcharReadbuff(c); + add_char_buff(&readbuf2, c); } /* - * Stuff the redo buffer into the stuffbuff. + * Stuff the redo buffer into readbuf2. * Insert the redo count into the command. * If "old_redo" is TRUE, the last but one command is repeated * instead of the last command (inserting text). This is used for @@ -823,13 +860,13 @@ start_redo(count, old_redo) /* copy the buffer name, if present */ if (c == '"') { - add_buff(&stuffbuff, (char_u *)"\"", 1L); + add_buff(&readbuf2, (char_u *)"\"", 1L); c = read_redo(FALSE, old_redo); /* if a numbered buffer is used, increment the number */ if (c >= '1' && c < '9') ++c; - add_char_buff(&stuffbuff, c); + add_char_buff(&readbuf2, c); c = read_redo(FALSE, old_redo); } @@ -850,18 +887,18 @@ start_redo(count, old_redo) { while (VIM_ISDIGIT(c)) /* skip "old" count */ c = read_redo(FALSE, old_redo); - add_num_buff(&stuffbuff, count); + add_num_buff(&readbuf2, count); } /* copy from the redo buffer into the stuff buffer */ - add_char_buff(&stuffbuff, c); + add_char_buff(&readbuf2, c); copy_redo(old_redo); return OK; } /* * Repeat the last insert (R, o, O, a, A, i or I command) by stuffing - * the redo buffer into the stuffbuff. + * the redo buffer into readbuf2. * return FAIL for failure, OK otherwise */ int @@ -879,7 +916,7 @@ start_redo_ins() if (vim_strchr((char_u *)"AaIiRrOo", c) != NULL) { if (c == 'O' || c == 'o') - stuffReadbuff(NL_STR); + add_buff(&readbuf2, NL_STR, -1L); break; } } @@ -1360,8 +1397,10 @@ save_typeahead(tp) tp->old_mod_mask = old_mod_mask; old_char = -1; - tp->save_stuffbuff = stuffbuff; - stuffbuff.bh_first.b_next = NULL; + tp->save_readbuf1 = readbuf1; + readbuf1.bh_first.b_next = NULL; + tp->save_readbuf2 = readbuf2; + readbuf2.bh_first.b_next = NULL; # ifdef USE_INPUT_BUF tp->save_inputbuf = get_input_buf(); # endif @@ -1384,8 +1423,10 @@ restore_typeahead(tp) old_char = tp->old_char; old_mod_mask = tp->old_mod_mask; - free_buff(&stuffbuff); - stuffbuff = tp->save_stuffbuff; + free_buff(&readbuf1); + readbuf1 = tp->save_readbuf1; + free_buff(&readbuf2); + readbuf2 = tp->save_readbuf2; # ifdef USE_INPUT_BUF set_input_buf(tp->save_inputbuf); # endif @@ -1992,7 +2033,7 @@ vgetorpeek(advance) typeahead_char = 0; } else - c = read_stuff(advance); + c = read_readbuffers(advance); if (c != NUL && !got_int) { if (advance) diff --git a/src/globals.h b/src/globals.h --- a/src/globals.h +++ b/src/globals.h @@ -979,11 +979,6 @@ EXTERN int RedrawingDisabled INIT(= 0); EXTERN int readonlymode INIT(= FALSE); /* Set to TRUE for "view" */ EXTERN int recoverymode INIT(= FALSE); /* Set to TRUE for "-r" option */ -EXTERN struct buffheader stuffbuff /* stuff buffer */ -#ifdef DO_INIT - = {{NULL, {NUL}}, NULL, 0, 0} -#endif - ; EXTERN typebuf_T typebuf /* typeahead buffer */ #ifdef DO_INIT = {NULL, NULL, 0, 0, 0, 0, 0, 0, 0} diff --git a/src/normal.c b/src/normal.c --- a/src/normal.c +++ b/src/normal.c @@ -655,8 +655,8 @@ normal_cmd(oap, toplevel) #ifdef FEAT_EVAL /* Set v:count here, when called from main() and not a stuffed * command, so that v:count can be used in an expression mapping - * when there is no count. */ - if (toplevel && stuff_empty()) + * when there is no count. Do set it for redo. */ + if (toplevel && readbuf1_empty()) set_vcount_ca(&ca, &set_prevcount); #endif @@ -736,8 +736,8 @@ getcount: #ifdef FEAT_EVAL /* Set v:count here, when called from main() and not a stuffed * command, so that v:count can be used in an expression mapping - * right after the count. */ - if (toplevel && stuff_empty()) + * right after the count. Do set it for redo. */ + if (toplevel && readbuf1_empty()) set_vcount_ca(&ca, &set_prevcount); #endif if (ctrl_w) @@ -819,8 +819,9 @@ getcount: #ifdef FEAT_EVAL /* * Only set v:count when called from main() and not a stuffed command. + * Do set it for redo. */ - if (toplevel && stuff_empty()) + if (toplevel && readbuf1_empty()) set_vcount(ca.count0, ca.count1, set_prevcount); #endif diff --git a/src/proto/getchar.pro b/src/proto/getchar.pro --- a/src/proto/getchar.pro +++ b/src/proto/getchar.pro @@ -1,8 +1,9 @@ /* getchar.c */ -void free_buff __ARGS((struct buffheader *buf)); +void free_buff __ARGS((buffheader_T *buf)); char_u *get_recorded __ARGS((void)); char_u *get_inserted __ARGS((void)); int stuff_empty __ARGS((void)); +int readbuf1_empty __ARGS((void)); void typeahead_noflush __ARGS((int c)); void flush_buffers __ARGS((int flush_typeahead)); void ResetRedobuff __ARGS((void)); diff --git a/src/structs.h b/src/structs.h --- a/src/structs.h +++ b/src/structs.h @@ -471,13 +471,17 @@ struct nr_trans blocknr_T nt_new_bnum; /* new, positive, number */ }; + +typedef struct buffblock buffblock_T; +typedef struct buffheader buffheader_T; + /* * structure used to store one block of the stuff/redo/recording buffers */ struct buffblock { - struct buffblock *b_next; /* pointer to next buffblock */ - char_u b_str[1]; /* contents (actually longer) */ + buffblock_T *b_next; /* pointer to next buffblock */ + char_u b_str[1]; /* contents (actually longer) */ }; /* @@ -485,10 +489,10 @@ struct buffblock */ struct buffheader { - struct buffblock bh_first; /* first (dummy) block of list */ - struct buffblock *bh_curr; /* buffblock for appending */ - int bh_index; /* index for reading */ - int bh_space; /* space in bh_curr for appending */ + buffblock_T bh_first; /* first (dummy) block of list */ + buffblock_T *bh_curr; /* buffblock for appending */ + int bh_index; /* index for reading */ + int bh_space; /* space in bh_curr for appending */ }; /* @@ -964,7 +968,8 @@ typedef struct int typebuf_valid; /* TRUE when save_typebuf valid */ int old_char; int old_mod_mask; - struct buffheader save_stuffbuff; + buffheader_T save_readbuf1; + buffheader_T save_readbuf2; #ifdef USE_INPUT_BUF char_u *save_inputbuf; #endif diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -739,6 +739,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 171, +/**/ 170, /**/ 169,