diff --git a/7.4.171 b/7.4.171 new file mode 100644 index 0000000..cfd3906 --- /dev/null +++ b/7.4.171 @@ -0,0 +1,841 @@ +To: vim_dev@googlegroups.com +Subject: Patch 7.4.171 +Fcc: outbox +From: Bram Moolenaar +Mime-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit +------------ + +Patch 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. +Files: src/getchar.c, src/globals.h, src/normal.c, src/proto/getchar.pro, + src/structs.h + + +*** ../vim-7.4.170/src/getchar.c 2013-06-29 13:43:27.000000000 +0200 +--- src/getchar.c 2014-02-11 14:54:46.830097259 +0100 +*************** +*** 40,52 **** + + #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}; + #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}; + #endif +! static struct buffheader recordbuff = {{NULL, {NUL}}, NULL, 0, 0}; + + static int typeahead_char = 0; /* typeahead char that's not flushed */ + +--- 40,52 ---- + + #define MINIMAL_SIZE 20 /* minimal size for b_str */ + +! 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 buffheader_T save_redobuff = {{NULL, {NUL}}, NULL, 0, 0}; +! static buffheader_T save_old_redobuff = {{NULL, {NUL}}, NULL, 0, 0}; + #endif +! static buffheader_T recordbuff = {{NULL, {NUL}}, NULL, 0, 0}; + + static int typeahead_char = 0; /* typeahead char that's not flushed */ + +*************** +*** 112,122 **** + + 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 void start_stuff __ARGS((void)); + static int read_redo __ARGS((int, int)); + static void copy_redo __ARGS((int)); +--- 112,123 ---- + + static int last_recorded_len = 0; /* number of last recorded chars */ + +! 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,145 **** + */ + void + free_buff(buf) +! struct buffheader *buf; + { +! struct buffblock *p, *np; + + for (p = buf->bh_first.b_next; p != NULL; p = np) + { +--- 138,146 ---- + */ + void + free_buff(buf) +! buffheader_T *buf; + { +! buffblock_T *p, *np; + + for (p = buf->bh_first.b_next; p != NULL; p = np) + { +*************** +*** 155,168 **** + */ + static char_u * + get_buffcont(buffer, dozero) +! struct buffheader *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; + + /* compute the total length of the string */ + for (bp = buffer->bh_first.b_next; bp != NULL; bp = bp->b_next) +--- 156,169 ---- + */ + static char_u * + get_buffcont(buffer, dozero) +! 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; +! buffblock_T *bp; + + /* compute the total length of the string */ + for (bp = buffer->bh_first.b_next; bp != NULL; bp = bp->b_next) +*************** +*** 230,240 **** + */ + static void + add_buff(buf, s, slen) +! struct buffheader *buf; + char_u *s; + long slen; /* length of "s" or -1 */ + { +! struct buffblock *p; + long_u len; + + if (slen < 0) +--- 231,241 ---- + */ + static void + add_buff(buf, s, slen) +! buffheader_T *buf; + char_u *s; + long slen; /* length of "s" or -1 */ + { +! buffblock_T *p; + long_u len; + + if (slen < 0) +*************** +*** 270,276 **** + len = MINIMAL_SIZE; + else + len = slen; +! p = (struct buffblock *)lalloc((long_u)(sizeof(struct buffblock) + len), + TRUE); + if (p == NULL) + return; /* no space, just forget it */ +--- 271,277 ---- + len = MINIMAL_SIZE; + else + len = slen; +! p = (buffblock_T *)lalloc((long_u)(sizeof(buffblock_T) + len), + TRUE); + if (p == NULL) + return; /* no space, just forget it */ +*************** +*** 289,295 **** + */ + static void + add_num_buff(buf, n) +! struct buffheader *buf; + long n; + { + char_u number[32]; +--- 290,296 ---- + */ + static void + add_num_buff(buf, n) +! buffheader_T *buf; + long n; + { + char_u number[32]; +*************** +*** 304,310 **** + */ + static void + add_char_buff(buf, c) +! struct buffheader *buf; + int c; + { + #ifdef FEAT_MBYTE +--- 305,311 ---- + */ + static void + add_char_buff(buf, c) +! buffheader_T *buf; + int c; + { + #ifdef FEAT_MBYTE +*************** +*** 354,399 **** + #endif + } + + /* +! * Get one byte from the stuff buffer. + * If advance == TRUE go to the next char. + * No translation is done K_SPECIAL and CSI are escaped. + */ + static int +! read_stuff(advance) + int advance; + { +! char_u c; +! struct buffblock *curr; + +! if (stuffbuff.bh_first.b_next == NULL) /* buffer is empty */ + return NUL; + +! curr = stuffbuff.bh_first.b_next; +! c = curr->b_str[stuffbuff.bh_index]; + + if (advance) + { +! if (curr->b_str[++stuffbuff.bh_index] == NUL) + { +! stuffbuff.bh_first.b_next = curr->b_next; + vim_free(curr); +! stuffbuff.bh_index = 0; + } + } + return c; + } + + /* +! * Prepare the stuff buffer for reading (if it contains something). + */ + static void + start_stuff() + { +! if (stuffbuff.bh_first.b_next != NULL) + { +! stuffbuff.bh_curr = &(stuffbuff.bh_first); +! stuffbuff.bh_space = 0; + } + } + +--- 355,425 ---- + #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 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_readbuffers(advance) + int advance; + { +! 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 = buf->bh_first.b_next; +! c = curr->b_str[buf->bh_index]; + + if (advance) + { +! if (curr->b_str[++buf->bh_index] == NUL) + { +! buf->bh_first.b_next = curr->b_next; + vim_free(curr); +! buf->bh_index = 0; + } + } + return c; + } + + /* +! * Prepare the read buffers for reading (if they contains something). + */ + static void + start_stuff() + { +! if (readbuf1.bh_first.b_next != NULL) + { +! 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,409 **** + int + stuff_empty() + { +! return (stuffbuff.bh_first.b_next == NULL); + } + + /* +--- 429,446 ---- + int + stuff_empty() + { +! 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,434 **** + init_typebuf(); + + start_stuff(); +! while (read_stuff(TRUE) != NUL) + ; + + if (flush_typeahead) /* remove all typeahead */ +--- 465,471 ---- + init_typebuf(); + + start_stuff(); +! while (read_readbuffers(TRUE) != NUL) + ; + + if (flush_typeahead) /* remove all typeahead */ +*************** +*** 483,489 **** + redobuff = old_redobuff; + old_redobuff.bh_first.b_next = NULL; + start_stuff(); +! while (read_stuff(TRUE) != NUL) + ; + } + } +--- 520,526 ---- + redobuff = old_redobuff; + old_redobuff.bh_first.b_next = NULL; + start_stuff(); +! while (read_readbuffers(TRUE) != NUL) + ; + } + } +*************** +*** 638,644 **** + stuffReadbuff(s) + char_u *s; + { +! add_buff(&stuffbuff, s, -1L); + } + + void +--- 675,681 ---- + stuffReadbuff(s) + char_u *s; + { +! add_buff(&readbuf1, s, -1L); + } + + void +*************** +*** 646,652 **** + char_u *s; + long len; + { +! add_buff(&stuffbuff, s, len); + } + + #if defined(FEAT_EVAL) || defined(PROTO) +--- 683,689 ---- + char_u *s; + long len; + { +! add_buff(&readbuf1, s, len); + } + + #if defined(FEAT_EVAL) || defined(PROTO) +*************** +*** 692,698 **** + stuffcharReadbuff(c) + int c; + { +! add_char_buff(&stuffbuff, c); + } + + /* +--- 729,735 ---- + stuffcharReadbuff(c) + int c; + { +! add_char_buff(&readbuf1, c); + } + + /* +*************** +*** 702,708 **** + stuffnumReadbuff(n) + long n; + { +! add_num_buff(&stuffbuff, n); + } + + /* +--- 739,745 ---- + stuffnumReadbuff(n) + long n; + { +! add_num_buff(&readbuf1, n); + } + + /* +*************** +*** 718,730 **** + int init; + int old_redo; + { +! static struct buffblock *bp; +! static char_u *p; +! int c; + #ifdef FEAT_MBYTE +! int n; +! char_u buf[MB_MAXBYTES + 1]; +! int i; + #endif + + if (init) +--- 755,767 ---- + int init; + int old_redo; + { +! static buffblock_T *bp; +! static char_u *p; +! int c; + #ifdef FEAT_MBYTE +! int n; +! char_u buf[MB_MAXBYTES + 1]; +! int i; + #endif + + if (init) +*************** +*** 795,805 **** + int c; + + while ((c = read_redo(FALSE, old_redo)) != NUL) +! stuffcharReadbuff(c); + } + + /* +! * Stuff the redo buffer into the stuffbuff. + * 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 +--- 832,842 ---- + int c; + + while ((c = read_redo(FALSE, old_redo)) != NUL) +! add_char_buff(&readbuf2, c); + } + + /* +! * 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,835 **** + /* copy the buffer name, if present */ + if (c == '"') + { +! add_buff(&stuffbuff, (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); + c = read_redo(FALSE, old_redo); + } + +--- 860,872 ---- + /* copy the buffer name, if present */ + if (c == '"') + { +! 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(&readbuf2, c); + c = read_redo(FALSE, old_redo); + } + +*************** +*** 850,867 **** + { + while (VIM_ISDIGIT(c)) /* skip "old" count */ + c = read_redo(FALSE, old_redo); +! add_num_buff(&stuffbuff, count); + } + + /* copy from the redo buffer into the stuff buffer */ +! add_char_buff(&stuffbuff, 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. + * return FAIL for failure, OK otherwise + */ + int +--- 887,904 ---- + { + while (VIM_ISDIGIT(c)) /* skip "old" count */ + c = read_redo(FALSE, old_redo); +! add_num_buff(&readbuf2, count); + } + + /* copy from the redo buffer into the stuff buffer */ +! 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 readbuf2. + * return FAIL for failure, OK otherwise + */ + int +*************** +*** 879,885 **** + if (vim_strchr((char_u *)"AaIiRrOo", c) != NULL) + { + if (c == 'O' || c == 'o') +! stuffReadbuff(NL_STR); + break; + } + } +--- 916,922 ---- + if (vim_strchr((char_u *)"AaIiRrOo", c) != NULL) + { + if (c == 'O' || c == 'o') +! add_buff(&readbuf2, NL_STR, -1L); + break; + } + } +*************** +*** 1360,1367 **** + tp->old_mod_mask = old_mod_mask; + old_char = -1; + +! tp->save_stuffbuff = stuffbuff; +! stuffbuff.bh_first.b_next = NULL; + # ifdef USE_INPUT_BUF + tp->save_inputbuf = get_input_buf(); + # endif +--- 1397,1406 ---- + tp->old_mod_mask = old_mod_mask; + old_char = -1; + +! 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,1391 **** + old_char = tp->old_char; + old_mod_mask = tp->old_mod_mask; + +! free_buff(&stuffbuff); +! stuffbuff = tp->save_stuffbuff; + # ifdef USE_INPUT_BUF + set_input_buf(tp->save_inputbuf); + # endif +--- 1423,1432 ---- + old_char = tp->old_char; + old_mod_mask = tp->old_mod_mask; + +! 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,1998 **** + typeahead_char = 0; + } + else +! c = read_stuff(advance); + if (c != NUL && !got_int) + { + if (advance) +--- 2033,2039 ---- + typeahead_char = 0; + } + else +! c = read_readbuffers(advance); + if (c != NUL && !got_int) + { + if (advance) +*** ../vim-7.4.170/src/globals.h 2013-11-09 03:31:45.000000000 +0100 +--- src/globals.h 2014-02-11 14:17:44.070063200 +0100 +*************** +*** 979,989 **** + 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} +--- 979,984 ---- +*** ../vim-7.4.170/src/normal.c 2014-01-14 13:18:53.000000000 +0100 +--- src/normal.c 2014-02-11 14:53:54.246096453 +0100 +*************** +*** 655,662 **** + #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()) + set_vcount_ca(&ca, &set_prevcount); + #endif + +--- 655,662 ---- + #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. Do set it for redo. */ +! if (toplevel && readbuf1_empty()) + set_vcount_ca(&ca, &set_prevcount); + #endif + +*************** +*** 736,743 **** + #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()) + set_vcount_ca(&ca, &set_prevcount); + #endif + if (ctrl_w) +--- 736,743 ---- + #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. Do set it for redo. */ +! if (toplevel && readbuf1_empty()) + set_vcount_ca(&ca, &set_prevcount); + #endif + if (ctrl_w) +*************** +*** 819,826 **** + #ifdef FEAT_EVAL + /* + * Only set v:count when called from main() and not a stuffed command. + */ +! if (toplevel && stuff_empty()) + set_vcount(ca.count0, ca.count1, set_prevcount); + #endif + +--- 819,827 ---- + #ifdef FEAT_EVAL + /* + * Only set v:count when called from main() and not a stuffed command. ++ * Do set it for redo. + */ +! if (toplevel && readbuf1_empty()) + set_vcount(ca.count0, ca.count1, set_prevcount); + #endif + +*** ../vim-7.4.170/src/proto/getchar.pro 2013-08-10 13:37:12.000000000 +0200 +--- src/proto/getchar.pro 2014-02-11 14:55:14.806097687 +0100 +*************** +*** 1,8 **** + /* getchar.c */ +! void free_buff __ARGS((struct buffheader *buf)); + char_u *get_recorded __ARGS((void)); + char_u *get_inserted __ARGS((void)); + int stuff_empty __ARGS((void)); + void typeahead_noflush __ARGS((int c)); + void flush_buffers __ARGS((int flush_typeahead)); + void ResetRedobuff __ARGS((void)); +--- 1,9 ---- + /* getchar.c */ +! 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)); +*** ../vim-7.4.170/src/structs.h 2013-11-12 04:43:57.000000000 +0100 +--- src/structs.h 2014-02-11 14:35:43.606079741 +0100 +*************** +*** 471,483 **** + blocknr_T nt_new_bnum; /* new, positive, number */ + }; + + /* + * 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) */ + }; + + /* +--- 471,487 ---- + 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 + { +! buffblock_T *b_next; /* pointer to next buffblock */ +! char_u b_str[1]; /* contents (actually longer) */ + }; + + /* +*************** +*** 485,494 **** + */ + 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 */ + }; + + /* +--- 489,498 ---- + */ + struct buffheader + { +! 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,970 **** + int typebuf_valid; /* TRUE when save_typebuf valid */ + int old_char; + int old_mod_mask; +! struct buffheader save_stuffbuff; + #ifdef USE_INPUT_BUF + char_u *save_inputbuf; + #endif +--- 968,975 ---- + int typebuf_valid; /* TRUE when save_typebuf valid */ + int old_char; + int old_mod_mask; +! buffheader_T save_readbuf1; +! buffheader_T save_readbuf2; + #ifdef USE_INPUT_BUF + char_u *save_inputbuf; + #endif +*** ../vim-7.4.170/src/version.c 2014-02-11 12:15:39.781950970 +0100 +--- src/version.c 2014-02-11 15:05:17.306106920 +0100 +*************** +*** 740,741 **** +--- 740,743 ---- + { /* Add new patch number below this line */ ++ /**/ ++ 171, + /**/ + +-- +Linux is just like a wigwam: no Windows, no Gates and an Apache inside. + + /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ +/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ +\\\ an exciting new programming language -- http://www.Zimbu.org /// + \\\ help me help AIDS victims -- http://ICCF-Holland.org ///