diff --git a/runtime/doc/editing.txt b/runtime/doc/editing.txt index f2daa9ec24..7c7628cd78 100644 --- a/runtime/doc/editing.txt +++ b/runtime/doc/editing.txt @@ -1,4 +1,4 @@ -*editing.txt* For Vim version 7.4. Last change: 2014 Jul 19 +*editing.txt* For Vim version 7.4. Last change: 2015 Apr 18 VIM REFERENCE MANUAL by Bram Moolenaar @@ -801,8 +801,9 @@ current window. The two windows then share this list, until one of them uses USING THE ARGUMENT LIST *:argdo* -:argdo[!] {cmd} Execute {cmd} for each file in the argument list. - It works like doing this: > +:[range]argdo[!] {cmd} Execute {cmd} for each file in the argument list or, + if [range] is specified, only for arguments in that + range. It works like doing this: > :rewind :{cmd} :next diff --git a/runtime/doc/tabpage.txt b/runtime/doc/tabpage.txt index 479c2cb455..bb0baf4ccf 100644 --- a/runtime/doc/tabpage.txt +++ b/runtime/doc/tabpage.txt @@ -1,4 +1,4 @@ -*tabpage.txt* For Vim version 7.4. Last change: 2012 Aug 08 +*tabpage.txt* For Vim version 7.4. Last change: 2015 Apr 18 VIM REFERENCE MANUAL by Bram Moolenaar @@ -222,8 +222,10 @@ clarification what +N means in this context see |[range]|. LOOPING OVER TAB PAGES: *:tabd* *:tabdo* -:tabd[o] {cmd} Execute {cmd} in each tab page. - It works like doing this: > +:[range]tabd[o] {cmd} + Execute {cmd} in each tab page or, if [range] is given, only + in tabpages which tab page number is in the [range]. It works + like doing this: > :tabfirst :{cmd} :tabnext diff --git a/runtime/doc/windows.txt b/runtime/doc/windows.txt index 0a1e114664..782349abe8 100644 --- a/runtime/doc/windows.txt +++ b/runtime/doc/windows.txt @@ -695,8 +695,9 @@ can also get to them with the buffer list commands, like ":bnext". 8. Do a command in all buffers or windows *list-repeat* *:windo* -:windo {cmd} Execute {cmd} in each window. - It works like doing this: > +:[range]windo {cmd} Execute {cmd} in each window or if [range] is given + only in windows for which the window number lies in + the [range]. It works like doing this: > CTRL-W t :{cmd} CTRL-W w @@ -714,8 +715,10 @@ can also get to them with the buffer list commands, like ":bnext". Also see |:tabdo|, |:argdo| and |:bufdo|. *:bufdo* -:bufdo[!] {cmd} Execute {cmd} in each buffer in the buffer list. - It works like doing this: > +:[range]bufdo[!] {cmd} Execute {cmd} in each buffer in the buffer list or if + [range[ is given only for buffers for which their + buffer name is in the [range]. It works like doing + this: > :bfirst :{cmd} :bnext diff --git a/src/nvim/ex_cmds.lua b/src/nvim/ex_cmds.lua index cfcd9d23ea..5cbe7a0ca5 100644 --- a/src/nvim/ex_cmds.lua +++ b/src/nvim/ex_cmds.lua @@ -99,8 +99,8 @@ return { }, { command='argdo', - flags=bit.bor(BANG, NEEDARG, EXTRA, NOTRLCOM), - addr_type=ADDR_LINES, + flags=bit.bor(BANG, NEEDARG, EXTRA, NOTRLCOM, RANGE, NOTADR, DFLALL), + addr_type=ADDR_ARGUMENTS, func='ex_listdo', }, { @@ -273,8 +273,8 @@ return { }, { command='bufdo', - flags=bit.bor(BANG, NEEDARG, EXTRA, NOTRLCOM), - addr_type=ADDR_LINES, + flags=bit.bor(BANG, NEEDARG, EXTRA, NOTRLCOM, RANGE, NOTADR, DFLALL), + addr_type=ADDR_BUFFERS, func='ex_listdo', }, { @@ -2583,8 +2583,8 @@ return { }, { command='tabdo', - flags=bit.bor(NEEDARG, EXTRA, NOTRLCOM), - addr_type=ADDR_LINES, + flags=bit.bor(NEEDARG, EXTRA, NOTRLCOM, RANGE, NOTADR, DFLALL), + addr_type=ADDR_TABS, func='ex_listdo', }, { @@ -2997,8 +2997,8 @@ return { }, { command='windo', - flags=bit.bor(BANG, NEEDARG, EXTRA, NOTRLCOM), - addr_type=ADDR_LINES, + flags=bit.bor(BANG, NEEDARG, EXTRA, NOTRLCOM, RANGE, NOTADR, DFLALL), + addr_type=ADDR_WINDOWS, func='ex_listdo', }, { diff --git a/src/nvim/ex_cmds2.c b/src/nvim/ex_cmds2.c index 98e6d87196..e453d68247 100644 --- a/src/nvim/ex_cmds2.c +++ b/src/nvim/ex_cmds2.c @@ -1844,13 +1844,33 @@ void ex_listdo(exarg_T *eap) || !check_changed(curbuf, CCGD_AW | (eap->forceit ? CCGD_FORCEIT : 0) | CCGD_EXCMD)) { - /* start at the first argument/window/buffer */ i = 0; + /* start at the eap->line1 argument/window/buffer */ wp = firstwin; tp = first_tabpage; + switch (eap->cmdidx) { + 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_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, 0); + goto_buffer(eap, DOBUF_FIRST, FORWARD, i); else setpcmark(); listcmd_busy = TRUE; /* avoids setting pcmark below */ @@ -1873,7 +1893,6 @@ void ex_listdo(exarg_T *eap) } if (curwin->w_arg_idx != i) break; - ++i; } else if (eap->cmdidx == CMD_windo) { /* go to window "wp" */ if (!win_valid(wp)) @@ -1899,13 +1918,14 @@ void ex_listdo(exarg_T *eap) } } + ++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) + if (next_fnum < 0 || next_fnum > eap->line2) break; /* Check if the buffer still exists. */ @@ -1939,6 +1959,14 @@ void ex_listdo(exarg_T *eap) if (curwin->w_p_scb) do_check_scrollbind(TRUE); } + if (eap->cmdidx == CMD_windo || eap->cmdidx == CMD_tabdo) { + if (i + 1 > eap->line2) { + break; + } + } + if (eap->cmdidx == CMD_argdo && i >= eap->line2) { + break; + } } listcmd_busy = FALSE; } diff --git a/src/nvim/testdir/test_command_count.in b/src/nvim/testdir/test_command_count.in index e7dadd2bed..16daad0b2d 100644 --- a/src/nvim/testdir/test_command_count.in +++ b/src/nvim/testdir/test_command_count.in @@ -90,6 +90,40 @@ STARTTEST :only! :e! test.out :call append(0, g:lines) +:unlet g:lines +:w|bd +:se hidden +:b1 +ENDTEST + +STARTTEST +:only! +:let g:lines = [] +:%argd +:arga a b c d e f +:3argu +:let args = '' +:.,$-argdo let args .= ' '.expand('%') +:call add(g:lines, 'argdo:' . args) +:split|split|split|split +:2wincmd w +:let windows = '' +:.,$-windo let windows .= ' '.winnr() +:call add(g:lines, 'windo:'. windows) +:b2 +:let buffers = '' +:.,$-bufdo let buffers .= ' '.bufnr('%') +:call add(g:lines, 'bufdo:' . buffers) +:let buffers = '' +:3,7bufdo let buffers .= ' '.bufnr('%') +:call add(g:lines, 'bufdo:' . buffers) +:tabe|tabe|tabe|tabe +:normal! 2gt +:let tabpages = '' +:.,$-tabdo let tabpages .= ' '.tabpagenr() +:call add(g:lines, 'tabdo:' . tabpages) +:e! test.out +:call append('$', g:lines) :w|qa! ENDTEST diff --git a/src/nvim/testdir/test_command_count.ok b/src/nvim/testdir/test_command_count.ok index 6e85f29d94..a936715b36 100644 --- a/src/nvim/testdir/test_command_count.ok +++ b/src/nvim/testdir/test_command_count.ok @@ -28,3 +28,8 @@ $tabe 2 $+tabe E16: Invalid range 0tabm x +argdo: c d e +windo: 2 3 4 +bufdo: 2 3 4 5 6 7 8 9 10 12 +bufdo: 3 4 5 6 7 +tabdo: 2 3 4 diff --git a/src/nvim/version.c b/src/nvim/version.c index 55db9da987..2d0c28b385 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -213,7 +213,7 @@ static int included_patches[] = { //569, //568, 567, - //566, + 566, 565, //564, 563,