Describe the bug
:cdo is expected to stop when it encounters an error. As far as I (and others) can tell, it does not.
Additionally, the test for this seems, well, broken:
" If the executed command fails, then the operation should be aborted
enew!
let subst_count = 0
exe "silent!" . Xdo . " s/Line/xLine/ | let subst_count += 1"
if subst_count != 1 || getline('.') != 'xLine1'
call add(v:errors, 'Abort command on error test failed')
endif
I cannot see how the given :cdo command is expected to fail performing the substitute; further, the test actually wants it to succeed, and only "fails" if the substitute is not done! This to me is not "abort on failure" but rather "succeeds at this particular substitute operation."
To Reproduce
Detailed steps to reproduce the behavior:
vim --clean (or gvim --clean, etc.):help :cdo:vimgrep /cdo/ %:cdo norm! cwtest:messages to see far more than just one error; if you check :cc, you'll see we are not stuck on the first location, but have traversed the entire list.Expected behavior
:cdo aborts on a failure and stops traversing the list.
Environment (please complete the following information):
VIM - Vi IMproved 8.1 (2018 May 18, compilé Aug 16 2019 02:18:16)
Version macOS
Rustines incluses : 1-1850
Compilé par Homebrew
Énorme version sans interface graphique.
Fonctionnalités incluses (+) ou non (-) :
+acl -farsi -mouse_sysmouse -tag_any_white
+arabic +file_in_path +mouse_urxvt -tcl
+autocmd +find_in_path +mouse_xterm +termguicolors
+autochdir +float +multi_byte +terminal
-autoservername +folding +multi_lang +terminfo
-balloon_eval -footer -mzscheme +termresponse
+balloon_eval_term +fork() +netbeans_intg +textobjects
-browse +gettext +num64 +textprop
++builtin_terms -hangul_input +packages +timers
+byte_offset +iconv +path_extra +title
+channel +insert_expand +perl -toolbar
+cindent +job +persistent_undo +user_commands
-clientserver +jumplist +postscript +vartabs
+clipboard +keymap +printer +vertsplit
+cmdline_compl +lambda +profile +virtualedit
+cmdline_hist +langmap -python +visual
+cmdline_info +libcall +python3 +visualextra
+comments +linebreak +quickfix +viminfo
+conceal +lispindent +reltime +vreplace
+cryptv +listcmds +rightleft +wildignore
+cscope +localmap +ruby +wildmenu
+cursorbind +lua +scrollbind +windows
+cursorshape +menu +signs +writebackup
+dialog_con +mksession +smartindent -X11
+diff +modify_fname -sound -xfontset
+digraphs +mouse +spell -xim
-dnd -mouseshape +startuptime -xpm
-ebcdic +mouse_dec +statusline -xsmp
+emacs_tags -mouse_gpm -sun_workshop -xterm_clipboard
+eval -mouse_jsbterm +syntax -xterm_save
+ex_extra +mouse_netterm +tag_binary
+extra_search +mouse_sgr -tag_old_static
fichier vimrc système : "$VIM/vimrc"
fichier vimrc utilisateur : "$HOME/.vimrc"
2me fichier vimrc utilisateur : "~/.vim/vimrc"
fichier exrc utilisateur : "$HOME/.exrc"
fichier de valeurs par défaut : "$VIMRUNTIME/defaults.vim"
$VIM par défaut : "/usr/local/share/vim"
Compilation : clang -c -I. -Iproto -DHAVE_CONFIG_H -DMACOS_X -DMACOS_X_DARWIN -g -O2 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=1
Édition de liens : clang -L. -fstack-protector-strong -L/usr/local/lib -L/usr/local/opt/libyaml/lib -L/usr/local/opt/openssl/lib -L/usr/local/opt/readline/lib -L/usr/local/lib -o vim -lncurses -liconv -lintl -framework AppKit -L/usr/local/opt/lua/lib -llua5.3 -mmacosx-version-min=10.14 -fstack-protector-strong -L/usr/local/lib -L/usr/local/Cellar/perl/5.30.0/lib/perl5/5.30.0/darwin-thread-multi-2level/CORE -lperl -lm -lutil -lc -L/usr/local/opt/python/Frameworks/Python.framework/Versions/3.7/lib/python3.7/config-3.7m-darwin -lpython3.7m -framework CoreFoundation -lruby.2.6
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub, or unsubscribe.![]()
The :cdo command stops when there is an error in switching to the next buffer after making
changes to the current buffer. In this it behaves similar to the :bufdo, :windo, tabdo, argdo,
and :cfdo commands. The difference is that those commands run once for each buffer in the
list. But the :cdo command runs for each entry in the list (multiple times for the same buffer).
The above referenced test behaves as expected. The :cdo command fails because the buffer is
not saved after making changes to the buffer. So the command is not able to edit the
next buffer in the list.
In the case of help buffers, as they are readonly, the command is able to switch to the
next buffer, even though it is not able to make the changes. So the command runs
through all the entries.
@yegappan thanks for the comparison to the other do commands, for the explanation of the test, and for demonstrating that that definition of :cdo explains basically all the behavior.
It is still unexpected behavior, and here is why:
:help :cdo
< When the current file can't be |abandon|ed and the [!]
is not present, the command fails.
When an error is detected execution stops.
The last buffer (or where an error occurred) becomes
the current buffer.
I see where you might have a point re: abandoning buffers. But the help says: "When an error is detected execution stops." Does this mean an error in :cdo (like the aforementioned abandon failure)? Or does this mean an error in {cmd} given to :cdo? Most users (myself included) seem to believe it's the latter—are you clarifying it is the former? Either way, we must update the help to be unambiguous (and it may be more useful to use the latter as actual behavior, given that :cdo operates at each entry, like :global (which, in fact, stops at the first error)).
@yegappan thanks for the comparison to the other
docommands, for the explanation of the test, and for demonstrating that that definition of:cdoexplains basically all the behavior.It is still unexpected behavior, and here is why:
:help :cdo < When the current file can't be |abandon|ed and the [!] is not present, the command fails. When an error is detected execution stops. The last buffer (or where an error occurred) becomes the current buffer.I see where you might have a point re: abandoning buffers. But the help says: "When an error is detected execution stops." Does this mean an error in
:cdo(like the aforementioned abandon failure)? Or does this mean an error in{cmd}given to:cdo? Most users (myself included) seem to believe it's the latter—are you clarifying it is the former? Either way, we must update the help to be unambiguous (and it may be more useful to use the latter as actual behavior, given that:cdooperates at each entry, like:global(which, in fact, stops at the first error)).
@yegappan Thanks for the explanation.
IIUC, cdo stops execution if and only if last entry in a buffer that make changes cause an error.
In another word, if an error happens, the current buffer after cdo might not be the error buffer, the only way to locate the entry that cause an error after cdo is to go through the message ?
@brammool I would appreciate a correction to the documentation.
That said, I understand why argdo, bufdo, cfdo, &c. stop on failures in a single buffer (file).
But cdo is far more like global—shouldn't it stop on the first entry that errors? (This probably all applies to ldo too, but I imagine they share some code in the implementation, so I'm ignoring that for now.)
@yegappan The patch posted to the mailing list gives global-like behavior (stopping at the first error).