Skip to content

Instantly share code, notes, and snippets.

@fwalch
Created August 4, 2015 12:38
Show Gist options
  • Save fwalch/4853ddb4505aafb7b5c1 to your computer and use it in GitHub Desktop.
Save fwalch/4853ddb4505aafb7b5c1 to your computer and use it in GitHub Desktop.
cdo patch interdiff
diff -u b/runtime/doc/quickfix.txt b/runtime/doc/quickfix.txt
--- b/runtime/doc/quickfix.txt Sat Mar 21 19:36:52 2015 -0700
+++ b/runtime/doc/quickfix.txt Fri Jul 24 20:23:43 2015 -0700
@@ -350,8 +350,8 @@
|:cdo|, |:ldo| and |:lfdo|.
*:ldo*
-:ld[o][!] {cmd} Execute {cmd} in each entry in the location list for
- the current window.
+:ld[o][!] {cmd} Execute {cmd} in each valid entry in the location list
+ for the current window.
It works like doing this: >
:lfirst
:{cmd}
diff -u b/src/ex_cmds.h b/src/ex_cmds.h
--- b/src/ex_cmds.h Sat Mar 21 19:36:52 2015 -0700
+++ b/src/ex_cmds.h Fri Jul 24 20:23:43 2015 -0700
@@ -65,6 +65,7 @@
#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;
@@ -272,7 +273,7 @@
ADDR_LINES),
EX(CMD_cdo, "cdo", ex_listdo,
BANG|NEEDARG|EXTRA|NOTRLCOM|RANGE|NOTADR|DFLALL,
- ADDR_LINES),
+ ADDR_QUICKFIX),
EX(CMD_center, "center", ex_align,
TRLBAR|RANGE|WHOLEFOLD|EXTRA|CMDWIN|MODIFY,
ADDR_LINES),
@@ -282,9 +283,11 @@
EX(CMD_cfile, "cfile", ex_cfile,
TRLBAR|FILE1|BANG,
ADDR_LINES),
+/* Even though 'cfdo' is alphabetically lower than 'cfile', it is after 'cfile'
+ * in this cmd list to support the existing ":cf" abbreviation */
EX(CMD_cfdo, "cfdo", ex_listdo,
BANG|NEEDARG|EXTRA|NOTRLCOM|RANGE|NOTADR|DFLALL,
- ADDR_LINES),
+ ADDR_QUICKFIX),
EX(CMD_cfirst, "cfirst", ex_cc,
RANGE|NOTADR|COUNT|TRLBAR|BANG,
ADDR_LINES),
@@ -737,7 +740,7 @@
ADDR_LINES),
EX(CMD_ldo, "ldo", ex_listdo,
BANG|NEEDARG|EXTRA|NOTRLCOM|RANGE|NOTADR|DFLALL,
- ADDR_LINES),
+ ADDR_QUICKFIX),
EX(CMD_left, "left", ex_align,
TRLBAR|RANGE|WHOLEFOLD|EXTRA|CMDWIN|MODIFY,
ADDR_LINES),
@@ -753,9 +756,11 @@
EX(CMD_lfile, "lfile", ex_cfile,
TRLBAR|FILE1|BANG,
ADDR_LINES),
+/* Even though 'lfdo' is alphabetically lower than 'lfile', it is after 'lfile'
+ * in this cmd list to support the existing ":lf" abbreviation */
EX(CMD_lfdo, "lfdo", ex_listdo,
BANG|NEEDARG|EXTRA|NOTRLCOM|RANGE|NOTADR|DFLALL,
- ADDR_LINES),
+ ADDR_QUICKFIX),
EX(CMD_lfirst, "lfirst", ex_cc,
RANGE|NOTADR|COUNT|TRLBAR|BANG,
ADDR_LINES),
diff -u b/src/ex_cmds2.c b/src/ex_cmds2.c
--- b/src/ex_cmds2.c Sat Mar 21 19:36:52 2015 -0700
+++ b/src/ex_cmds2.c Fri Jul 24 20:23:43 2015 -0700
@@ -2448,6 +2448,7 @@
char_u *p_shm_save;
#ifdef FEAT_QUICKFIX
int qf_size;
+ int qf_idx;
#endif
#ifndef FEAT_WINDOWS
@@ -2628,7 +2629,13 @@
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
diff -u b/src/ex_docmd.c b/src/ex_docmd.c
--- b/src/ex_docmd.c Sat Mar 21 19:36:52 2015 -0700
+++ b/src/ex_docmd.c Fri Jul 24 20:23:43 2015 -0700
@@ -135,7 +135,7 @@
#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 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,9 +2173,12 @@
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.cmd, ea.addr_type, ea.skip, ea.addr_count == 0);
+ 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,6 +2236,12 @@
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;
}
@@ -2692,6 +2701,11 @@
else
ea.line2 = ARGCOUNT;
break;
+ case ADDR_QUICKFIX:
+ ea.line2 = qf_get_size(&ea);
+ if (ea.line2 == 0)
+ ea.line2 = 1;
+ break;
}
}
@@ -4324,7 +4338,8 @@
* Return MAXLNUM when no Ex address was found.
*/
static linenr_T
-get_address(ptr, addr_type, skip, to_other_file)
+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 */
@@ -4365,6 +4380,9 @@
case ADDR_TABS:
lnum = CURRENT_TAB_NR;
break;
+ case ADDR_QUICKFIX:
+ lnum = qf_get_cur_valid_idx(eap);
+ break;
}
break;
@@ -4397,6 +4415,11 @@
case ADDR_TABS:
lnum = LAST_TAB_NR;
break;
+ case ADDR_QUICKFIX:
+ lnum = qf_get_size(eap);
+ if (lnum == 0)
+ lnum = 1;
+ break;
}
break;
@@ -4569,6 +4592,9 @@
case ADDR_TABS:
lnum = CURRENT_TAB_NR;
break;
+ case ADDR_QUICKFIX:
+ lnum = qf_get_cur_valid_idx(eap);
+ break;
}
}
@@ -4707,6 +4733,10 @@
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,6 +5847,7 @@
{ADDR_TABS, "tabs"},
{ADDR_BUFFERS, "buffers"},
{ADDR_WINDOWS, "windows"},
+ {ADDR_QUICKFIX, "quickfix"},
{-1, NULL}
};
#endif
@@ -9224,7 +9255,7 @@
{
long n;
- n = get_address(&eap->arg, eap->addr_type, FALSE, FALSE);
+ n = get_address(eap, &eap->arg, eap->addr_type, FALSE, FALSE);
if (eap->arg == NULL) /* error detected */
{
eap->nextcmd = NULL;
diff -u b/src/proto/quickfix.pro b/src/proto/quickfix.pro
--- b/src/proto/quickfix.pro Sat Mar 21 19:36:52 2015 -0700
+++ b/src/proto/quickfix.pro Fri Jul 24 20:23:43 2015 -0700
@@ -30,3 +30,4 @@
int qf_get_size __ARGS((exarg_T *eap));
-int qf_get_buffers __ARGS((garray_T *gap, int qfl));
+int qf_get_cur_idx __ARGS((exarg_T *eap));
+int qf_get_cur_valid_idx __ARGS((exarg_T *eap));
/* vim: set ft=c : */
diff -u b/src/quickfix.c b/src/quickfix.c
--- b/src/quickfix.c Sat Mar 21 19:36:52 2015 -0700
+++ b/src/quickfix.c Fri Jul 24 20:23:43 2015 -0700
@@ -3014,6 +3014,7 @@
++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)
@@ -3022,12 +3023,84 @@
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.
@@ -3052,6 +3125,7 @@
i++, qfp = qfp->qf_next)
{
if (qfp->qf_valid)
+ {
if (fdo)
{
if (qfp->qf_fnum > 0 && qfp->qf_fnum != prev_fnum)
@@ -3063,6 +3137,7 @@
}
else
eidx++;
+ }
if (eidx == n)
break;
diff -u b/src/testdir/Make_amiga.mak b/src/testdir/Make_amiga.mak
--- b/src/testdir/Make_amiga.mak Sat Mar 21 19:36:52 2015 -0700
+++ b/src/testdir/Make_amiga.mak Fri Jul 24 20:23:43 2015 -0700
@@ -54,8 +54,7 @@
test_qf_title.out \
test_signs.out \
test_textobjects.out \
- test_utf8.out \
- test_cdo.out
+ test_utf8.out
.SUFFIXES: .in .out
@@ -65,7 +64,8 @@
test_set.out \
test_signs.out \
test_textobjects.out \
- test_utf8.out
+ test_utf8.out \
+ test_cdo.out
.SUFFIXES: .in .out
diff -u b/src/testdir/Make_dos.mak b/src/testdir/Make_dos.mak
--- b/src/testdir/Make_dos.mak Sat Mar 21 19:36:52 2015 -0700
+++ b/src/testdir/Make_dos.mak Fri Jul 24 20:23:43 2015 -0700
@@ -53,8 +53,7 @@
test_qf_title.out \
test_signs.out \
test_textobjects.out \
- test_utf8.out \
- test_cdo.out
+ test_utf8.out
SCRIPTS32 = test50.out test70.out
@@ -64,7 +63,8 @@
test_set.out \
test_signs.out \
test_textobjects.out \
- test_utf8.out
+ test_utf8.out \
+ test_cdo.out
SCRIPTS32 = test50.out test70.out
diff -u b/src/testdir/Make_ming.mak b/src/testdir/Make_ming.mak
--- b/src/testdir/Make_ming.mak Sat Mar 21 19:36:52 2015 -0700
+++ b/src/testdir/Make_ming.mak Fri Jul 24 20:23:43 2015 -0700
@@ -75,8 +75,7 @@
test_qf_title.out \
test_signs.out \
test_textobjects.out \
- test_utf8.out \
- test_cdo.out
+ test_utf8.out
SCRIPTS32 = test50.out test70.out
@@ -86,7 +85,8 @@
test_set.out \
test_signs.out \
test_textobjects.out \
- test_utf8.out
+ test_utf8.out \
+ test_cdo.out
SCRIPTS32 = test50.out test70.out
diff -u b/src/testdir/Make_os2.mak b/src/testdir/Make_os2.mak
--- b/src/testdir/Make_os2.mak Sat Mar 21 19:36:52 2015 -0700
+++ b/src/testdir/Make_os2.mak Fri Jul 24 20:23:43 2015 -0700
@@ -55,8 +55,7 @@
test_qf_title.out \
test_signs.out \
test_textobjects.out \
- test_utf8.out \
- test_cdo.out
+ test_utf8.out
SCRIPTS_BENCH = bench_re_freeze.out
@@ -66,7 +65,8 @@
test_set.out \
test_signs.out \
test_textobjects.out \
- test_utf8.out
+ test_utf8.out \
+ test_cdo.out
SCRIPTS_BENCH = bench_re_freeze.out
diff -u b/src/testdir/Make_vms.mms b/src/testdir/Make_vms.mms
--- b/src/testdir/Make_vms.mms Sat Mar 21 19:36:52 2015 -0700
+++ b/src/testdir/Make_vms.mms Fri Jul 24 20:23:43 2015 -0700
@@ -114,8 +114,7 @@
test_qf_title.out \
test_signs.out \
test_textobjects.out \
- test_utf8.out \
- test_cdo.out
+ test_utf8.out
# Known problems:
# test17: ?
@@ -125,7 +124,8 @@
test_set.out \
test_signs.out \
test_textobjects.out \
- test_utf8.out
+ test_utf8.out \
+ test_cdo.out
# Known problems:
# test17: ?
diff -u b/src/testdir/Makefile b/src/testdir/Makefile
--- b/src/testdir/Makefile Sat Mar 21 19:36:52 2015 -0700
+++ b/src/testdir/Makefile Fri Jul 24 20:23:43 2015 -0700
@@ -51,8 +51,7 @@
test_qf_title.out \
test_signs.out \
test_textobjects.out \
- test_utf8.out \
- test_cdo.out
+ test_utf8.out
SCRIPTS_GUI = test16.out
@@ -62,7 +61,8 @@
test_set.out \
test_signs.out \
test_textobjects.out \
- test_utf8.out
+ test_utf8.out \
+ test_cdo.out
SCRIPTS_GUI = test16.out
diff -u b/src/testdir/test_cdo.in b/src/testdir/test_cdo.in
--- b/src/testdir/test_cdo.in Sat Mar 21 19:36:52 2015 -0700
+++ b/src/testdir/test_cdo.in Fri Jul 24 20:23:43 2015 -0700
@@ -27,14 +27,14 @@
: 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=''
+: " Range test commands
: 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
+: 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"
@@ -58,6 +58,11 @@
: 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']"
@@ -68,6 +73,10 @@
: 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']"
diff -u b/src/testdir/test_cdo.ok b/src/testdir/test_cdo.ok
--- b/src/testdir/test_cdo.ok Sat Mar 21 19:36:52 2015 -0700
+++ b/src/testdir/test_cdo.ok Fri Jul 24 20:23:43 2015 -0700
@@ -8,7 +8,10 @@
Xtestfile1 1L 3C
Xtestfile2 2L 2C
Xtestfile3 3L 1C
-Range test passed
+Xtestfile1 1L 3C
+Xtestfile2 2L 2C
+Xtestfile3 3L 1C
+Xtestfile2 2L 2C
Unsaved file change test passed
Xtestfile2 2L 2C
Xtestfile3 3L 1C
@@ -18,6 +21,13 @@
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
@@ -30,7 +40,10 @@
Xtestfile1 1L 3C
Xtestfile2 2L 2C
Xtestfile3 3L 1C
-Range test passed
+Xtestfile1 1L 3C
+Xtestfile2 2L 2C
+Xtestfile3 3L 1C
+Xtestfile2 2L 2C
Unsaved file change test passed
Xtestfile2 2L 2C
Xtestfile3 3L 1C
@@ -41,4 +54,11 @@
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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment