Permalink
Browse files

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)
  • Loading branch information...
1 parent 4a4b821 commit aa23b379421aa214e6543b06c974594a25799b09 @brammool brammool committed Sep 8, 2015
@@ -511,6 +511,8 @@ followed by another Vim command:
:argdo
:autocmd
:bufdo
+ :cdo
+ :cfdo
:command
:cscope
:debug
@@ -521,6 +523,8 @@ followed by another Vim command:
:help
:helpfind
:lcscope
+ :ldo
+ :lfdo
:make
:normal
:perl
@@ -868,7 +868,8 @@ USING THE ARGUMENT LIST
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
@@ -1138,6 +1138,8 @@ tag command action ~
|: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
@@ -1296,6 +1298,8 @@ tag command action ~
|: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
@@ -248,7 +248,8 @@ LOOPING OVER TAB PAGES:
{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*
@@ -715,7 +715,8 @@ can also get to them with the buffer list commands, like ":bnext".
{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 @@ can also get to them with the buffer list commands, like ":bnext".
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: >
View
@@ -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;
@@ -270,6 +271,9 @@ EX(CMD_cclose, "cclose", ex_cclose,
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,6 +283,9 @@ EX(CMD_cexpr, "cexpr", ex_cexpr,
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,6 +736,9 @@ EX(CMD_lclose, "lclose", ex_cclose,
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,6 +754,9 @@ EX(CMD_lexpr, "lexpr", ex_cexpr,
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),
View
@@ -2429,7 +2429,7 @@ ex_argdelete(eap)
}
/*
- * ":argdo", ":windo", ":bufdo", ":tabdo"
+ * ":argdo", ":windo", ":bufdo", ":tabdo", ":cdo", ":ldo", ":cfdo" and ":lfdo"
*/
void
ex_listdo(eap)
@@ -2446,6 +2446,10 @@ ex_listdo(eap)
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,18 +2502,37 @@ ex_listdo(eap)
}
/* 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
+ 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)
+ 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,11 +2618,28 @@ ex_listdo(eap)
set_option_value((char_u *)"shm", 0L, p_shm_save, 0);
vim_free(p_shm_save);
- /* If autocommands took us elsewhere, quit here */
+ /* 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 */
View
@@ -135,7 +135,7 @@ static int getargopt __ARGS((exarg_T *eap));
#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 @@ do_one_cmd(cmdlinep, sourcing,
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 @@ do_one_cmd(cmdlinep, sourcing,
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,6 +2702,11 @@ do_one_cmd(cmdlinep, sourcing,
else
ea.line2 = ARGCOUNT;
break;
+ case ADDR_QUICKFIX:
+ ea.line2 = qf_get_size(&ea);
+ if (ea.line2 == 0)
+ ea.line2 = 1;
+ break;
}
}
@@ -3839,6 +3853,8 @@ set_one_cmd_context(xp, buff)
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,7 +3864,9 @@ set_one_cmd_context(xp, buff)
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,7 +4339,8 @@ skip_range(cmd, ctx)
* 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 */
@@ -4362,6 +4381,9 @@ get_address(ptr, addr_type, skip, to_other_file)
case ADDR_TABS:
lnum = CURRENT_TAB_NR;
break;
+ case ADDR_QUICKFIX:
+ lnum = qf_get_cur_valid_idx(eap);
+ break;
}
break;
@@ -4394,6 +4416,11 @@ get_address(ptr, addr_type, skip, to_other_file)
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 +4596,9 @@ get_address(ptr, addr_type, skip, to_other_file)
case ADDR_TABS:
lnum = CURRENT_TAB_NR;
break;
+ case ADDR_QUICKFIX:
+ lnum = qf_get_cur_valid_idx(eap);
+ break;
}
}
@@ -4707,6 +4737,10 @@ invalid_range(eap)
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 +5851,7 @@ static struct
{ADDR_TABS, "tabs"},
{ADDR_BUFFERS, "buffers"},
{ADDR_WINDOWS, "windows"},
+ {ADDR_QUICKFIX, "quickfix"},
{-1, NULL}
};
#endif
@@ -9224,7 +9259,7 @@ ex_copymove(eap)
{
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;
@@ -17,6 +17,9 @@ int bt_dontwrite_msg __ARGS((buf_T *buf));
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));
Oops, something went wrong.

0 comments on commit aa23b37

Please sign in to comment.