Really happy to see those new commands being added! After updating Vim I tried :h :cdo, but no help was found. I checked my repository and indeed, the added documentation is nowhere to be found. As you can see in the commit on GitHub [1] there are no changes to runtime/doc/quickfix.txt. Looks like they got lost.
[1] https://github.com/vim/vim/commit/aa23b379421aa214e6543b06c974594a25799b09 Cheers, Christian On Tuesday, September 8, 2015 at 6:47:00 PM UTC+2, Bram Moolenaar wrote: > Patch 7.4.858 > Problem: It's a bit clumsy to execute a command on a list of matches. > Solution: Add the ":ldo", ":lfdo", ":cdo" and ":cfdo" commands. (Yegappan > Lakshmanan) > Files: runtime/doc/cmdline.txt, runtime/doc/editing.txt, > runtime/doc/index.txt, runtime/doc/quickfix.txt, > runtime/doc/tabpage.txt, runtime/doc/windows.txt, src/ex_cmds.h, > src/ex_cmds2.c, src/ex_docmd.c, src/proto/quickfix.pro, > src/quickfix.c, src/testdir/Make_amiga.mak, > src/testdir/Make_dos.mak, src/testdir/Make_ming.mak, > src/testdir/Make_os2.mak, src/testdir/Make_vms.mms, > src/testdir/Makefile, src/testdir/test_cdo.in, > src/testdir/test_cdo.ok > > > *** ../vim-7.4.857/runtime/doc/cmdline.txt 2014-02-23 23:38:58.812760280 > +0100 > --- runtime/doc/cmdline.txt 2015-09-08 18:07:42.256948348 +0200 > *************** > *** 511,516 **** > --- 511,518 ---- > :argdo > :autocmd > :bufdo > + :cdo > + :cfdo > :command > :cscope > :debug > *************** > *** 521,526 **** > --- 523,530 ---- > :help > :helpfind > :lcscope > + :ldo > + :lfdo > :make > :normal > :perl > *** ../vim-7.4.857/runtime/doc/editing.txt 2015-01-07 16:52:53.506792420 > +0100 > --- runtime/doc/editing.txt 2015-09-08 18:07:42.256948348 +0200 > *************** > *** 854,860 **** > each file. > {not in Vi} {not available when compiled without the > |+listcmds| feature} > ! Also see |:windo|, |:tabdo| and |:bufdo|. > > Example: > > :args *.c > --- 868,875 ---- > each file. > {not in Vi} {not available when compiled without the > |+listcmds| feature} > ! Also see |:windo|, |:tabdo|, |:bufdo|, |:cdo|, |:ldo|, > ! |:cfdo| and |:lfdo| > > Example: > > :args *.c > *** ../vim-7.4.857/runtime/doc/index.txt 2014-09-19 19:39:30.762446025 > +0200 > --- runtime/doc/index.txt 2015-09-08 18:10:53.402969644 +0200 > *************** > *** 1133,1138 **** > --- 1138,1145 ---- > |:cc| :cc go to specific error > |:cclose| :ccl[ose] close quickfix window > |:cd| :cd change directory > + |:cdo| :cdo execute command in each valid error > list entry > + |:cfdo| :cfd[o] execute command in each file in error > list > |:center| :ce[nter] format lines at the center > |:cexpr| :cex[pr] read errors from expr and jump to first > |:cfile| :cf[ile] read file with error messages and jump to first > *************** > *** 1290,1295 **** > --- 1298,1305 ---- > |:lchdir| :lch[dir] change directory locally > |:lclose| :lcl[ose] close location window > |:lcscope| :lcs[cope] like ":cscope" but uses location list > + |:ldo| :ld[o] execute command in valid location list > entries > + |:lfdo| :lfd[o] execute command in each file in > location list > |:left| :le[ft] left align lines > |:leftabove| :lefta[bove] make split window appear left or above > |:let| :let assign a value to a variable or option > *** ../vim-7.4.857/runtime/doc/quickfix.txt 2014-02-23 23:38:58.820760280 > +0100 > --- runtime/doc/quickfix.txt 2015-09-08 18:27:53.564412123 +0200 > *************** > *** 299,321 **** > au QuickfixCmdPost make call QfMakeConv() > > > > ============================================================================= > 2. The error window *quickfix-window* > > *:cope* *:copen* *w:quickfix_title* > :cope[n] [height] Open a window to show the current list of errors. > When [height] is given, the window becomes that high > ! (if there is room). Otherwise the window is made ten > ! lines high. > ! The window will contain a special buffer, with > ! 'buftype' equal to "quickfix". Don't change this! > If there already is a quickfix window, it will be made > the current window. It is not possible to open a > ! second quickfix window. The window will have the > ! w:quickfix_title variable set which will indicate the > ! command that produced the quickfix list. This can be > ! used to compose a custom status line if the value of > ! 'statusline' is adjusted properly. > > *:lop* *:lopen* > :lop[en] [height] Open a window to show the location list for the > --- 299,395 ---- > au QuickfixCmdPost make call QfMakeConv() > > > + EXECUTE A COMMAND IN ALL THE BUFFERS IN QUICKFIX OR LOCATION LIST: > + *:cdo* > + :cdo[!] {cmd} Execute {cmd} in each valid entry in the > quickfix list. > + It works like doing this: > > + :cfirst > + :{cmd} > + :cnext > + :{cmd} > + etc. > + < When the current file can't be |abandon|ed and the [!] > + is not present, the command fails. > + When an error is detected excecution stops. > + The last buffer (or where an error occurred) becomes > + the current buffer. > + {cmd} can contain '|' to concatenate several commands. > + > + Only valid entries in the quickfix list are used. > + A range can be used to select entries, e.g.: > > + :10,$cdo cmd > + < To skip entries 1 to 9. > + > + Note: While this command is executing, the Syntax > + autocommand event is disabled by adding it to > + 'eventignore'. This considerably speeds up editing > + each buffer. > + {not in Vi} {not available when compiled without the > + |+listcmds| feature} > + Also see |:bufdo|, |:tabdo|, |:argdo|, |:windo|, > + |:ldo|, |:cfdo| and |:lfdo|. > + > + *:cfdo* > + :cfdo[!] {cmd} Execute {cmd} in each file in the quickfix list. > + It works like doing this: > > + :cfirst > + :{cmd} > + :cnfile > + :{cmd} > + etc. > + < Otherwise it works the same as `:cdo`. > + {not in Vi} {not available when compiled without the > + |+listcmds| feature} > + > + *:ldo* > + :ld[o][!] {cmd} Execute {cmd} in each valid entry in the > location list > + for the current window. > + It works like doing this: > > + :lfirst > + :{cmd} > + :lnext > + :{cmd} > + etc. > + < Only valid entries in the location list are used. > + Otherwise it works the same as `:cdo`. > + {not in Vi} {not available when compiled without the > + |+listcmds| feature} > + > + *:lfdo* > + :lfdo[!] {cmd} Execute {cmd} in each file in the location list > for > + the current window. > + It works like doing this: > > + :lfirst > + :{cmd} > + :lnfile > + :{cmd} > + etc. > + < Otherwise it works the same as `:ldo`. > + {not in Vi} {not available when compiled without the > + |+listcmds| feature} > + > > ============================================================================= > 2. The error window *quickfix-window* > > *:cope* *:copen* *w:quickfix_title* > :cope[n] [height] Open a window to show the current list of errors. > + > When [height] is given, the window becomes that high > ! (if there is room). When [height] is omitted the > ! window is made ten lines high. > ! > If there already is a quickfix window, it will be made > the current window. It is not possible to open a > ! second quickfix window. If [height] is given the > ! existing window will be resized to it. > ! > ! The window will contain a special buffer, with > ! 'buftype' equal to "quickfix". Don't change this! > ! The window will have the w:quickfix_title variable set > ! which will indicate the command that produced the > ! quickfix list. This can be used to compose a custom > ! status line if the value of 'statusline' is adjusted > ! properly. > > *:lop* *:lopen* > :lop[en] [height] Open a window to show the location list for the > *** ../vim-7.4.857/runtime/doc/tabpage.txt 2015-04-21 18:08:21.838719097 > +0200 > --- runtime/doc/tabpage.txt 2015-09-08 18:07:42.256948348 +0200 > *************** > *** 248,254 **** > {cmd} must not open or close tab pages or reorder them. > {not in Vi} {not available when compiled without the > |+listcmds| feature} > ! Also see |:windo|, |:argdo| and |:bufdo|. > > > ============================================================================== > 3. Other items *tab-page-other* > --- 248,255 ---- > {cmd} must not open or close tab pages or reorder them. > {not in Vi} {not available when compiled without the > |+listcmds| feature} > ! Also see |:windo|, |:argdo|, |:bufdo|, |:cdo|, |:ldo|, |:cfdo| > ! and |:lfdo| > > > ============================================================================== > 3. Other items *tab-page-other* > *** ../vim-7.4.857/runtime/doc/windows.txt 2015-07-21 15:03:00.691467213 > +0200 > --- runtime/doc/windows.txt 2015-09-08 18:07:42.256948348 +0200 > *************** > *** 715,721 **** > {cmd} must not open or close windows or reorder them. > {not in Vi} {not available when compiled without the > |+listcmds| feature} > ! Also see |:tabdo|, |:argdo| and |:bufdo|. > > *:bufdo* > :[range]bufdo[!] {cmd} Execute {cmd} in each buffer in the buffer list > or if > --- 715,722 ---- > {cmd} must not open or close windows or reorder them. > {not in Vi} {not available when compiled without the > |+listcmds| feature} > ! Also see |:tabdo|, |:argdo|, |:bufdo|, |:cdo|, |:ldo|, > ! |:cfdo| and |:lfdo| > > *:bufdo* > :[range]bufdo[!] {cmd} Execute {cmd} in each buffer in the buffer list > or if > *************** > *** 743,749 **** > each buffer. > {not in Vi} {not available when compiled without the > |+listcmds| feature} > ! Also see |:tabdo|, |:argdo| and |:windo|. > > Examples: > > > --- 744,751 ---- > each buffer. > {not in Vi} {not available when compiled without the > |+listcmds| feature} > ! Also see |:tabdo|, |:argdo|, |:windo|, |:cdo|, |:ldo|, > ! |:cfdo| and |:lfdo| > > Examples: > > > *** ../vim-7.4.857/src/ex_cmds.h 2015-07-21 15:03:00.691467213 +0200 > --- src/ex_cmds.h 2015-09-08 18:20:51.228782439 +0200 > *************** > *** 65,70 **** > --- 65,71 ---- > #define ADDR_LOADED_BUFFERS 3 > #define ADDR_BUFFERS 4 > #define ADDR_TABS 5 > + #define ADDR_QUICKFIX 6 > > #ifndef DO_DECLARE_EXCMD > typedef struct exarg exarg_T; > *************** > *** 270,275 **** > --- 271,279 ---- > EX(CMD_cd, "cd", ex_cd, > BANG|FILE1|TRLBAR|CMDWIN, > ADDR_LINES), > + EX(CMD_cdo, "cdo", ex_listdo, > + BANG|NEEDARG|EXTRA|NOTRLCOM|RANGE|NOTADR|DFLALL, > + ADDR_QUICKFIX), > EX(CMD_center, "center", ex_align, > TRLBAR|RANGE|WHOLEFOLD|EXTRA|CMDWIN|MODIFY, > ADDR_LINES), > *************** > *** 279,284 **** > --- 283,291 ---- > EX(CMD_cfile, "cfile", ex_cfile, > TRLBAR|FILE1|BANG, > ADDR_LINES), > + EX(CMD_cfdo, "cfdo", ex_listdo, > + BANG|NEEDARG|EXTRA|NOTRLCOM|RANGE|NOTADR|DFLALL, > + ADDR_QUICKFIX), > EX(CMD_cfirst, "cfirst", ex_cc, > RANGE|NOTADR|COUNT|TRLBAR|BANG, > ADDR_LINES), > *************** > *** 729,734 **** > --- 736,744 ---- > EX(CMD_lcscope, "lcscope", do_cscope, > EXTRA|NOTRLCOM|XFILE, > ADDR_LINES), > + EX(CMD_ldo, "ldo", ex_listdo, > + BANG|NEEDARG|EXTRA|NOTRLCOM|RANGE|NOTADR|DFLALL, > + ADDR_QUICKFIX), > EX(CMD_left, "left", ex_align, > TRLBAR|RANGE|WHOLEFOLD|EXTRA|CMDWIN|MODIFY, > ADDR_LINES), > *************** > *** 744,749 **** > --- 754,762 ---- > EX(CMD_lfile, "lfile", ex_cfile, > TRLBAR|FILE1|BANG, > ADDR_LINES), > + EX(CMD_lfdo, "lfdo", ex_listdo, > + BANG|NEEDARG|EXTRA|NOTRLCOM|RANGE|NOTADR|DFLALL, > + ADDR_QUICKFIX), > EX(CMD_lfirst, "lfirst", ex_cc, > RANGE|NOTADR|COUNT|TRLBAR|BANG, > ADDR_LINES), > *** ../vim-7.4.857/src/ex_cmds2.c 2015-08-11 19:13:55.134175736 +0200 > --- src/ex_cmds2.c 2015-09-08 18:24:57.594233149 +0200 > *************** > *** 2429,2435 **** > } > > /* > ! * ":argdo", ":windo", ":bufdo", ":tabdo" > */ > void > ex_listdo(eap) > --- 2429,2435 ---- > } > > /* > ! * ":argdo", ":windo", ":bufdo", ":tabdo", ":cdo", ":ldo", ":cfdo" and > ":lfdo" > */ > void > ex_listdo(eap) > *************** > *** 2446,2451 **** > --- 2446,2455 ---- > char_u *save_ei = NULL; > #endif > char_u *p_shm_save; > + #ifdef FEAT_QUICKFIX > + int qf_size; > + int qf_idx; > + #endif > > #ifndef FEAT_WINDOWS > if (eap->cmdidx == CMD_windo) > *************** > *** 2498,2515 **** > } > /* set pcmark now */ > if (eap->cmdidx == CMD_bufdo) > ! { > /* Advance to the first listed buffer after "eap->line1". */ > ! for (buf = firstbuf; buf != NULL && (buf->b_fnum < eap->line1 > || !buf->b_p_bl); buf = buf->b_next) > if (buf->b_fnum > eap->line2) > { > buf = NULL; > break; > } > ! if (buf != NULL) > goto_buffer(eap, DOBUF_FIRST, FORWARD, buf->b_fnum); > ! } > else > setpcmark(); > listcmd_busy = TRUE; /* avoids setting pcmark below */ > --- 2502,2538 ---- > } > /* set pcmark now */ > if (eap->cmdidx == CMD_bufdo) > ! { > /* Advance to the first listed buffer after "eap->line1". */ > ! for (buf = firstbuf; buf != NULL && (buf->b_fnum < eap->line1 > || !buf->b_p_bl); buf = buf->b_next) > if (buf->b_fnum > eap->line2) > { > buf = NULL; > break; > } > ! if (buf != NULL) > goto_buffer(eap, DOBUF_FIRST, FORWARD, buf->b_fnum); > ! } > ! #ifdef FEAT_QUICKFIX > ! else if (eap->cmdidx == CMD_cdo || eap->cmdidx == CMD_ldo > ! || eap->cmdidx == CMD_cfdo || eap->cmdidx == CMD_lfdo) > ! { > ! qf_size = qf_get_size(eap); > ! if (qf_size <= 0 || eap->line1 > qf_size) > ! buf = NULL; > ! else > ! { > ! ex_cc(eap); > ! > ! buf = curbuf; > ! i = eap->line1 - 1; > ! if (eap->addr_count <= 0) > ! /* default is all the quickfix/location list entries */ > ! eap->line2 = qf_size; > ! } > ! } > ! #endif > else > setpcmark(); > listcmd_busy = TRUE; /* avoids setting pcmark below */ > *************** > *** 2595,2605 **** > 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; > } > > if (eap->cmdidx == CMD_windo) > { > validate_cursor(); /* cursor may have moved */ > --- 2618,2645 ---- > 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; > } > > + #ifdef FEAT_QUICKFIX > + if (eap->cmdidx == CMD_cdo || eap->cmdidx == CMD_ldo > + || eap->cmdidx == CMD_cfdo || eap->cmdidx == CMD_lfdo) > + { > + if (i >= qf_size || i >= eap->line2) > + break; > + > + qf_idx = qf_get_cur_idx(eap); > + > + ex_cnext(eap); > + > + /* If jumping to the next quickfix entry fails, quit here */ > + if (qf_get_cur_idx(eap) == qf_idx) > + break; > + } > + #endif > + > if (eap->cmdidx == CMD_windo) > { > validate_cursor(); /* cursor may have moved */ > *** ../vim-7.4.857/src/ex_docmd.c 2015-08-11 18:52:58.073121563 +0200 > --- src/ex_docmd.c 2015-09-08 18:07:42.260948306 +0200 > *************** > *** 135,141 **** > #endif > > static int check_more __ARGS((int, int)); > ! static linenr_T get_address __ARGS((char_u **, int addr_type, int skip, int > to_other_file)); > static void get_flags __ARGS((exarg_T *eap)); > #if !defined(FEAT_PERL) \ > || !defined(FEAT_PYTHON) || !defined(FEAT_PYTHON3) \ > --- 135,141 ---- > #endif > > static int check_more __ARGS((int, int)); > ! static linenr_T get_address __ARGS((exarg_T *, char_u **, int addr_type, > int skip, int to_other_file)); > static void get_flags __ARGS((exarg_T *eap)); > #if !defined(FEAT_PERL) \ > || !defined(FEAT_PYTHON) || !defined(FEAT_PYTHON3) \ > *************** > *** 2173,2181 **** > lnum = CURRENT_TAB_NR; > ea.line2 = lnum; > break; > } > ea.cmd = skipwhite(ea.cmd); > ! lnum = get_address(&ea.cmd, ea.addr_type, ea.skip, ea.addr_count == 0); > if (ea.cmd == NULL) /* error detected */ > goto doend; > if (lnum == MAXLNUM) > --- 2173,2184 ---- > lnum = CURRENT_TAB_NR; > ea.line2 = lnum; > break; > + case ADDR_QUICKFIX: > + ea.line2 = qf_get_cur_valid_idx(&ea); > + break; > } > ea.cmd = skipwhite(ea.cmd); > ! lnum = get_address(&ea, &ea.cmd, ea.addr_type, ea.skip, ea.addr_count > == 0); > if (ea.cmd == NULL) /* error detected */ > goto doend; > if (lnum == MAXLNUM) > *************** > *** 2233,2238 **** > --- 2236,2247 ---- > ea.line2 = ARGCOUNT; > } > break; > + case ADDR_QUICKFIX: > + ea.line1 = 1; > + ea.line2 = qf_get_size(&ea); > + if (ea.line2 == 0) > + ea.line2 = 1; > + break; > } > ++ea.addr_count; > } > *************** > *** 2693,2698 **** > --- 2702,2712 ---- > else > ea.line2 = ARGCOUNT; > break; > + case ADDR_QUICKFIX: > + ea.line2 = qf_get_size(&ea); > + if (ea.line2 == 0) > + ea.line2 = 1; > + break; > } > } > > *************** > *** 3839,3844 **** > --- 3853,3860 ---- > case CMD_botright: > case CMD_browse: > case CMD_bufdo: > + case CMD_cdo: > + case CMD_cfdo: > case CMD_confirm: > case CMD_debug: > case CMD_folddoclosed: > *************** > *** 3848,3854 **** > --- 3864,3872 ---- > case CMD_keepjumps: > case CMD_keepmarks: > case CMD_keeppatterns: > + case CMD_ldo: > case CMD_leftabove: > + case CMD_lfdo: > case CMD_lockmarks: > case CMD_noautocmd: > case CMD_noswapfile: > *************** > *** 4321,4327 **** > * Return MAXLNUM when no Ex address was found. > */ > static linenr_T > ! get_address(ptr, addr_type, skip, to_other_file) > char_u **ptr; > int addr_type; /* flag: one of ADDR_LINES, ... */ > int skip; /* only skip the address, don't use it */ > --- 4339,4346 ---- > * Return MAXLNUM when no Ex address was found. > */ > static linenr_T > ! get_address(eap, ptr, addr_type, skip, to_other_file) > ! exarg_T *eap; > char_u **ptr; > int addr_type; /* flag: one of ADDR_LINES, ... */ > int skip; /* only skip the address, don't use it */ > *************** > *** 4362,4367 **** > --- 4381,4389 ---- > case ADDR_TABS: > lnum = CURRENT_TAB_NR; > break; > + case ADDR_QUICKFIX: > + lnum = qf_get_cur_valid_idx(eap); > + break; > } > break; > > *************** > *** 4394,4399 **** > --- 4416,4426 ---- > case ADDR_TABS: > lnum = LAST_TAB_NR; > break; > + case ADDR_QUICKFIX: > + lnum = qf_get_size(eap); > + if (lnum == 0) > + lnum = 1; > + break; > } > break; > > *************** > *** 4569,4574 **** > --- 4596,4604 ---- > case ADDR_TABS: > lnum = CURRENT_TAB_NR; > break; > + case ADDR_QUICKFIX: > + lnum = qf_get_cur_valid_idx(eap); > + break; > } > } > > *************** > *** 4707,4712 **** > --- 4737,4746 ---- > if (eap->line2 > LAST_TAB_NR) > return (char_u *)_(e_invrange); > break; > + case ADDR_QUICKFIX: > + if (eap->line2 != 1 && eap->line2 > qf_get_size(eap)) > + return (char_u *)_(e_invrange); > + break; > } > } > return NULL; > *************** > *** 5817,5822 **** > --- 5851,5857 ---- > {ADDR_TABS, "tabs"}, > {ADDR_BUFFERS, "buffers"}, > {ADDR_WINDOWS, "windows"}, > + {ADDR_QUICKFIX, "quickfix"}, > {-1, NULL} > }; > #endif > *************** > *** 9224,9230 **** > { > long n; > > ! n = get_address(&eap->arg, eap->addr_type, FALSE, FALSE); > if (eap->arg == NULL) /* error detected */ > { > eap->nextcmd = NULL; > --- 9259,9265 ---- > { > long n; > > ! n = get_address(eap, &eap->arg, eap->addr_type, FALSE, FALSE); > if (eap->arg == NULL) /* error detected */ > { > eap->nextcmd = NULL; > *** ../vim-7.4.857/src/proto/quickfix.pro 2013-08-10 13:37:24.000000000 > +0200 > --- src/proto/quickfix.pro 2015-09-08 18:29:04.723675697 +0200 > *************** > *** 17,22 **** > --- 17,25 ---- > int buf_hide __ARGS((buf_T *buf)); > int grep_internal __ARGS((cmdidx_T cmdidx)); > void ex_make __ARGS((exarg_T *eap)); > + int qf_get_size __ARGS((exarg_T *eap)); > + int qf_get_cur_idx __ARGS((exarg_T *eap)); > + int qf_get_cur_valid_idx __ARGS((exarg_T *eap)); > void ex_cc __ARGS((exarg_T *eap)); > void ex_cnext __ARGS((exarg_T *eap)); > void ex_cfile __ARGS((exarg_T *eap)); > *** ../vim-7.4.857/src/quickfix.c 2015-06-19 18:35:29.683602295 +0200 > --- src/quickfix.c 2015-09-08 18:30:09.711003127 +0200 > *************** > *** 1373,1379 **** > /* > * Check in which directory of the directory stack the given file can be > * found. > ! * Returns a pointer to the directory name or NULL if not found > * Cleans up intermediate directory entries. > * > * TODO: How to solve the following problem? > --- 1373,1379 ---- > /* > * Check in which directory of the directory stack the given file can be > * found. > ! * Returns a pointer to the directory name or NULL if not found. > * Cleans up intermediate directory entries. > * > * TODO: How to solve the following problem? > *************** > *** 2990,3008 **** > } > > /* > * ":cc", ":crewind", ":cfirst" and ":clast". > * ":ll", ":lrewind", ":lfirst" and ":llast". > */ > void > ex_cc(eap) > exarg_T *eap; > { > qf_info_T *qi = &ql_info; > > if (eap->cmdidx == CMD_ll > || eap->cmdidx == CMD_lrewind > || eap->cmdidx == CMD_lfirst > ! || eap->cmdidx == CMD_llast) > { > qi = GET_LOC_LIST(curwin); > if (qi == NULL) > --- 2990,3172 ---- > } > > /* > + * Returns the number of valid entries in the current quickfix/location > list. > + */ > + int > + qf_get_size(eap) > + exarg_T *eap; > + { > + qf_info_T *qi = &ql_info; > + qfline_T *qfp; > + int i, sz = 0; > + int prev_fnum = 0; > + > + if (eap->cmdidx == CMD_ldo || eap->cmdidx == CMD_lfdo) > + { > + /* Location list */ > + qi = GET_LOC_LIST(curwin); > + if (qi == NULL) > + return 0; > + } > + > + for (i = 0, qfp = qi->qf_lists[qi->qf_curlist].qf_start; > + (i < qi->qf_lists[qi->qf_curlist].qf_count) && (qfp != NULL); > + ++i, qfp = qfp->qf_next) > + { > + if (qfp->qf_valid) > + { > + if (eap->cmdidx == CMD_cdo || eap->cmdidx == CMD_ldo) > + sz++; /* Count all valid entries */ > + else if (qfp->qf_fnum > 0 && qfp->qf_fnum != prev_fnum) > + { > + /* Count the number of files */ > + sz++; > + prev_fnum = qfp->qf_fnum; > + } > + } > + } > + > + return sz; > + } > + > + /* > + * Returns the current index of the quickfix/location list. > + * Returns 0 if there is an error. > + */ > + int > + qf_get_cur_idx(eap) > + exarg_T *eap; > + { > + qf_info_T *qi = &ql_info; > + > + if (eap->cmdidx == CMD_ldo || eap->cmdidx == CMD_lfdo) > + { > + /* Location list */ > + qi = GET_LOC_LIST(curwin); > + if (qi == NULL) > + return 0; > + } > + > + return qi->qf_lists[qi->qf_curlist].qf_index; > + } > + > + /* > + * Returns the current index in the quickfix/location list (counting only > valid > + * entries). If no valid entries are in the list, then returns 1. > + */ > + int > + qf_get_cur_valid_idx(eap) > + exarg_T *eap; > + { > + qf_info_T *qi = &ql_info; > + qf_list_T *qfl; > + qfline_T *qfp; > + int i, eidx = 0; > + int prev_fnum = 0; > + > + if (eap->cmdidx == CMD_ldo || eap->cmdidx == CMD_lfdo) > + { > + /* Location list */ > + qi = GET_LOC_LIST(curwin); > + if (qi == NULL) > + return 1; > + } > + > + qfl = &qi->qf_lists[qi->qf_curlist]; > + qfp = qfl->qf_start; > + > + /* check if the list has valid errors */ > + if (qfl->qf_count <= 0 || qfl->qf_nonevalid) > + return 1; > + > + for (i = 1; i <= qfl->qf_index && qfp!= NULL; i++, qfp = qfp->qf_next) > + { > + if (qfp->qf_valid) > + { > + if (eap->cmdidx == CMD_cfdo || eap->cmdidx == CMD_lfdo) > + { > + if (qfp->qf_fnum > 0 && qfp->qf_fnum != prev_fnum) > + { > + /* Count the number of files */ > + eidx++; > + prev_fnum = qfp->qf_fnum; > + } > + } > + else > + eidx++; > + } > + } > + > + return eidx ? eidx : 1; > + } > + > + /* > + * Get the 'n'th valid error entry in the quickfix or location list. > + * Used by :cdo, :ldo, :cfdo and :lfdo commands. > + * For :cdo and :ldo returns the 'n'th valid error entry. > + * For :cfdo and :lfdo returns the 'n'th valid file entry. > + */ > + static int > + qf_get_nth_valid_entry(qi, n, fdo) > + qf_info_T *qi; > + int n; > + int fdo; > + { > + qf_list_T *qfl = &qi->qf_lists[qi->qf_curlist]; > + qfline_T *qfp = qfl->qf_start; > + int i, eidx; > + int prev_fnum = 0; > + > + /* check if the list has valid errors */ > + if (qfl->qf_count <= 0 || qfl->qf_nonevalid) > + return 1; > + > + for (i = 1, eidx = 0; i <= qfl->qf_count && qfp!= NULL; > + i++, qfp = qfp->qf_next) > + { > + if (qfp->qf_valid) > + { > + if (fdo) > + { > + if (qfp->qf_fnum > 0 && qfp->qf_fnum != prev_fnum) > + { > + /* Count the number of files */ > + eidx++; > + prev_fnum = qfp->qf_fnum; > + } > + } > + else > + eidx++; > + } > + > + if (eidx == n) > + break; > + } > + > + if (i <= qfl->qf_count) > + return i; > + else > + return 1; > + } > + > + /* > * ":cc", ":crewind", ":cfirst" and ":clast". > * ":ll", ":lrewind", ":lfirst" and ":llast". > + * ":cdo", ":ldo", ":cfdo" and ":lfdo" > */ > void > ex_cc(eap) > exarg_T *eap; > { > qf_info_T *qi = &ql_info; > + int errornr; > > if (eap->cmdidx == CMD_ll > || eap->cmdidx == CMD_lrewind > || eap->cmdidx == CMD_lfirst > ! || eap->cmdidx == CMD_llast > ! || eap->cmdidx == CMD_ldo > ! || eap->cmdidx == CMD_lfdo) > { > qi = GET_LOC_LIST(curwin); > if (qi == NULL) > *************** > *** 3012,3045 **** > } > } > > ! qf_jump(qi, 0, > ! eap->addr_count > 0 > ! ? (int)eap->line2 > ! : (eap->cmdidx == CMD_cc || eap->cmdidx == CMD_ll) > ! ? 0 > ! : (eap->cmdidx == CMD_crewind || eap->cmdidx == CMD_lrewind > ! || eap->cmdidx == CMD_cfirst || eap->cmdidx == CMD_lfirst) > ! ? 1 > ! : 32767, > ! eap->forceit); > } > > /* > * ":cnext", ":cnfile", ":cNext" and ":cprevious". > * ":lnext", ":lNext", ":lprevious", ":lnfile", ":lNfile" and ":lpfile". > */ > void > ex_cnext(eap) > exarg_T *eap; > { > qf_info_T *qi = &ql_info; > > if (eap->cmdidx == CMD_lnext > || eap->cmdidx == CMD_lNext > || eap->cmdidx == CMD_lprevious > || eap->cmdidx == CMD_lnfile > || eap->cmdidx == CMD_lNfile > ! || eap->cmdidx == CMD_lpfile) > { > qi = GET_LOC_LIST(curwin); > if (qi == NULL) > --- 3176,3226 ---- > } > } > > ! if (eap->addr_count > 0) > ! errornr = (int)eap->line2; > ! else > ! { > ! if (eap->cmdidx == CMD_cc || eap->cmdidx == CMD_ll) > ! errornr = 0; > ! else if (eap->cmdidx == CMD_crewind || eap->cmdidx == CMD_lrewind > ! || eap->cmdidx == CMD_cfirst || eap->cmdidx == CMD_lfirst) > ! errornr = 1; > ! else > ! errornr = 32767; > ! } > ! > ! /* For cdo and ldo commands, jump to the nth valid error. > ! * For cfdo and lfdo commands, jump to the nth valid file entry. > ! */ > ! if (eap->cmdidx == CMD_cdo || eap->cmdidx == CMD_ldo || > ! eap->cmdidx == CMD_cfdo || eap->cmdidx == CMD_lfdo) > ! errornr = qf_get_nth_valid_entry(qi, > ! eap->addr_count > 0 ? (int)eap->line1 : 1, > ! eap->cmdidx == CMD_cfdo || eap->cmdidx == CMD_lfdo); > ! > ! qf_jump(qi, 0, errornr, eap->forceit); > } > > /* > * ":cnext", ":cnfile", ":cNext" and ":cprevious". > * ":lnext", ":lNext", ":lprevious", ":lnfile", ":lNfile" and ":lpfile". > + * Also, used by ":cdo", ":ldo", ":cfdo" and ":lfdo" commands. > */ > void > ex_cnext(eap) > exarg_T *eap; > { > qf_info_T *qi = &ql_info; > + int errornr; > > if (eap->cmdidx == CMD_lnext > || eap->cmdidx == CMD_lNext > || eap->cmdidx == CMD_lprevious > || eap->cmdidx == CMD_lnfile > || eap->cmdidx == CMD_lNfile > ! || eap->cmdidx == CMD_lpfile > ! || eap->cmdidx == CMD_ldo > ! || eap->cmdidx == CMD_lfdo) > { > qi = GET_LOC_LIST(curwin); > if (qi == NULL) > *************** > *** 3049,3063 **** > } > } > > ! qf_jump(qi, (eap->cmdidx == CMD_cnext || eap->cmdidx == CMD_lnext) > ? FORWARD > ! : (eap->cmdidx == CMD_cnfile || eap->cmdidx == CMD_lnfile) > ? FORWARD_FILE > : (eap->cmdidx == CMD_cpfile || eap->cmdidx == CMD_lpfile > || eap->cmdidx == CMD_cNfile || eap->cmdidx == CMD_lNfile) > ? BACKWARD_FILE > : BACKWARD, > ! eap->addr_count > 0 ? (int)eap->line2 : 1, eap->forceit); > } > > /* > --- 3230,3253 ---- > } > } > > ! if (eap->addr_count > 0 && > ! (eap->cmdidx != CMD_cdo && eap->cmdidx != CMD_ldo && > ! eap->cmdidx != CMD_cfdo && eap->cmdidx != CMD_lfdo)) > ! errornr = (int)eap->line2; > ! else > ! errornr = 1; > ! > ! qf_jump(qi, (eap->cmdidx == CMD_cnext || eap->cmdidx == CMD_lnext > ! || eap->cmdidx == CMD_cdo || eap->cmdidx == CMD_ldo) > ? FORWARD > ! : (eap->cmdidx == CMD_cnfile || eap->cmdidx == CMD_lnfile > ! || eap->cmdidx == CMD_cfdo || eap->cmdidx == CMD_lfdo) > ? FORWARD_FILE > : (eap->cmdidx == CMD_cpfile || eap->cmdidx == CMD_lpfile > || eap->cmdidx == CMD_cNfile || eap->cmdidx == CMD_lNfile) > ? BACKWARD_FILE > : BACKWARD, > ! errornr, eap->forceit); > } > > /* > *** ../vim-7.4.857/src/testdir/Make_amiga.mak 2015-09-01 16:04:26.706472322 > +0200 > --- src/testdir/Make_amiga.mak 2015-09-08 18:33:40.696822313 +0200 > *************** > *** 41,46 **** > --- 41,47 ---- > test_autocmd_option.out \ > test_autoformat_join.out \ > test_breakindent.out \ > + test_cdo.out \ > test_changelist.out \ > test_charsearch.out \ > test_close_count.out \ > *************** > *** 195,200 **** > --- 196,202 ---- > test_autocmd_option.out: test_autocmd_option.in > test_autoformat_join.out: test_autoformat_join.in > test_breakindent.out: test_breakindent.in > + test_cdo.out: test_cdo.in > test_changelist.out: test_changelist.in > test_charsearch.out: test_charsearch.in > test_close_count.out: test_close_count.in > *** ../vim-7.4.857/src/testdir/Make_dos.mak 2015-09-01 16:04:26.706472322 > +0200 > --- src/testdir/Make_dos.mak 2015-09-08 18:33:24.828984002 +0200 > *************** > *** 40,45 **** > --- 40,46 ---- > test_autocmd_option.out \ > test_autoformat_join.out \ > test_breakindent.out \ > + test_cdo.out \ > test_changelist.out \ > test_charsearch.out \ > test_close_count.out \ > *** ../vim-7.4.857/src/testdir/Make_ming.mak 2015-09-01 16:04:26.706472322 > +0200 > --- src/testdir/Make_ming.mak 2015-09-08 18:33:54.412682545 +0200 > *************** > *** 62,67 **** > --- 62,68 ---- > test_autocmd_option.out \ > test_autoformat_join.out \ > test_breakindent.out \ > + test_cdo.out \ > test_changelist.out \ > test_charsearch.out \ > test_close_count.out \ > *** ../vim-7.4.857/src/testdir/Make_os2.mak 2015-09-01 16:04:26.706472322 > +0200 > --- src/testdir/Make_os2.mak 2015-09-08 18:34:06.004564414 +0200 > *************** > *** 42,47 **** > --- 42,48 ---- > test_autocmd_option.out \ > test_autoformat_join.out \ > test_breakindent.out \ > + test_cdo.out \ > test_changelist.out \ > test_charsearch.out \ > test_close_count.out \ > *** ../vim-7.4.857/src/testdir/Make_vms.mms 2015-09-01 16:04:26.706472322 > +0200 > --- src/testdir/Make_vms.mms 2015-09-08 18:34:18.448437596 +0200 > *************** > *** 4,10 **** > # Authors: Zoltan Arpadffy, <arpad...@polarhome.com> > # Sandor Kopanyi, <sandor.kopa...@mailbox.hu> > # > ! # Last change: 2015 Sep 01 > # > # This has been tested on VMS 6.2 to 8.3 on DEC Alpha, VAX and IA64. > # Edit the lines in the Configuration section below to select. > --- 4,10 ---- > # Authors: Zoltan Arpadffy, <arpad...@polarhome.com> > # Sandor Kopanyi, <sandor.kopa...@mailbox.hu> > # > ! # Last change: 2015 Sep 08 > # > # This has been tested on VMS 6.2 to 8.3 on DEC Alpha, VAX and IA64. > # Edit the lines in the Configuration section below to select. > *************** > *** 101,106 **** > --- 101,107 ---- > test_autocmd_option.out \ > test_autoformat_join.out \ > test_breakindent.out \ > + test_cdo.out \ > test_changelist.out \ > test_charsearch.out \ > test_close_count.out \ > *** ../vim-7.4.857/src/testdir/Makefile 2015-09-01 16:04:26.706472322 > +0200 > --- src/testdir/Makefile 2015-09-08 18:34:35.048268412 +0200 > *************** > *** 38,43 **** > --- 38,44 ---- > test_autocmd_option.out \ > test_autoformat_join.out \ > test_breakindent.out \ > + test_cdo.out \ > test_changelist.out \ > test_charsearch.out \ > test_close_count.out \ > *** ../vim-7.4.857/src/testdir/test_cdo.in 2015-09-08 18:42:16.203563949 > +0200 > --- src/testdir/test_cdo.in 2015-09-08 18:07:42.260948306 +0200 > *************** > *** 0 **** > --- 1,107 ---- > + Tests for the :cdo, :cfdo, :ldo and :lfdo commands > + > + STARTTEST > + :so small.vim > + :if !has('quickfix') | e! test.ok | wq! test.out | endif > + > + :call writefile(["Line1", "Line2", "Line3"], 'Xtestfile1') > + :call writefile(["Line1", "Line2", "Line3"], 'Xtestfile2') > + :call writefile(["Line1", "Line2", "Line3"], 'Xtestfile3') > + > + :function RunTests(cchar) > + : let nl="\n" > + > + : enew > + : " Try with an empty list > + : exe a:cchar . "do let g:result .= expand('%') . ' ' . line('.') . 'L' . > ' ' . col('.') . 'C' . nl" > + > + : " Populate the list and then try > + : exe a:cchar . "getexpr ['non-error 1', 'Xtestfile1:1:3:Line1', > 'non-error 2', 'Xtestfile2:2:2:Line2', 'non-error 3', 'Xtestfile3:3:1:Line3']" > + : exe a:cchar . "do let g:result .= expand('%') . ' ' . line('.') . 'L' . > ' ' . col('.') . 'C' . nl" > + > + : " Run command only on selected error lines > + : enew > + : exe "2,3" . a:cchar . "do let g:result .= expand('%') . ' ' . line('.') > . 'L' . ' ' . col('.') . 'C' . nl" > + : " Boundary condition tests > + : enew > + : exe "1,1" . a:cchar . "do let g:result .= expand('%') . ' ' . line('.') > . 'L' . ' ' . col('.') . 'C' . nl" > + : enew > + : exe "3" . a:cchar . "do let g:result .= expand('%') . ' ' . line('.') . > 'L' . ' ' . col('.') . 'C' . nl" > + : " Range test commands > + : enew > + : exe "%" . a:cchar . "do let g:result .= expand('%') . ' ' . line('.') . > 'L' . ' ' . col('.') . 'C' . nl" > + : enew > + : exe "1,$" . a:cchar . "do let g:result .= expand('%') . ' ' . line('.') > . 'L' . ' ' . col('.') . 'C' . nl" > + : enew > + : exe a:cchar . 'prev' > + : exe "." . a:cchar . "do let g:result .= expand('%') . ' ' . line('.') . > 'L' . ' ' . col('.') . 'C' . nl" > + : " Invalid error lines test > + : enew > + : exe "27" . a:cchar . "do let g:result .= expand('%') . ' ' . line('.') . > 'L' . ' ' . col('.') . 'C' . nl" > + : exe "4,5" . a:cchar . "do let g:result .= expand('%') . ' ' . line('.') > . 'L' . ' ' . col('.') . 'C' . nl" > + > + : " Run commands from an unsaved buffer > + : let v:errmsg='' > + : enew > + : setlocal modified > + : exe "2,2" . a:cchar . "do let g:result .= expand('%') . ' ' . line('.') > . 'L' . ' ' . col('.') . 'C' . nl" > + : if v:errmsg =~# 'No write since last change' > + : let g:result .= 'Unsaved file change test passed' . nl > + : else > + : let g:result .= 'Unsaved file change test failed' . nl > + : endif > + > + : " If the executed command fails, then the operation should be aborted > + : enew! > + : let subst_count = 0 > + : exe a:cchar . "do s/Line/xLine/ | let subst_count += 1" > + : if subst_count == 1 && getline('.') == 'xLine1' > + : let g:result .= 'Abort command on error test passed' . nl > + : else > + : let g:result .= 'Abort command on error test failed' . nl > + : endif > + > + : exe "2,2" . a:cchar . "do! let g:result .= expand('%') . ' ' . line('.') > . 'L' . ' ' . col('.') . 'C' . nl" > + > + : " List with no valid error entries > + : edit! +2 Xtestfile1 > + : exe a:cchar . "getexpr ['non-error 1', 'non-error 2', 'non-error 3']" > + : exe a:cchar . "do let g:result .= expand('%') . ' ' . line('.') . 'L' . > ' ' . col('.') . 'C' . nl" > + : exe "2" . a:cchar . "do let g:result .= expand('%') . ' ' . line('.') . > 'L' . ' ' . col('.') . 'C' . nl" > + : let v:errmsg='' > + : exe "%" . a:cchar . "do let g:result .= expand('%') . ' ' . line('.') . > 'L' . ' ' . col('.') . 'C' . nl" > + : exe "1,$" . a:cchar . "do let g:result .= expand('%') . ' ' . line('.') > . 'L' . ' ' . col('.') . 'C' . nl" > + : exe "." . a:cchar . "do let g:result .= expand('%') . ' ' . line('.') . > 'L' . ' ' . col('.') . 'C' . nl" > + : let g:result .= v:errmsg > + > + : " List with only one valid entry > + : exe a:cchar . "getexpr ['Xtestfile3:3:1:Line3']" > + : exe a:cchar . "do let g:result .= expand('%') . ' ' . line('.') . 'L' . > ' ' . col('.') . 'C' . nl" > + > + : " Tests for :cfdo and :lfdo commands > + : exe a:cchar . "getexpr ['non-error 1', 'Xtestfile1:1:3:Line1', > 'Xtestfile1:2:1:Line2', 'non-error 2', 'Xtestfile2:2:2:Line2', 'non-error 3', > 'Xtestfile3:2:3:Line2', 'Xtestfile3:3:1:Line3']" > + : exe a:cchar . "fdo let g:result .= expand('%') . ' ' . line('.') . 'L' . > ' ' . col('.') . 'C' . nl" > + : exe "3" . a:cchar . "fdo let g:result .= expand('%') . ' ' . line('.') . > 'L' . ' ' . col('.') . 'C' . nl" > + : exe "2,3" . a:cchar . "fdo let g:result .= expand('%') . ' ' . line('.') > . 'L' . ' ' . col('.') . 'C' . nl" > + : exe "%" . a:cchar . "fdo let g:result .= expand('%') . ' ' . line('.') . > 'L' . ' ' . col('.') . 'C' . nl" > + : exe "1,$" . a:cchar . "fdo let g:result .= expand('%') . ' ' . line('.') > . 'L' . ' ' . col('.') . 'C' . nl" > + : exe a:cchar . 'pfile' > + : exe "." . a:cchar . "fdo let g:result .= expand('%') . ' ' . line('.') . > 'L' . ' ' . col('.') . 'C' . nl" > + > + : " List with only one valid entry > + : exe a:cchar . "getexpr ['Xtestfile2:2:5:Line2']" > + : exe a:cchar . "fdo let g:result .= expand('%') . ' ' . line('.') . 'L' . > ' ' . col('.') . 'C' . nl" > + :endfunction > + > + :let result='' > + :" Tests for the :cdo quickfix list command > + :call RunTests('c') > + :let result .= "\n" > + :" Tests for the :ldo location list command > + :call RunTests('l') > + > + :edit! test.out > + :0put =result > + :wq! > + ENDTEST > + > *** ../vim-7.4.857/src/testdir/test_cdo.ok 2015-09-08 18:42:16.207563908 > +0200 > --- src/testdir/test_cdo.ok 2015-09-08 18:07:42.260948306 +0200 > *************** > *** 0 **** > --- 1,66 ---- > + Xtestfile1 1L 3C > + Xtestfile2 2L 2C > + Xtestfile3 3L 1C > + Xtestfile2 2L 2C > + Xtestfile3 3L 1C > + Xtestfile1 1L 3C > + Xtestfile3 3L 1C > + Xtestfile1 1L 3C > + Xtestfile2 2L 2C > + Xtestfile3 3L 1C > + Xtestfile1 1L 3C > + Xtestfile2 2L 2C > + Xtestfile3 3L 1C > + Xtestfile2 2L 2C > + Unsaved file change test passed > + Abort command on error test passed > + Xtestfile2 2L 2C > + Xtestfile3 3L 1C > + Xtestfile1 1L 3C > + Xtestfile2 2L 2C > + Xtestfile3 2L 3C > + Xtestfile3 2L 3C > + Xtestfile2 2L 2C > + Xtestfile3 2L 3C > + Xtestfile1 1L 3C > + Xtestfile2 2L 2C > + Xtestfile3 2L 3C > + Xtestfile1 1L 3C > + Xtestfile2 2L 2C > + Xtestfile3 2L 3C > + Xtestfile2 2L 2C > + Xtestfile2 2L 5C > + > + Xtestfile1 1L 3C > + Xtestfile2 2L 2C > + Xtestfile3 3L 1C > + Xtestfile2 2L 2C > + Xtestfile3 3L 1C > + Xtestfile1 1L 3C > + Xtestfile3 3L 1C > + Xtestfile1 1L 3C > + Xtestfile2 2L 2C > + Xtestfile3 3L 1C > + Xtestfile1 1L 3C > + Xtestfile2 2L 2C > + Xtestfile3 3L 1C > + Xtestfile2 2L 2C > + Unsaved file change test passed > + Abort command on error test passed > + Xtestfile2 2L 2C > + Xtestfile3 3L 1C > + Xtestfile1 1L 3C > + Xtestfile2 2L 2C > + Xtestfile3 2L 3C > + Xtestfile3 2L 3C > + Xtestfile2 2L 2C > + Xtestfile3 2L 3C > + Xtestfile1 1L 3C > + Xtestfile2 2L 2C > + Xtestfile3 2L 3C > + Xtestfile1 1L 3C > + Xtestfile2 2L 2C > + Xtestfile3 2L 3C > + Xtestfile2 2L 2C > + Xtestfile2 2L 5C > + > *** ../vim-7.4.857/src/version.c 2015-09-08 17:50:38.071546587 +0200 > --- src/version.c 2015-09-08 18:07:17.353206130 +0200 > *************** > *** 743,744 **** > --- 743,746 ---- > { /* Add new patch number below this line */ > + /**/... -- -- 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 vim_dev+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.