Hi all,
On Sun, Jun 2, 2013 at 2:09 PM, Bram Moolenaar <[email protected]> wrote:
>
> Yegappan Lakshmanan wrote:
>
>> I am attaching a patch to add the :cdo and :ldo commands. The :cdo command
>> can be used to execute commands over all the buffers in the quickfix list.
>> The :ldo command can be used to execute commands over all the buffers in
>> the location list. These are similar to the existing :bufdo, :windo
>> and :tabdo commands.
>
> Thanks. I'll add it in the todo list.
>
I am attaching an updated patch with a lot of test cases against Vim 7.4.671.
This patch introduces the ":cdo", ":ldo", ":cfdo" and ":lfdo"commands.
The patch to the documentation is also included.
- Yegappan
--
--
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 c0df98c0770c runtime/doc/cmdline.txt
--- a/runtime/doc/cmdline.txt Sat Mar 21 14:20:16 2015 +0100
+++ b/runtime/doc/cmdline.txt Sat Mar 21 19:36:52 2015 -0700
@@ -511,6 +511,8 @@
:argdo
:autocmd
:bufdo
+ :cdo
+ :cfdo
:command
:cscope
:debug
@@ -521,6 +523,8 @@
:help
:helpfind
:lcscope
+ :ldo
+ :lfdo
:make
:normal
:perl
diff -r c0df98c0770c runtime/doc/editing.txt
--- a/runtime/doc/editing.txt Sat Mar 21 14:20:16 2015 +0100
+++ b/runtime/doc/editing.txt Sat Mar 21 19:36:52 2015 -0700
@@ -855,7 +855,8 @@
each file.
{not in Vi} {not available when compiled without the
|+listcmds| feature}
- Also see |:windo|, |:tabdo| and |:bufdo|.
+ Also see |:windo|, |:tabdo|, |:bufdo|, |:cdo|, |:ldo|,
+ |:cfdo| and |:lfdo|
Example: >
:args *.c
diff -r c0df98c0770c runtime/doc/index.txt
--- a/runtime/doc/index.txt Sat Mar 21 14:20:16 2015 +0100
+++ b/runtime/doc/index.txt Sat Mar 21 19:36:52 2015 -0700
@@ -1138,6 +1138,8 @@
|: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| :cfdo 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
@@ -1296,6 +1298,8 @@
|: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
diff -r c0df98c0770c runtime/doc/quickfix.txt
--- a/runtime/doc/quickfix.txt Sat Mar 21 14:20:16 2015 +0100
+++ b/runtime/doc/quickfix.txt Sat Mar 21 19:36:52 2015 -0700
@@ -298,6 +298,108 @@
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 on one buffer, further
+ buffers will not be visited.
+ 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.
+ 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.
+< When the current file can't be |abandon|ed and the [!]
+ is not present, the command fails.
+ When an error is detected on one buffer, further
+ buffers will not be visited.
+ 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.
+ 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|,
+ |:cdo|, |:ldo| and |:lfdo|.
+
+ *:ldo*
+:ld[o][!] {cmd} Execute {cmd} in each entry in the location
list for
+ the current window.
+ It works like doing this: >
+ :lfirst
+ :{cmd}
+ :lnext
+ :{cmd}
+ etc.
+< When the current file can't be |abandon|ed and the [!]
+ is not present, the command fails.
+ When an error is detected on one buffer, further
+ buffers will not be visited.
+ The last buffer (or where an error occurred) becomes
+ the current buffer.
+ {cmd} can contain '|' to concatenate several commands.
+ Only valid entries in the location list are used.
+ 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|,
+ |:cdo|, |:cfdo| and |:lfdo|.
+
+ *: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.
+< When the current file can't be |abandon|ed and the [!]
+ is not present, the command fails.
+ When an error is detected on one buffer, further
+ buffers will not be visited.
+ The last buffer (or where an error occurred) becomes
+ the current buffer.
+ {cmd} can contain '|' to concatenate several commands.
+ Only valid entries in the location list are used.
+ 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|,
+ |:cdo|, |:ldo| and |:cfdo|.
=============================================================================
2. The error window *quickfix-window*
diff -r c0df98c0770c runtime/doc/tabpage.txt
--- a/runtime/doc/tabpage.txt Sat Mar 21 14:20:16 2015 +0100
+++ b/runtime/doc/tabpage.txt Sat Mar 21 19:36:52 2015 -0700
@@ -242,7 +242,8 @@
{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|.
+ Also see |:windo|, |:argdo|, |:bufdo|, |:cdo|, |:ldo|, |:cfdo|
+ and |:lfdo|
==============================================================================
3. Other items *tab-page-other*
diff -r c0df98c0770c runtime/doc/windows.txt
--- a/runtime/doc/windows.txt Sat Mar 21 14:20:16 2015 +0100
+++ b/runtime/doc/windows.txt Sat Mar 21 19:36:52 2015 -0700
@@ -715,7 +715,8 @@
{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|.
+ 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,7 +744,8 @@
each buffer.
{not in Vi} {not available when compiled without the
|+listcmds| feature}
- Also see |:tabdo|, |:argdo| and |:windo|.
+ Also see |:tabdo|, |:argdo|, |:windo|, |:cdo|, |:ldo|,
+ |:cfdo| and |:lfdo|
Examples: >
diff -r c0df98c0770c src/ex_cmds.h
--- a/src/ex_cmds.h Sat Mar 21 14:20:16 2015 +0100
+++ b/src/ex_cmds.h Sat Mar 21 19:36:52 2015 -0700
@@ -270,12 +270,18 @@
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_LINES),
EX(CMD_center, "center", ex_align,
TRLBAR|RANGE|WHOLEFOLD|EXTRA|CMDWIN|MODIFY,
ADDR_LINES),
EX(CMD_cexpr, "cexpr", ex_cexpr,
NEEDARG|WORD1|NOTRLCOM|TRLBAR|BANG,
ADDR_LINES),
+EX(CMD_cfdo, "cfdo", ex_listdo,
+ BANG|NEEDARG|EXTRA|NOTRLCOM|RANGE|NOTADR|DFLALL,
+ ADDR_LINES),
EX(CMD_cfile, "cfile", ex_cfile,
TRLBAR|FILE1|BANG,
ADDR_LINES),
@@ -729,6 +735,9 @@
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_LINES),
EX(CMD_left, "left", ex_align,
TRLBAR|RANGE|WHOLEFOLD|EXTRA|CMDWIN|MODIFY,
ADDR_LINES),
@@ -741,6 +750,9 @@
EX(CMD_lexpr, "lexpr", ex_cexpr,
NEEDARG|WORD1|NOTRLCOM|TRLBAR|BANG,
ADDR_LINES),
+EX(CMD_lfdo, "lfdo", ex_listdo,
+ BANG|NEEDARG|EXTRA|NOTRLCOM|RANGE|NOTADR|DFLALL,
+ ADDR_LINES),
EX(CMD_lfile, "lfile", ex_cfile,
TRLBAR|FILE1|BANG,
ADDR_LINES),
diff -r c0df98c0770c src/ex_cmds2.c
--- a/src/ex_cmds2.c Sat Mar 21 14:20:16 2015 +0100
+++ b/src/ex_cmds2.c Sat Mar 21 19:36:52 2015 -0700
@@ -2429,7 +2429,7 @@
}
/*
- * ":argdo", ":windo", ":bufdo", ":tabdo"
+ * ":argdo", ":windo", ":bufdo", ":tabdo", ":cdo", ":ldo", ":cfdo" and ":lfdo"
*/
void
ex_listdo(eap)
@@ -2446,6 +2446,9 @@
char_u *save_ei = NULL;
#endif
char_u *p_shm_save;
+#ifdef FEAT_QUICKFIX
+ int qf_size;
+#endif
#ifndef FEAT_WINDOWS
if (eap->cmdidx == CMD_windo)
@@ -2510,6 +2513,24 @@
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)
+ eap->line2 = qf_size; /* default is all the
quickfix/location list entries */
+ }
+ }
+#endif
else
setpcmark();
listcmd_busy = TRUE; /* avoids setting pcmark below */
@@ -2600,6 +2621,17 @@
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;
+
+ ex_cnext(eap);
+ }
+#endif
+
if (eap->cmdidx == CMD_windo)
{
validate_cursor(); /* cursor may have moved */
diff -r c0df98c0770c src/ex_docmd.c
--- a/src/ex_docmd.c Sat Mar 21 14:20:16 2015 +0100
+++ b/src/ex_docmd.c Sat Mar 21 19:36:52 2015 -0700
@@ -3838,6 +3838,8 @@
case CMD_botright:
case CMD_browse:
case CMD_bufdo:
+ case CMD_cdo:
+ case CMD_cfdo:
case CMD_confirm:
case CMD_debug:
case CMD_folddoclosed:
@@ -3847,7 +3849,9 @@
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:
diff -r c0df98c0770c src/proto/quickfix.pro
--- a/src/proto/quickfix.pro Sat Mar 21 14:20:16 2015 +0100
+++ b/src/proto/quickfix.pro Sat Mar 21 19:36:52 2015 -0700
@@ -27,4 +27,6 @@
void ex_cbuffer __ARGS((exarg_T *eap));
void ex_cexpr __ARGS((exarg_T *eap));
void ex_helpgrep __ARGS((exarg_T *eap));
+int qf_get_size __ARGS((exarg_T *eap));
+int qf_get_buffers __ARGS((garray_T *gap, int qfl));
/* vim: set ft=c : */
diff -r c0df98c0770c src/quickfix.c
--- a/src/quickfix.c Sat Mar 21 14:20:16 2015 +0100
+++ b/src/quickfix.c Sat Mar 21 19:36:52 2015 -0700
@@ -2985,19 +2985,108 @@
}
/*
+ * 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;
+}
+
+/*
+ * 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_llast
+ || eap->cmdidx == CMD_ldo
+ || eap->cmdidx == CMD_lfdo)
{
qi = GET_LOC_LIST(curwin);
if (qi == NULL)
@@ -3007,34 +3096,51 @@
}
}
- 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);
+ 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_lpfile
+ || eap->cmdidx == CMD_ldo
+ || eap->cmdidx == CMD_lfdo)
{
qi = GET_LOC_LIST(curwin);
if (qi == NULL)
@@ -3044,15 +3150,24 @@
}
}
- qf_jump(qi, (eap->cmdidx == CMD_cnext || eap->cmdidx == CMD_lnext)
+ 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_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,
- eap->addr_count > 0 ? (int)eap->line2 : 1, eap->forceit);
+ errornr, eap->forceit);
}
/*
diff -r c0df98c0770c src/testdir/Make_amiga.mak
--- a/src/testdir/Make_amiga.mak Sat Mar 21 14:20:16 2015 +0100
+++ b/src/testdir/Make_amiga.mak Sat Mar 21 19:36:52 2015 -0700
@@ -54,7 +54,8 @@
test_qf_title.out \
test_signs.out \
test_textobjects.out \
- test_utf8.out
+ test_utf8.out \
+ test_cdo.out
.SUFFIXES: .in .out
@@ -197,3 +198,4 @@
test_signs.out: test_signs.in
test_textobjects.out: test_textobjects.in
test_utf8.out: test_utf8.in
+test_cdo.out: test_cdo.in
diff -r c0df98c0770c src/testdir/Make_dos.mak
--- a/src/testdir/Make_dos.mak Sat Mar 21 14:20:16 2015 +0100
+++ b/src/testdir/Make_dos.mak Sat Mar 21 19:36:52 2015 -0700
@@ -53,7 +53,8 @@
test_qf_title.out \
test_signs.out \
test_textobjects.out \
- test_utf8.out
+ test_utf8.out \
+ test_cdo.out
SCRIPTS32 = test50.out test70.out
diff -r c0df98c0770c src/testdir/Make_ming.mak
--- a/src/testdir/Make_ming.mak Sat Mar 21 14:20:16 2015 +0100
+++ b/src/testdir/Make_ming.mak Sat Mar 21 19:36:52 2015 -0700
@@ -75,7 +75,8 @@
test_qf_title.out \
test_signs.out \
test_textobjects.out \
- test_utf8.out
+ test_utf8.out \
+ test_cdo.out
SCRIPTS32 = test50.out test70.out
diff -r c0df98c0770c src/testdir/Make_os2.mak
--- a/src/testdir/Make_os2.mak Sat Mar 21 14:20:16 2015 +0100
+++ b/src/testdir/Make_os2.mak Sat Mar 21 19:36:52 2015 -0700
@@ -55,7 +55,8 @@
test_qf_title.out \
test_signs.out \
test_textobjects.out \
- test_utf8.out
+ test_utf8.out \
+ test_cdo.out
SCRIPTS_BENCH = bench_re_freeze.out
diff -r c0df98c0770c src/testdir/Make_vms.mms
--- a/src/testdir/Make_vms.mms Sat Mar 21 14:20:16 2015 +0100
+++ b/src/testdir/Make_vms.mms Sat Mar 21 19:36:52 2015 -0700
@@ -114,7 +114,8 @@
test_qf_title.out \
test_signs.out \
test_textobjects.out \
- test_utf8.out
+ test_utf8.out \
+ test_cdo.out
# Known problems:
# test17: ?
diff -r c0df98c0770c src/testdir/Makefile
--- a/src/testdir/Makefile Sat Mar 21 14:20:16 2015 +0100
+++ b/src/testdir/Makefile Sat Mar 21 19:36:52 2015 -0700
@@ -51,7 +51,8 @@
test_qf_title.out \
test_signs.out \
test_textobjects.out \
- test_utf8.out
+ test_utf8.out \
+ test_cdo.out
SCRIPTS_GUI = test16.out
diff -r c0df98c0770c src/testdir/test_cdo.in
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/testdir/test_cdo.in Sat Mar 21 19:36:52 2015 -0700
@@ -0,0 +1,88 @@
+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"
+: let v:errmsg=''
+: enew
+: exe "1,4" . a:cchar . "do let g:result .= expand('%') . ' ' . line('.') .
'L' . ' ' . col('.') . 'C' . nl"
+: if v:errmsg =~# 'No more items'
+: let g:result .= 'Range test failed' . nl
+: else
+: let g:result .= 'Range test passed' . nl
+: endif
+: " 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
+
+: 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"
+
+: " 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"
+
+: " 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
+
diff -r c0df98c0770c src/testdir/test_cdo.ok
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/testdir/test_cdo.ok Sat Mar 21 19:36:52 2015 -0700
@@ -0,0 +1,44 @@
+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
+Range test passed
+Unsaved file change 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
+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
+Range test passed
+Unsaved file change 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
+Xtestfile2 2L 5C
+