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.

10
  • 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, 2019 at 5: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, 2019 at 5: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, 2019 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, 2019 at 12:38
  • 2
    bug report filed github.com/vim/vim/issues/5102
    – D. Ben Knoble
    Oct 21, 2019 at 13:20

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Browse other questions tagged or ask your own question.