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