views:

77

answers:

3

I have a folder containing hundreds of TTL (TeraTermLanguage) files. Now I wanted indent all these files.

I have created teraterm.vim for indentation and I open a file using VIM and do "gg=G" and whole file gets indented properly.

But is there any way, where I can indent all the files in folder.

I wanted to do with help of Shell. But in VIM I couldnt pass file indent command as the argument to VIM.

Please suggest which is the best way I can do indentation to all the files in VIM.

+4  A: 

Open up a terminal. Type:

$ vim -w indentme.scr foo.c

Then, type this exactly (in command mode):

gg=G:wq

This will close vim, saving the process of indenting all lines in the file to a Vim script called indentme.scr.

Note: indentme.scr will contain a record of all key commands typed, so when you are done indenting the file, don't spend a lot of time using the arrow keys to look around the file, because this will lead to a much larger script and will severely slow down batch operations.

Now, in order to indent all the lines in a file, just type the following command:

$ vim -s indentme.scr unindented-file.c

Vim will flash open-shut (if you're on a fast computer and not editing a huge file), indenting all lines, then saving the file in-place.

Unfortunately, this will only work on one file at a time, but you can scale the functionality easily using sh's for loop:

for filename in *.ttl ; do
    vim -s indentme.scr "$filename"
done

Note: This will save-over any file. Unless set bk is in your ~/.vimrc, don't expect a backup to be saved.

amphetamachine
+2  A: 

Check out this screencast, it might be exact thing you need: http://www.derekwyatt.org/vim/vim-tutorial-videos/vim-intermediate-tutorial-videos/#manyfilemacro

d.m
+1, This is a very interesting link, thanks!
Amir Rachum
A: 

Much simpler than scripting vim from the bash command line is to use vimscript from inside of vim (or perhaps a much simpler one-liner for scripting vim from the command line). I personally prefer using the arg list for all multi-file manipulation. For example:

:args ~/src/myproject/**/*.ttl | argdo execute "normal gg=G" | update
  • args sets the arglist, using wildcards (** will match the current directory as well as subdirectories)
  • | lets us run multiple commands on one line
  • argdo runs the following commands on each arg (it will swallow up the second |)
  • execute prevents normal from swallowing up the next pipe.
  • normal runs the following normal mode commands (what you were working with in the first place)
  • update is like :w, but only saves when the buffer is modified.

This :args ... | argdo ... | update pattern is very useful for any sort of project wide file manipulation (e.g. search and replace via %s/foo/bar/ge or setting uniform fileformat or fileencoding).

(other people prefer a similar pattern using the buffer list and :bufdo, but with the arg list I don't need to worry about closing current buffers or opening up new vim session.)

nicholas a. evans
Thanks Nicholas, This is simply great way of doing. Also this is very helpful in many other cases. Even though I was able to do using script, this is much faster. Well I have around 900 files which I had to modify. Only hiccup i faced is every time it fills up the screen with file names, I have to press spacebar, so that it can take up next set of files.
hari
If it's getting in your way, you should be able to avoid the "--More--" prompt and hitting space every screen by a liberal application of `:silent`. E.g. `:argdo silent execute "normal gg=G" | silent update`
nicholas a. evans