diff options
Diffstat (limited to 'src/nvim/ex_cmds2.c')
-rw-r--r-- | src/nvim/ex_cmds2.c | 44 |
1 files changed, 40 insertions, 4 deletions
diff --git a/src/nvim/ex_cmds2.c b/src/nvim/ex_cmds2.c index 87a6283310..57153cf5a1 100644 --- a/src/nvim/ex_cmds2.c +++ b/src/nvim/ex_cmds2.c @@ -1868,7 +1868,7 @@ void ex_argdelete(exarg_T *eap) } /* - * ":argdo", ":windo", ":bufdo", ":tabdo" + * ":argdo", ":windo", ":bufdo", ":tabdo", ":cdo", ":ldo", ":cfdo" and ":lfdo" */ void ex_listdo(exarg_T *eap) { @@ -1879,7 +1879,6 @@ void ex_listdo(exarg_T *eap) char_u *save_ei = NULL; char_u *p_shm_save; - if (eap->cmdidx != CMD_windo && eap->cmdidx != CMD_tabdo) /* Don't do syntax HL autocommands. Skipping the syntax file is a * great speed improvement. */ @@ -1914,7 +1913,10 @@ void ex_listdo(exarg_T *eap) default: break; } + buf_T *buf = curbuf; + size_t qf_size = 0; + /* set pcmark now */ if (eap->cmdidx == CMD_bufdo) { /* Advance to the first listed buffer after "eap->line1". */ @@ -1929,6 +1931,22 @@ void ex_listdo(exarg_T *eap) if (buf != NULL) { goto_buffer(eap, DOBUF_FIRST, FORWARD, buf->b_fnum); } + } else if (eap->cmdidx == CMD_cdo || eap->cmdidx == CMD_ldo || + eap->cmdidx == CMD_cfdo || eap->cmdidx == CMD_lfdo) { + qf_size = qf_get_size(eap); + assert(eap->line1 >= 0); + if (qf_size == 0 || (size_t)eap->line1 > qf_size) { + buf = NULL; + } else { + ex_cc(eap); + + buf = curbuf; + i = eap->line1 - 1; + if (eap->addr_count <= 0) { + // Default to all quickfix/location list entries. + eap->line2 = qf_size; + } + } } else { setpcmark(); } @@ -2009,9 +2027,27 @@ void ex_listdo(exarg_T *eap) set_option_value((char_u *)"shm", 0L, p_shm_save, 0); xfree(p_shm_save); - /* If autocommands took us elsewhere, quit here */ - if (curbuf->b_fnum != next_fnum) + // If autocommands took us elsewhere, quit here. + if (curbuf->b_fnum != next_fnum) { + break; + } + } + + if (eap->cmdidx == CMD_cdo || eap->cmdidx == CMD_ldo || + eap->cmdidx == CMD_cfdo || eap->cmdidx == CMD_lfdo) { + assert(i >= 0); + if ((size_t)i >= qf_size || i >= eap->line2) { break; + } + + size_t 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; + } } if (eap->cmdidx == CMD_windo) { |