by Ingo Karkat
This plugin supports you with batch processing many files by extending the built-in :windo, :argdo, etc. commands. You can filter the argument list, add files not matching a pattern, convert between arguments and quickfix list, and apply arbitrary Ex commands (also partially) via :Argdo, then analyze any errors and retry on an argument list where the successfully processed arguments have been removed.
- The :ArgsNegated command was inspired by the following Stack Overflow question: http://stackoverflow.com/questions/11547662/how-can-i-negate-a-glob-in-vim
- vim-qargs (https://github.com/nelstrom/vim-qargs) has a :Qargs command similar (but more simplistic) than :CListToArgs.
- vim-lister (https://github.com/tommcdo/vim-lister) also has (among others) :Qargs and :Largs commands, and an :Afilter equivalent of :ArgsFilter (that takes a pattern instead of an expression, though).
- Pretty Args (vimscript #4681) provides an :Arg command which takes filename-modifiers to print a shortened argument list, e.g. just the filenames.
- JustDo (vimscript #4981) provides a :BufDo command that skips unmodifiable buffers.
:[range]Bufdo[!] {cmd} Execute {cmd} in each buffer in the buffer list, then
return back to the original one.
Any encountered errors are also put into the
quickfix list.
:[range]BufdoWrite {cmd}
Execute {cmd} in each modifiable buffer in the buffer
list and automatically persist any changes (:update).
:[range]Windo {cmd} Execute {cmd} in each window, then return back to the
original one.
:[range]WindoWrite {cmd}
Execute {cmd} in each window showing a modifiable
buffer and automatically persist any changes (:update).
:[range]Winbufdo {cmd} Execute {cmd} in each different buffer shown in one of
the windows in the current tab page (once per buffer),
then return back to the original one.
:[range]WinbufdoWrite {cmd}
Execute {cmd} in each different modifiable buffer
shown in one of the windows in the current tab page
(once per buffer) and automatically persist any
changes (:update).
:[range]Tabdo {cmd} Execute {cmd} once in each tab page, then return back
to the original one.
:[range]Tabwindo {cmd} Execute {cmd} in each open window on each tab page,
then return back to the original one.
:[range]TabwindoWrite {cmd}
Execute {cmd} in each open window on each tab page,
that shows a modifiable buffer and automatically
persist any changes (:update).
:[range]Argdo[!] {cmd} Execute {cmd} for each file in the argument list, then
return back to the original file and argument.
[range] is emulated for older Vim versions, but can
only be used interactively (not in scripts).
In contrast to :argdo, this also avoids the
hit-enter prompt (all files will be processed
without further interaction from you), and an error
summary will be printed.
To work on the errors / arguments with errors, you can
use :ArgdoErrors and :ArgdoDeleteSuccessful.
Also, any encountered errors are put into the
quickfix list.
:[range]ArgdoWrite[!] {cmd}
Execute {cmd} in each modifiable buffer in the
argument list and automatically persist any changes
(:update).
:[range]ArgdoConfirmWrite[!] {cmd}
Like :ArgdoWrite, but confirm each write, allowing
to review the automatically applied changes of {cmd}
before persisting them. When you quit the argument
processing before the last argument, this will not
return to the original file (to make it easier to
process the remaining arguments again).
:ArgdoErrors List all error messages that occurred during the last
:Argdo command, and for each unique error, print the
argument number and filespec.
:ArgdoDeleteSuccessful Delete those arguments from the argument list that
didn't cause any error messages during the last
:Argdo command.
:[count]ArgMerge [{name} ...]
Add the {name}s to the argument list, but only if they
aren't yet contained in the argument list (:argadd
doesn't check and requires a follow-up deduplication).
When {name} is omitted add the current buffer name to
the argument list.
:[N]ArgDrop[!] [N] Delete the current [N] argument(s) from the argument
list and edit the next one instead. Complains when the
current file is not contained in the argument list
unless [!] is given (which is also required to
abandon changes in the current buffer).
:[range]ArgsDeleteExisting[!]
Delete any files from the argument list that do (with
[!]: not) exist in the file system (actually: can[not]
be read).
:[range]ArgsDeleteFilesFromThisRoot[!]
Delete any files from the argument list that are (with
[!]: not) inside the current project root directory.
:[range]ArgsFilter[!] {expr}
Apply the filter() of {expr} to the files in the
argument list (i.e. values from argv(), referenced
as v:val), and keep only those where {expr} yields
true. This allows you to :argdelete multiple
arguments at once and to delete without specifying the
full filename.
:[range]ArgsFilterDo[!] {expr}
Apply the filter() of {expr} to the argument list
within the context of each argument, and keep only
those where {expr} yields true. In contrast to
:ArgsFilter, this allows filtering based on buffer
contents (or buffer variables, buffer settings).
For example, remove all arguments whose buffers have
more than 100 lines:
:ArgsFilterDo line('$') <= 100
:[range]ArgsKeepMatchingBuffers[!] [{pattern}]
Keep all arguments where {pattern} / the last search
pattern matches in the buffer.
:[range]ArgsDeleteMatchingBuffers[!] [{pattern}]
Delete all arguments where {pattern} / the last search
pattern matches in the buffer.
:[range]ArgsSort[!] [f][i][l][n][N]|{func-name}
Sort the argument list. [!] reverses the order; all
other arguments like sort().
:ArgsNegated[!] {arglist}
Define all files except {arglist} as the new argument
list and edit the first one.
:[range]ArgsList[!] List each argument number, modification state, and
filespec in a neat list (not just one after the other
as :args). With [!], expand all arguments to
absolute filespecs.
:[range]ArgsList[!] {glob}
List each argument number, modification state, and
filespec that matches (with [!]: does not match)
{glob} in a neat list.
Matching and printing is done to the full filespec.
[count]<Leader>la List each / the next [count] argument[s] (number,
modification state, and filespec) in a neat list.
:[range]ArgsToQuickfix Show all arguments as a quickfix list.
:CListToArgs Convert the files in the quickfix list to arguments.
:[count]CListToArgsAdd
:LListToArgs Convert the files in the window's location list to
:[count]LListToArgsAdd arguments.
:CList[!], :LList[!] List each file that has listed errors in the quickfix
/ location list in a neat list. With [!], expand all
to absolute filespecs.
:CList[!] {glob} List each file that has listed errors in the quickfix
:LList[!] {glob} / location list that matches (with [!]: does not
match) {glob} in a neat list. Matching and printing is
done to the full filespec.
:[range]CDoEntry {cmd} Execute {cmd} on each entry in the quickfix /
:[range]LDoEntry {cmd} location list (limited to buffers in [range]).
:[range]CDoFile {cmd} Execute {cmd} once on each file that appears in the
:[range]LDoFile {cmd} quickfix / location list (limited to buffers in
[range]).
:[range]CDoFixEntry {cmd}
:[range]LDoFixEntry {cmd}
Execute {cmd} on each entry in the quickfix / location
list (limited to buffers in [range]). If the {cmd}
does not abort and changes the buffer (i.e. increases
b:changedtick), that entry is removed from the
quickfix / location list. Else, the original entry is
augmented with error information. (Entries for buffers
outside [range] are kept as-is.)
The code is hosted in a Git repo at https://github.com/inkarkat/vim-ArgsAndMore You can use your favorite plugin manager, or "git clone" into a directory used for Vim packages. Releases are on the "stable" branch, the latest unstable development snapshot on "master".
This script is also packaged as a vimball. If you have the "gunzip" decompressor in your PATH, simply edit the *.vmb.gz package in Vim; otherwise, decompress the archive first, e.g. using WinZip. Inside Vim, install by sourcing the vimball or via the :UseVimball command.
vim ArgsAndMore*.vmb.gz
:so %
To uninstall, use the :RmVimball command.
- Requires Vim 7.0 or higher.
- Requires the ingo-library.vim plugin (vimscript #4433), version 1.048 or higher.
- The :ArgsDeleteFilesFromThisRoot command requires the VcsRoot.vim plugin (unreleased), version 1.00 or higher.
After each {cmd}, an extra Ex command (sequence) can be executed. By default, a delay of 100 ms is introduced here. This allows you to abort an interactive :s///c substitution by pressing CTRL-C twice within the delay. (Without the delay, it may or may not abort.) To also persist any changes to the buffer, you could use:
let g:ArgsAndMore_AfterCommand = 'update | sleep 100m'
During :argdo, syntax highlighting of freshly loaded buffers is turned off for performance reasons, but for interactive commands, it is useful to have syntax highlighting. Therefore, the :Argdo and :Bufdo commands detect interactive commands and overrule the default syntax suppression then. By default, this applies to the :substitute command with the :s_c flag; you can adapt the pattern to match other commands, too:
let g:ArgsAndMore_InteractiveCommandPattern = '...'
If you want to use different mappings, map your keys to the <Plug>(ArgsAndMore...) mapping targets before sourcing the script (e.g. in your vimrc):
nmap <Leader>la <Plug>(ArgsAndMoreList)
Report any bugs, send patches, or suggest features via the issue tracker at https://github.com/inkarkat/vim-ArgsAndMore/issues or email (address below).
- ENH: Add :ArgsDeleteFilesFromThisRoot command. Requires VcsRoot.vim (vimscript #0000) version 1.00 or higher.
- ENH: Add <Leader>la command for :ArgsList.
- UI: ENH: :ArgsList, :CList and :LList now also show the modification state of each buffer with little sigils: + / - / =.
- ENH: :ArgsSort maintains the currently active argument.
- ENH: Add :ArgMerge command.
- BUG: :ArgsFilterDo fails with runtime error.
- ENH: Add :Args{Keep,Delete}MatchingBuffers specializations of :ArgsFilterDo.
- BUG: Avoid "E16: Invalid range" on :ArgDrop on the last argument.
- ENH: DWIM: :Args{Delete{Existing,FilesFromThisRoot},Filter[Do],{Keep,Delete}MatchingBuffers} automatically go to the next remaining argument if the current argument is deleted.
You need to update to ingo-library (vimscript #4433) version 1.048!
- Add :ArgDrop command.
- Add :ArgsDeleteExisting specialization of :ArgsFilter. Useful to throw out files that have been removed from the file system (with !), or to drop files that have been created and saved (without !).
- FIX: :ArgsNegated does not handle arguments with escaped spaces and cmdline-special characters (e.g. #).
- Add :WindoWrite, :WinbufdoWrite, :TabwindoWrite variants that automatically persist any changes (like :ArgdoWrite).
- Only iterate over modifiable buffers in the :*Write commands; skip buffers where 'modifiable' is unset (e.g. terminal buffers), to avoid errors on attempted modification and :update.
- ENH: Add :ArgsSort command.
You need to update to ingo-library (vimscript #4433) version 1.043!
- Support [range] on :ArgsFilter.
- Add :ArgsFilterDo variant of :ArgsFilter.
- Use proper error aborting for :Bufdo, :Argdo, and :[CL]Do*.
- FIX: Avoid creating jump on :bufdo / :windo / :tabdo.
- Support [!] on :Bufdo[Write], :Argdo[[Confirm]Write], ArgsFilterDo to force iteration when the current buffer has unpersisted modifications and 'hidden' isn't set (just like with the built-in :argdo, :bufdo).
You need to update to ingo-library (vimscript #4433) version 1.035!
- FIX: :Bufdo..., :Win..., :Tab... in recent Vim 7.4 defaults to wrong range. Forgot -range=% argument.
- Add :CDoFile, :CDoEntry, :CDoFixEntry commands for iteration over quickfix / location list.
- Use ingo#msg#WarningMsg().
- ENH: Keep previous (last accessed) window on :Windo. Thanks to Daniel Hahler for the patch.
- ENH: Keep alternate buffer (#) on :Argdo and :Bufdo commands. Thanks to Daniel Hahler for the suggestion.
- Handle modified buffers together with :set nohidden when restoring the original buffer after :Argdo and :Bufdo by using :hide.
- FIX: :Argdo may fail to restore the original buffer. Ensure that argidx() actually points to valid argument; this may not be the case when arguments have only been :argadd'ed, but not visited yet.
- Support the -addr=arguments attribute in Vim 7.4.530 or later for :Argdo... commands. With that, relative addressing can also be used non-interactively.
- Support ranges in :Bufdo..., :Windo..., :Tabdo... if supported by Vim.
- Support ranges in :ArgsList and :ArgsToQuickfix if supported by Vim.
- Switch to ingo#regexp#fromwildcard#AnchoredToPathBoundaries() to correctly enforce path boundaries in :ArgsList {glob}.
You need to update to ingo-library (vimscript #4433) version 1.023!
- Add :CList and :LList, analog to :ArgsList.
- FIX: :ArgsList printed "cnt" is zero-based, not 1-based.
- Add :ArgdoConfirmWrite variant of :ArgdoWrite.
- Also catch custom exceptions and errors caused by the passed user command (or configured post-command).
You need to update to ingo-library (vimscript #4433) version 1.017!
- FIX: Use the rules for the /pattern/ separator as stated in :help E146 in the default of g:ArgsAndMore_InteractiveCommandPattern.
- Minor: Exclude further special buffers from syntax enabling.
- :ArgsList also handles ** and [...] wildcards.
- Move escapings.vim into ingo-library.
You need to update to ingo-library (vimscript #4433) version 1.014!
- Add dependency to ingo-library (vimscript #4433).
You need to separately install ingo-library (vimscript #4433) version 1.007 (or higher)!
- ENH: Add :ArgdoWrite and :BufdoWrite variants that also perform an automatic :update.
- ENH: Add errors from :Argdo and :Bufdo to the quickfix list to allow easier rework.
- Avoid script errors when using :Argdo 3s/foo/bar
- Minor: Change :Argdo[Write] -range=-1 default check to use <count>, which maintains the actual -1 default, and therefore also delivers correct results when on line 1.
- ENH: Enable syntax highlighting on :Argdo / :Bufdo on freshly loaded buffers when the command is an interactive one (:s///c, according to g:ArgsAndMore_InteractiveCommandPattern), but for performance reasons not in the general case.
- In :{range}Argdo, emulate the behavior of the built-in :argdo to disable syntax highlighting during to speed up the iteration, but consider our own enhancement, the exception for interactive commands.
- Minor: Make matchstr() robust against 'ignorecase'.
- FIX: Factor out s:sort() and also use numerical sort in the one missed case.
- Add g:ArgsAndMore_AfterCommand hook before buffer switching and use this by default to add a small delay, which allows for aborting an interactive s///c substitution by pressing CTRL-C twice within the delay.
- Add :Bufdo command for completeness, to get the new hook, and the enhanced error reporting of :Argdo.
- Do not use <f-args> because of its unescaping behavior.
- FIX: "E480: No match" on :ArgsNegated with ../other/path relative argument; need to issue a dummy :chdir to convert relative args before doing the :argdelete.
- First published version.
- Started development.
Copyright: (C) 2012-2026 Ingo Karkat - The VIM LICENSE applies to this plugin.
Maintainer: Ingo Karkat <ingo@karkat.de>