2

:h :cdo says:

            When an error is detected execution stops.
            The last buffer (or where an error occurred) becomes
            the current buffer.

Let's see what really happens:

Prepare test file a:

dog0 dog1
dog2 dog3

Prepare test file b:

dog4 dog5
dog6 dog7

set up quickfix for all dogs :

vimgrep /dog\d/g a b

Create a test command:

" call cdo to change dog to cat, throw an error in the first n entries
command! -nargs=1 TestCdo call Test(<q-args>)

function! Test(error_count)
  let s:error_count = a:error_count
  let s:error_index = 0

  " restore a b
  cdo e!

  cdo call s:test_impl()
endfunction

function! s:test_impl()
  if s:error_index < s:error_count
    let s:error_index += 1
    throw 1
  endif
  norm! c3lcat
endfunction

Test result:

Test        dogs     cats
---------------------------
TestCdo 1   dog0     cat1-7
TestCdo 2   dog0-1   cat2-7
TestCdo 3   dog0-2   cat3-7
TestCdo 4   dog0-7
TestCdo 5   dog0-7
TestCdo 6   dog0-7
TestCdo 7   dog0-7
TestCdo 8   dog0-7

It looks like cdo stops only if dog3 throws an error, dog3 is the last entry in a, does that mean cdo only stops if last entry in a buffer cause an error? That's very disturbing, especially if you have hundreds of files to deal with. Is this a bug?

I know you can create macro such as qp@q:cnext<cr>q to make it stop at first error, this question is not about that.

I'm using vim8.1-2127 on ubuntu16.04.

Update0

@Ralf's comment shows that cdo may continue to next buffer if all entries in a buffer throws an error.

Update1

@D.Ben.Knoble filed a bug report.

dedowsdi
  • 6,248
  • 1
  • 18
  • 31
  • 1
    I just tested :cdo echo x and Vim printed E121: Undefined variable: x for every entry in the qf list. I expected it to stop after the first error. Either I'm totally misinterpreting the docs or it is a bug. – Ralf Oct 21 '19 at 05:25
  • @Ralf Just tried your :cdo echo x, I thout it would stop after the first 4 errors, but it didn't, which makes it even more mysterious. – dedowsdi Oct 21 '19 at 05:46
  • Exactly, but why throw on the first count entries? I would have expected to throw once, at the given index. I realize now your comment says error in the first n, but why? How is that measuring what you want? You might also want to try with only a single error at position n, and also use the input 0. That could help give a more complete picture of whats happening. Also, using :debug could help trace the execution better. To your bold q: your tests for 4+ prove that cdo did not stop every time the last entry in a buffer causes an error. – D. Ben Knoble Oct 21 '19 at 12:12
  • @D.BenKnoble The doc says cdo stops if an error is detected, my goal is to prove it doesn't, the bold conclusion is in fact a question, there is a ? after it, as i don't have solid prove, it's just an observation, Ralf's comment already shows that my conclusion is wrong. Sorry if my test examples give you confusion. – dedowsdi Oct 21 '19 at 12:38
  • I understand your goal, but your test seems far too complicated. Ralf's is simpler, and there are others. Again, I'm not sure why throwing n errors is better than throwing 1 or all, but I'll leave that be; perhaps I've just misunderstood. Please re-read my comment, where I state To your bold q:—I was attempting to answer your question, using an observation about your results. They give effective proof that the claim in the q is false. You might want to check :TestCdo 0, as I said, or try with only a single error (instead of many). Try with :debug. Then file a bug report. – D. Ben Knoble Oct 21 '19 at 13:12
  • 2
    bug report filed https://github.com/vim/vim/issues/5102 – D. Ben Knoble Oct 21 '19 at 13:20
  • @D.BenKnoble The tests for 4 and 4+ shows that all dogs in b is not changed, it doesn't conflict with my observation. I just tried to throw 1 instead of n, the result didn't conflict with my observation too, only throw in dog3 can stop cdo from continue to b, only throw in dog3 can save dog4-7 from being changed to cat4-7 – dedowsdi Oct 21 '19 at 13:34
  • @dedowsdi agh, i got mixed up again. I see how your tests indicate something relating to the last error in a buffer. But still, that shouldnt be expected. Thanks for clearing that up. – D. Ben Knoble Oct 21 '19 at 13:46
  • @D.BenKnoble There is a patch available for testing. It was send to the vimdev mailing list and didn't make it to github. – Ralf Oct 22 '19 at 17:58
  • All: I've tested the patch and it gives more global-like behavior – D. Ben Knoble Oct 23 '19 at 13:58

0 Answers0