The "first buffer" and not the "first buffer that is not deleted" was being 
used when processing :bufdo.

new_ex_bufdo_function.diff: bufdo specific code was moved out of ex_listdo() 
into a new function ex_bufdo(). I made the change so I could more easily 
understand how bufdo is processed. (Much of the diff is due to increasing 
indentation level of some code. The diff looks *much* nicer when ignoring 
whitespace changes.)

bufdo_skip_deleted_buffer.diff: bug fix including updated test case. (Apply 
after new_ex_bufdo_function.diff.)

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.
diff -r b64f0df9399c -r f0640998ecf6 src/ex_cmds2.c
--- a/src/ex_cmds2.c	Tue Feb 17 17:50:26 2015 +0100
+++ b/src/ex_cmds2.c	Wed Feb 18 14:08:52 2015 +1100
@@ -2429,6 +2429,60 @@
 }
 
 /*
+ * ":bufdo"
+ */
+    static void
+ex_bufdo(eap)
+    exarg_T	*eap;
+{
+    buf_T	*buf;
+    int		next_fnum = 0;
+    char_u	*p_shm_save;
+
+    goto_buffer(eap, DOBUF_FIRST, FORWARD, eap->line1);
+
+    listcmd_busy = TRUE;
+
+    while (!got_int)
+    {
+	/* Remember the number of the next listed buffer, in case
+	    * ":bwipe" is used or autocommands do something strange. */
+	next_fnum = -1;
+	for (buf = curbuf->b_next; buf != NULL; buf = buf->b_next)
+	    if (buf->b_p_bl)
+	    {
+		next_fnum = buf->b_fnum;
+		break;
+	    }
+
+	do_cmdline(eap->arg, eap->getline, eap->cookie,
+					    DOCMD_VERBOSE + DOCMD_NOWAIT);
+
+	if (next_fnum < 0 || next_fnum > eap->line2)
+	    break;
+	/* Check if the buffer still exists. */
+	for (buf = firstbuf; buf != NULL; buf = buf->b_next)
+	    if (buf->b_fnum == next_fnum)
+		break;
+	if (buf == NULL)
+	    break;
+
+	/* Go to the next buffer.  Clear 'shm' to avoid that the file
+	    * message overwrites any output from the command. */
+	p_shm_save = vim_strsave(p_shm);
+	set_option_value((char_u *)"shm", 0L, (char_u *)"", 0);
+	goto_buffer(eap, DOBUF_FIRST, FORWARD, next_fnum);
+	set_option_value((char_u *)"shm", 0L, p_shm_save, 0);
+	vim_free(p_shm_save);
+
+	/* If autocommands took us elsewhere, quit here */
+	if (curbuf->b_fnum != next_fnum)
+	    break;
+    }
+    listcmd_busy = FALSE;
+}
+
+/*
  * ":argdo", ":windo", ":bufdo", ":tabdo"
  */
     void
@@ -2440,8 +2494,6 @@
     win_T	*wp;
     tabpage_T	*tp;
 #endif
-    buf_T	*buf;
-    int		next_fnum = 0;
 #if defined(FEAT_AUTOCMD) && defined(FEAT_SYN_HL)
     char_u	*save_ei = NULL;
 #endif
@@ -2472,145 +2524,107 @@
 				    | (eap->forceit ? CCGD_FORCEIT : 0)
 				    | CCGD_EXCMD))
     {
-	i = 0;
-	/* start at the eap->line1 argument/window/buffer */
+	if (eap->cmdidx == CMD_bufdo)
+	    ex_bufdo(eap);
+	else
+	{
+	    i = 0;
+	    /* start at the eap->line1 argument/window/buffer */
 #ifdef FEAT_WINDOWS
-	wp = firstwin;
-	tp = first_tabpage;
+	    wp = firstwin;
+	    tp = first_tabpage;
 #endif
-	switch (eap->cmdidx)
-	{
+	    switch (eap->cmdidx)
+	    {
 #ifdef FEAT_WINDOWS
-	    case CMD_windo:
-		for ( ; wp != NULL && i + 1 < eap->line1; wp = wp->w_next)
-		    i++;
-		break;
-	    case CMD_tabdo:
-		for( ; tp != NULL && i + 1 < eap->line1; tp = tp->tp_next)
-		    i++;
-		break;
+		case CMD_windo:
+		    for ( ; wp != NULL && i + 1 < eap->line1; wp = wp->w_next)
+			i++;
+		    break;
+		case CMD_tabdo:
+		    for( ; tp != NULL && i + 1 < eap->line1; tp = tp->tp_next)
+			i++;
+		    break;
 #endif
-	    case CMD_argdo:
-		i = eap->line1 - 1;
-		break;
-	    case CMD_bufdo:
-		i = eap->line1;
-		break;
-	    default:
-		break;
-	}
-	/* set pcmark now */
-	if (eap->cmdidx == CMD_bufdo)
-	    goto_buffer(eap, DOBUF_FIRST, FORWARD, i);
-	else
-	    setpcmark();
-	listcmd_busy = TRUE;	    /* avoids setting pcmark below */
-
-	while (!got_int)
-	{
-	    if (eap->cmdidx == CMD_argdo)
-	    {
-		/* go to argument "i" */
-		if (i == ARGCOUNT)
+		case CMD_argdo:
+		    i = eap->line1 - 1;
 		    break;
-		/* Don't call do_argfile() when already there, it will try
-		 * reloading the file. */
-		if (curwin->w_arg_idx != i || !editing_arg_idx(curwin))
-		{
-		    /* Clear 'shm' to avoid that the file message overwrites
-		     * any output from the command. */
-		    p_shm_save = vim_strsave(p_shm);
-		    set_option_value((char_u *)"shm", 0L, (char_u *)"", 0);
-		    do_argfile(eap, i);
-		    set_option_value((char_u *)"shm", 0L, p_shm_save, 0);
-		    vim_free(p_shm_save);
-		}
-		if (curwin->w_arg_idx != i)
+		default:
 		    break;
 	    }
+	    /* set pcmark now */
+	    setpcmark();
+	    listcmd_busy = TRUE;	    /* avoids setting pcmark below */
+
+	    while (!got_int)
+	    {
+		if (eap->cmdidx == CMD_argdo)
+		{
+		    /* go to argument "i" */
+		    if (i == ARGCOUNT)
+			break;
+		    /* Don't call do_argfile() when already there, it will try
+		    * reloading the file. */
+		    if (curwin->w_arg_idx != i || !editing_arg_idx(curwin))
+		    {
+			/* Clear 'shm' to avoid that the file message overwrites
+			* any output from the command. */
+			p_shm_save = vim_strsave(p_shm);
+			set_option_value((char_u *)"shm", 0L, (char_u *)"", 0);
+			do_argfile(eap, i);
+			set_option_value((char_u *)"shm", 0L, p_shm_save, 0);
+			vim_free(p_shm_save);
+		    }
+		    if (curwin->w_arg_idx != i)
+			break;
+		}
 #ifdef FEAT_WINDOWS
-	    else if (eap->cmdidx == CMD_windo)
-	    {
-		/* go to window "wp" */
-		if (!win_valid(wp))
-		    break;
-		win_goto(wp);
-		if (curwin != wp)
-		    break;  /* something must be wrong */
-		wp = curwin->w_next;
-	    }
-	    else if (eap->cmdidx == CMD_tabdo)
-	    {
-		/* go to window "tp" */
-		if (!valid_tabpage(tp))
-		    break;
-		goto_tabpage_tp(tp, TRUE, TRUE);
-		tp = tp->tp_next;
-	    }
+		else if (eap->cmdidx == CMD_windo)
+		{
+		    /* go to window "wp" */
+		    if (!win_valid(wp))
+			break;
+		    win_goto(wp);
+		    if (curwin != wp)
+			break;  /* something must be wrong */
+		    wp = curwin->w_next;
+		}
+		else if (eap->cmdidx == CMD_tabdo)
+		{
+		    /* go to window "tp" */
+		    if (!valid_tabpage(tp))
+			break;
+		    goto_tabpage_tp(tp, TRUE, TRUE);
+		    tp = tp->tp_next;
+		}
 #endif
-	    else if (eap->cmdidx == CMD_bufdo)
-	    {
-		/* Remember the number of the next listed buffer, in case
-		 * ":bwipe" is used or autocommands do something strange. */
-		next_fnum = -1;
-		for (buf = curbuf->b_next; buf != NULL; buf = buf->b_next)
-		    if (buf->b_p_bl)
-		    {
-			next_fnum = buf->b_fnum;
+
+		++i;
+
+		/* execute the command */
+		do_cmdline(eap->arg, eap->getline, eap->cookie,
+						    DOCMD_VERBOSE + DOCMD_NOWAIT);
+
+		if (eap->cmdidx == CMD_windo)
+		{
+		    validate_cursor();	/* cursor may have moved */
+#ifdef FEAT_SCROLLBIND
+		    /* required when 'scrollbind' has been set */
+		    if (curwin->w_p_scb)
+			do_check_scrollbind(TRUE);
+#endif
+		}
+
+#ifdef FEAT_WINDOWS
+		if (eap->cmdidx == CMD_windo || eap->cmdidx == CMD_tabdo)
+		    if (i+1 > eap->line2)
 			break;
-		    }
-	    }
-
-	    ++i;
-
-	    /* execute the command */
-	    do_cmdline(eap->arg, eap->getline, eap->cookie,
-						DOCMD_VERBOSE + DOCMD_NOWAIT);
-
-	    if (eap->cmdidx == CMD_bufdo)
-	    {
-		/* Done? */
-		if (next_fnum < 0 || next_fnum > eap->line2)
-		    break;
-		/* Check if the buffer still exists. */
-		for (buf = firstbuf; buf != NULL; buf = buf->b_next)
-		    if (buf->b_fnum == next_fnum)
-			break;
-		if (buf == NULL)
-		    break;
-
-		/* Go to the next buffer.  Clear 'shm' to avoid that the file
-		 * message overwrites any output from the command. */
-		p_shm_save = vim_strsave(p_shm);
-		set_option_value((char_u *)"shm", 0L, (char_u *)"", 0);
-		goto_buffer(eap, DOBUF_FIRST, FORWARD, next_fnum);
-		set_option_value((char_u *)"shm", 0L, p_shm_save, 0);
-		vim_free(p_shm_save);
-
-		/* If autocommands took us elsewhere, quit here */
-		if (curbuf->b_fnum != next_fnum)
+#endif
+		if (eap->cmdidx == CMD_argdo && i >= eap->line2)
 		    break;
 	    }
-
-	    if (eap->cmdidx == CMD_windo)
-	    {
-		validate_cursor();	/* cursor may have moved */
-#ifdef FEAT_SCROLLBIND
-		/* required when 'scrollbind' has been set */
-		if (curwin->w_p_scb)
-		    do_check_scrollbind(TRUE);
-#endif
-	    }
-
-#ifdef FEAT_WINDOWS
-	    if (eap->cmdidx == CMD_windo || eap->cmdidx == CMD_tabdo)
-		if (i+1 > eap->line2)
-		    break;
-#endif
-	    if (eap->cmdidx == CMD_argdo && i >= eap->line2)
-		break;
+	    listcmd_busy = FALSE;
 	}
-	listcmd_busy = FALSE;
     }
 
 #if defined(FEAT_AUTOCMD) && defined(FEAT_SYN_HL)
diff -r f0640998ecf6 src/ex_cmds2.c
--- a/src/ex_cmds2.c	Wed Feb 18 14:08:52 2015 +1100
+++ b/src/ex_cmds2.c	Wed Feb 18 14:14:06 2015 +1100
@@ -2439,7 +2439,11 @@
     int		next_fnum = 0;
     char_u	*p_shm_save;
 
-    goto_buffer(eap, DOBUF_FIRST, FORWARD, eap->line1);
+    for (buf = firstbuf; buf && (buf->b_fnum < eap->line1 || !buf->b_p_bl); buf = buf->b_next)
+	;
+    if (buf == NULL || buf->b_fnum > eap->line2)
+	return;
+    goto_buffer(eap, DOBUF_FIRST, FORWARD, buf->b_fnum);
 
     listcmd_busy = TRUE;
 
diff -r f0640998ecf6 src/testdir/test_command_count.in
--- a/src/testdir/test_command_count.in	Wed Feb 18 14:08:52 2015 +1100
+++ b/src/testdir/test_command_count.in	Wed Feb 18 14:14:06 2015 +1100
@@ -141,6 +141,7 @@
 :let buffers = ''
 :.,$-bufdo let buffers .= ' '.bufnr('%')
 :call add(g:lines, 'bufdo:' . buffers)
+:3bd
 :let buffers = ''
 :3,7bufdo let buffers .= ' '.bufnr('%')
 :call add(g:lines, 'bufdo:' . buffers)
diff -r f0640998ecf6 src/testdir/test_command_count.ok
--- a/src/testdir/test_command_count.ok	Wed Feb 18 14:08:52 2015 +1100
+++ b/src/testdir/test_command_count.ok	Wed Feb 18 14:14:06 2015 +1100
@@ -34,5 +34,5 @@
 argdo: c d e
 windo: 2 3 4
 bufdo: 2 3 4 5 6 7 8 9 10 15
-bufdo: 3 4 5 6 7
+bufdo: 4 5 6 7
 tabdo: 2 3 4

Raspunde prin e-mail lui