Skip to content

Commit aa23b37

Browse files
committed
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)
1 parent 4a4b821 commit aa23b37

19 files changed

+506
-31
lines changed

runtime/doc/cmdline.txt

+4
Original file line numberDiff line numberDiff line change
@@ -511,6 +511,8 @@ followed by another Vim command:
511511
:argdo
512512
:autocmd
513513
:bufdo
514+
:cdo
515+
:cfdo
514516
:command
515517
:cscope
516518
:debug
@@ -521,6 +523,8 @@ followed by another Vim command:
521523
:help
522524
:helpfind
523525
:lcscope
526+
:ldo
527+
:lfdo
524528
:make
525529
:normal
526530
:perl

runtime/doc/editing.txt

+2-1
Original file line numberDiff line numberDiff line change
@@ -868,7 +868,8 @@ USING THE ARGUMENT LIST
868868
each file.
869869
{not in Vi} {not available when compiled without the
870870
|+listcmds| feature}
871-
Also see |:windo|, |:tabdo| and |:bufdo|.
871+
Also see |:windo|, |:tabdo|, |:bufdo|, |:cdo|, |:ldo|,
872+
|:cfdo| and |:lfdo|
872873

873874
Example: >
874875
:args *.c

runtime/doc/index.txt

+4
Original file line numberDiff line numberDiff line change
@@ -1138,6 +1138,8 @@ tag command action ~
11381138
|:cc| :cc go to specific error
11391139
|:cclose| :ccl[ose] close quickfix window
11401140
|:cd| :cd change directory
1141+
|:cdo| :cdo execute command in each valid error list entry
1142+
|:cfdo| :cfd[o] execute command in each file in error list
11411143
|:center| :ce[nter] format lines at the center
11421144
|:cexpr| :cex[pr] read errors from expr and jump to first
11431145
|:cfile| :cf[ile] read file with error messages and jump to first
@@ -1296,6 +1298,8 @@ tag command action ~
12961298
|:lchdir| :lch[dir] change directory locally
12971299
|:lclose| :lcl[ose] close location window
12981300
|:lcscope| :lcs[cope] like ":cscope" but uses location list
1301+
|:ldo| :ld[o] execute command in valid location list entries
1302+
|:lfdo| :lfd[o] execute command in each file in location list
12991303
|:left| :le[ft] left align lines
13001304
|:leftabove| :lefta[bove] make split window appear left or above
13011305
|:let| :let assign a value to a variable or option

runtime/doc/tabpage.txt

+2-1
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,8 @@ LOOPING OVER TAB PAGES:
248248
{cmd} must not open or close tab pages or reorder them.
249249
{not in Vi} {not available when compiled without the
250250
|+listcmds| feature}
251-
Also see |:windo|, |:argdo| and |:bufdo|.
251+
Also see |:windo|, |:argdo|, |:bufdo|, |:cdo|, |:ldo|, |:cfdo|
252+
and |:lfdo|
252253

253254
==============================================================================
254255
3. Other items *tab-page-other*

runtime/doc/windows.txt

+4-2
Original file line numberDiff line numberDiff line change
@@ -715,7 +715,8 @@ can also get to them with the buffer list commands, like ":bnext".
715715
{cmd} must not open or close windows or reorder them.
716716
{not in Vi} {not available when compiled without the
717717
|+listcmds| feature}
718-
Also see |:tabdo|, |:argdo| and |:bufdo|.
718+
Also see |:tabdo|, |:argdo|, |:bufdo|, |:cdo|, |:ldo|,
719+
|:cfdo| and |:lfdo|
719720

720721
*:bufdo*
721722
:[range]bufdo[!] {cmd} Execute {cmd} in each buffer in the buffer list or if
@@ -743,7 +744,8 @@ can also get to them with the buffer list commands, like ":bnext".
743744
each buffer.
744745
{not in Vi} {not available when compiled without the
745746
|+listcmds| feature}
746-
Also see |:tabdo|, |:argdo| and |:windo|.
747+
Also see |:tabdo|, |:argdo|, |:windo|, |:cdo|, |:ldo|,
748+
|:cfdo| and |:lfdo|
747749

748750
Examples: >
749751

src/ex_cmds.h

+13
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@
6565
#define ADDR_LOADED_BUFFERS 3
6666
#define ADDR_BUFFERS 4
6767
#define ADDR_TABS 5
68+
#define ADDR_QUICKFIX 6
6869

6970
#ifndef DO_DECLARE_EXCMD
7071
typedef struct exarg exarg_T;
@@ -270,6 +271,9 @@ EX(CMD_cclose, "cclose", ex_cclose,
270271
EX(CMD_cd, "cd", ex_cd,
271272
BANG|FILE1|TRLBAR|CMDWIN,
272273
ADDR_LINES),
274+
EX(CMD_cdo, "cdo", ex_listdo,
275+
BANG|NEEDARG|EXTRA|NOTRLCOM|RANGE|NOTADR|DFLALL,
276+
ADDR_QUICKFIX),
273277
EX(CMD_center, "center", ex_align,
274278
TRLBAR|RANGE|WHOLEFOLD|EXTRA|CMDWIN|MODIFY,
275279
ADDR_LINES),
@@ -279,6 +283,9 @@ EX(CMD_cexpr, "cexpr", ex_cexpr,
279283
EX(CMD_cfile, "cfile", ex_cfile,
280284
TRLBAR|FILE1|BANG,
281285
ADDR_LINES),
286+
EX(CMD_cfdo, "cfdo", ex_listdo,
287+
BANG|NEEDARG|EXTRA|NOTRLCOM|RANGE|NOTADR|DFLALL,
288+
ADDR_QUICKFIX),
282289
EX(CMD_cfirst, "cfirst", ex_cc,
283290
RANGE|NOTADR|COUNT|TRLBAR|BANG,
284291
ADDR_LINES),
@@ -729,6 +736,9 @@ EX(CMD_lclose, "lclose", ex_cclose,
729736
EX(CMD_lcscope, "lcscope", do_cscope,
730737
EXTRA|NOTRLCOM|XFILE,
731738
ADDR_LINES),
739+
EX(CMD_ldo, "ldo", ex_listdo,
740+
BANG|NEEDARG|EXTRA|NOTRLCOM|RANGE|NOTADR|DFLALL,
741+
ADDR_QUICKFIX),
732742
EX(CMD_left, "left", ex_align,
733743
TRLBAR|RANGE|WHOLEFOLD|EXTRA|CMDWIN|MODIFY,
734744
ADDR_LINES),
@@ -744,6 +754,9 @@ EX(CMD_lexpr, "lexpr", ex_cexpr,
744754
EX(CMD_lfile, "lfile", ex_cfile,
745755
TRLBAR|FILE1|BANG,
746756
ADDR_LINES),
757+
EX(CMD_lfdo, "lfdo", ex_listdo,
758+
BANG|NEEDARG|EXTRA|NOTRLCOM|RANGE|NOTADR|DFLALL,
759+
ADDR_QUICKFIX),
747760
EX(CMD_lfirst, "lfirst", ex_cc,
748761
RANGE|NOTADR|COUNT|TRLBAR|BANG,
749762
ADDR_LINES),

src/ex_cmds2.c

+46-6
Original file line numberDiff line numberDiff line change
@@ -2429,7 +2429,7 @@ ex_argdelete(eap)
24292429
}
24302430

24312431
/*
2432-
* ":argdo", ":windo", ":bufdo", ":tabdo"
2432+
* ":argdo", ":windo", ":bufdo", ":tabdo", ":cdo", ":ldo", ":cfdo" and ":lfdo"
24332433
*/
24342434
void
24352435
ex_listdo(eap)
@@ -2446,6 +2446,10 @@ ex_listdo(eap)
24462446
char_u *save_ei = NULL;
24472447
#endif
24482448
char_u *p_shm_save;
2449+
#ifdef FEAT_QUICKFIX
2450+
int qf_size;
2451+
int qf_idx;
2452+
#endif
24492453

24502454
#ifndef FEAT_WINDOWS
24512455
if (eap->cmdidx == CMD_windo)
@@ -2498,18 +2502,37 @@ ex_listdo(eap)
24982502
}
24992503
/* set pcmark now */
25002504
if (eap->cmdidx == CMD_bufdo)
2501-
{
2505+
{
25022506
/* Advance to the first listed buffer after "eap->line1". */
2503-
for (buf = firstbuf; buf != NULL && (buf->b_fnum < eap->line1
2507+
for (buf = firstbuf; buf != NULL && (buf->b_fnum < eap->line1
25042508
|| !buf->b_p_bl); buf = buf->b_next)
25052509
if (buf->b_fnum > eap->line2)
25062510
{
25072511
buf = NULL;
25082512
break;
25092513
}
2510-
if (buf != NULL)
2514+
if (buf != NULL)
25112515
goto_buffer(eap, DOBUF_FIRST, FORWARD, buf->b_fnum);
2512-
}
2516+
}
2517+
#ifdef FEAT_QUICKFIX
2518+
else if (eap->cmdidx == CMD_cdo || eap->cmdidx == CMD_ldo
2519+
|| eap->cmdidx == CMD_cfdo || eap->cmdidx == CMD_lfdo)
2520+
{
2521+
qf_size = qf_get_size(eap);
2522+
if (qf_size <= 0 || eap->line1 > qf_size)
2523+
buf = NULL;
2524+
else
2525+
{
2526+
ex_cc(eap);
2527+
2528+
buf = curbuf;
2529+
i = eap->line1 - 1;
2530+
if (eap->addr_count <= 0)
2531+
/* default is all the quickfix/location list entries */
2532+
eap->line2 = qf_size;
2533+
}
2534+
}
2535+
#endif
25132536
else
25142537
setpcmark();
25152538
listcmd_busy = TRUE; /* avoids setting pcmark below */
@@ -2595,11 +2618,28 @@ ex_listdo(eap)
25952618
set_option_value((char_u *)"shm", 0L, p_shm_save, 0);
25962619
vim_free(p_shm_save);
25972620

2598-
/* If autocommands took us elsewhere, quit here */
2621+
/* If autocommands took us elsewhere, quit here. */
25992622
if (curbuf->b_fnum != next_fnum)
26002623
break;
26012624
}
26022625

2626+
#ifdef FEAT_QUICKFIX
2627+
if (eap->cmdidx == CMD_cdo || eap->cmdidx == CMD_ldo
2628+
|| eap->cmdidx == CMD_cfdo || eap->cmdidx == CMD_lfdo)
2629+
{
2630+
if (i >= qf_size || i >= eap->line2)
2631+
break;
2632+
2633+
qf_idx = qf_get_cur_idx(eap);
2634+
2635+
ex_cnext(eap);
2636+
2637+
/* If jumping to the next quickfix entry fails, quit here */
2638+
if (qf_get_cur_idx(eap) == qf_idx)
2639+
break;
2640+
}
2641+
#endif
2642+
26032643
if (eap->cmdidx == CMD_windo)
26042644
{
26052645
validate_cursor(); /* cursor may have moved */

src/ex_docmd.c

+39-4
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ static int getargopt __ARGS((exarg_T *eap));
135135
#endif
136136

137137
static int check_more __ARGS((int, int));
138-
static linenr_T get_address __ARGS((char_u **, int addr_type, int skip, int to_other_file));
138+
static linenr_T get_address __ARGS((exarg_T *, char_u **, int addr_type, int skip, int to_other_file));
139139
static void get_flags __ARGS((exarg_T *eap));
140140
#if !defined(FEAT_PERL) \
141141
|| !defined(FEAT_PYTHON) || !defined(FEAT_PYTHON3) \
@@ -2173,9 +2173,12 @@ do_one_cmd(cmdlinep, sourcing,
21732173
lnum = CURRENT_TAB_NR;
21742174
ea.line2 = lnum;
21752175
break;
2176+
case ADDR_QUICKFIX:
2177+
ea.line2 = qf_get_cur_valid_idx(&ea);
2178+
break;
21762179
}
21772180
ea.cmd = skipwhite(ea.cmd);
2178-
lnum = get_address(&ea.cmd, ea.addr_type, ea.skip, ea.addr_count == 0);
2181+
lnum = get_address(&ea, &ea.cmd, ea.addr_type, ea.skip, ea.addr_count == 0);
21792182
if (ea.cmd == NULL) /* error detected */
21802183
goto doend;
21812184
if (lnum == MAXLNUM)
@@ -2233,6 +2236,12 @@ do_one_cmd(cmdlinep, sourcing,
22332236
ea.line2 = ARGCOUNT;
22342237
}
22352238
break;
2239+
case ADDR_QUICKFIX:
2240+
ea.line1 = 1;
2241+
ea.line2 = qf_get_size(&ea);
2242+
if (ea.line2 == 0)
2243+
ea.line2 = 1;
2244+
break;
22362245
}
22372246
++ea.addr_count;
22382247
}
@@ -2693,6 +2702,11 @@ do_one_cmd(cmdlinep, sourcing,
26932702
else
26942703
ea.line2 = ARGCOUNT;
26952704
break;
2705+
case ADDR_QUICKFIX:
2706+
ea.line2 = qf_get_size(&ea);
2707+
if (ea.line2 == 0)
2708+
ea.line2 = 1;
2709+
break;
26962710
}
26972711
}
26982712

@@ -3839,6 +3853,8 @@ set_one_cmd_context(xp, buff)
38393853
case CMD_botright:
38403854
case CMD_browse:
38413855
case CMD_bufdo:
3856+
case CMD_cdo:
3857+
case CMD_cfdo:
38423858
case CMD_confirm:
38433859
case CMD_debug:
38443860
case CMD_folddoclosed:
@@ -3848,7 +3864,9 @@ set_one_cmd_context(xp, buff)
38483864
case CMD_keepjumps:
38493865
case CMD_keepmarks:
38503866
case CMD_keeppatterns:
3867+
case CMD_ldo:
38513868
case CMD_leftabove:
3869+
case CMD_lfdo:
38523870
case CMD_lockmarks:
38533871
case CMD_noautocmd:
38543872
case CMD_noswapfile:
@@ -4321,7 +4339,8 @@ skip_range(cmd, ctx)
43214339
* Return MAXLNUM when no Ex address was found.
43224340
*/
43234341
static linenr_T
4324-
get_address(ptr, addr_type, skip, to_other_file)
4342+
get_address(eap, ptr, addr_type, skip, to_other_file)
4343+
exarg_T *eap;
43254344
char_u **ptr;
43264345
int addr_type; /* flag: one of ADDR_LINES, ... */
43274346
int skip; /* only skip the address, don't use it */
@@ -4362,6 +4381,9 @@ get_address(ptr, addr_type, skip, to_other_file)
43624381
case ADDR_TABS:
43634382
lnum = CURRENT_TAB_NR;
43644383
break;
4384+
case ADDR_QUICKFIX:
4385+
lnum = qf_get_cur_valid_idx(eap);
4386+
break;
43654387
}
43664388
break;
43674389

@@ -4394,6 +4416,11 @@ get_address(ptr, addr_type, skip, to_other_file)
43944416
case ADDR_TABS:
43954417
lnum = LAST_TAB_NR;
43964418
break;
4419+
case ADDR_QUICKFIX:
4420+
lnum = qf_get_size(eap);
4421+
if (lnum == 0)
4422+
lnum = 1;
4423+
break;
43974424
}
43984425
break;
43994426

@@ -4569,6 +4596,9 @@ get_address(ptr, addr_type, skip, to_other_file)
45694596
case ADDR_TABS:
45704597
lnum = CURRENT_TAB_NR;
45714598
break;
4599+
case ADDR_QUICKFIX:
4600+
lnum = qf_get_cur_valid_idx(eap);
4601+
break;
45724602
}
45734603
}
45744604

@@ -4707,6 +4737,10 @@ invalid_range(eap)
47074737
if (eap->line2 > LAST_TAB_NR)
47084738
return (char_u *)_(e_invrange);
47094739
break;
4740+
case ADDR_QUICKFIX:
4741+
if (eap->line2 != 1 && eap->line2 > qf_get_size(eap))
4742+
return (char_u *)_(e_invrange);
4743+
break;
47104744
}
47114745
}
47124746
return NULL;
@@ -5817,6 +5851,7 @@ static struct
58175851
{ADDR_TABS, "tabs"},
58185852
{ADDR_BUFFERS, "buffers"},
58195853
{ADDR_WINDOWS, "windows"},
5854+
{ADDR_QUICKFIX, "quickfix"},
58205855
{-1, NULL}
58215856
};
58225857
#endif
@@ -9224,7 +9259,7 @@ ex_copymove(eap)
92249259
{
92259260
long n;
92269261

9227-
n = get_address(&eap->arg, eap->addr_type, FALSE, FALSE);
9262+
n = get_address(eap, &eap->arg, eap->addr_type, FALSE, FALSE);
92289263
if (eap->arg == NULL) /* error detected */
92299264
{
92309265
eap->nextcmd = NULL;

src/proto/quickfix.pro

+3
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ int bt_dontwrite_msg __ARGS((buf_T *buf));
1717
int buf_hide __ARGS((buf_T *buf));
1818
int grep_internal __ARGS((cmdidx_T cmdidx));
1919
void ex_make __ARGS((exarg_T *eap));
20+
int qf_get_size __ARGS((exarg_T *eap));
21+
int qf_get_cur_idx __ARGS((exarg_T *eap));
22+
int qf_get_cur_valid_idx __ARGS((exarg_T *eap));
2023
void ex_cc __ARGS((exarg_T *eap));
2124
void ex_cnext __ARGS((exarg_T *eap));
2225
void ex_cfile __ARGS((exarg_T *eap));

0 commit comments

Comments
 (0)