changeset 5649:beb037a6c270 v7.4.171

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.
author Bram Moolenaar <bram@vim.org>
date Tue, 11 Feb 2014 15:10:43 +0100
parents e2140f8c3b20
children 5b8873427318
files src/getchar.c src/globals.h src/normal.c src/proto/getchar.pro src/structs.h src/version.c
diffstat 6 files changed, 123 insertions(+), 78 deletions(-) [+]
line wrap: on
line diff
--- 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)
--- 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}
--- 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
 
--- 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));
--- 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
--- 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,