mirror of
https://github.com/vim/vim.git
synced 2025-09-23 03:43:49 -04:00
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)
This commit is contained in:
222
src/quickfix.c
222
src/quickfix.c
@@ -1373,7 +1373,7 @@ qf_clean_dir_stack(stackptr)
|
||||
/*
|
||||
* 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
|
||||
* Returns a pointer to the directory name or NULL if not found.
|
||||
* Cleans up intermediate directory entries.
|
||||
*
|
||||
* TODO: How to solve the following problem?
|
||||
@@ -2989,20 +2989,184 @@ get_mef_name()
|
||||
return name;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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_llast
|
||||
|| eap->cmdidx == CMD_ldo
|
||||
|| eap->cmdidx == CMD_lfdo)
|
||||
{
|
||||
qi = GET_LOC_LIST(curwin);
|
||||
if (qi == NULL)
|
||||
@@ -3012,34 +3176,51 @@ ex_cc(eap)
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
@@ -3049,15 +3230,24 @@ ex_cnext(eap)
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
Reference in New Issue
Block a user