10

Let's say I have a function, named StripWhitespace.

I can run it on a single file by opening the file and running :StripWhitespace.

How can I automatically run that function against a folder of files, and save the results as I go along?

7

You can use the -c argument to run a command on startup, from vim(1):

   -c {command}
               {command} will be executed after the first  file  has  been
               read.   {command}  is interpreted as an Ex command.  If the
               {command} contains spaces it must  be  enclosed  in  double
               quotes  (this depends on the shell that is used).  Example:
               Vim "+set si" main.c
               Note: You can use up to 10 "+" or "-c" commands.

Example:

vim -c ':call StripWhitespace()' file1 file2

To quit afterwards, add | :wqa:

vim -c ':call StripWhitespace() | :wqa' file1 file2
  • 1
    You want an :argdo, if you run this for a couple of files on the commandline – Christian Brabandt Mar 3 '15 at 17:29
17

If you are already in Vim, you can use the :argdo or :bufdo commands to execute a command on every item in the argument list or buffer list, respectively.

e.g. to run a : command on every file in the argument list:

:argdo StripWhitespace

Or to invoke a function from every file in the buffer list:

:bufdo call StripWhitespace()

Or to run macro q on every file in the arguments list:

:argdo normal @q

You can then save all changed buffers with :wall, or save all and quit Vim with :wqall.

If you want to write the files as you go along, you can add in a call to :update, like so:

:argdo s/foo/bar/ge | update

There are various ways you can get the files into Vim in the first place, including:

  • Supply parameters to the vim command line: vim * (this adds all the files to the argument list),
  • Use the :args command (which supports wildcards and backtick expressions) to populate the argument list, or the :argadd command to add files to it,
  • Just open them all manually with :e, :Ex, or a file-opening plugin.
  • 1
    I like this answer because it doesn't require leaving Vim, which in my opinion is too expensive (my precious buffer list!). I have some notes: (1) leaving buffers without writing requires 'hidden' to be set; (2) the : update command is a slight improvement over :w because it only writes if a change has been made, so :bufdo update or :argdo update will write all modified buffers or arguments. – tommcdo Feb 12 '15 at 11:10
  • Good point on update. I considered mentioning hidden when I was writing the answer, but decided against it because I didn't want to overcomplicate it. On reflection though, it should be in there. I'll update the answer to include both suggestions presently. – Rich Feb 12 '15 at 11:18
  • @tommcdo Just checked the documentation for :wall, and it only writes changed buffers, so :bufdo update is not necessary after all. – Rich Feb 12 '15 at 11:20
  • good catch regarding :wall, which also has the advantage of not cycling through buffers and moving you away from where you started. I suppose :argdo update is still a different story -- maybe you don't want to write to buffers that are not in your argument list. – tommcdo Feb 12 '15 at 11:44
  • @tommcdo Good point. – Rich Feb 12 '15 at 11:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.