4

I recently needed to re-indent a large number of files. I used variations of:
find . -type f -exec vim -c "normal gg=GZZ" {} \;

Which worked well, but incredibly slowly (across several hundred files, some of which have thousands of lines).

Is there a faster way to have used vim for this? (note: I'm not asking the general question of how to do re-indenting, but only if there is a faster method in vim)


Update: I attempted filbranden's answer and it was MUCH slower, but I don't think I was able to make a good apples to apples comparison, so it may not be fair to call it slower. My attempt using the args list never finished and I ended up killing it. It was progressing, but very slowly. I like having the args list approach in my toolbox; I'm sure it will be useful sometime.

For context, I ran this in git bash on Windows. The vim process was pretty steady at ~90 mb ram, but the system commit charge was really high at ~37 gb (which is abnormal on my 32 gb ram machine). I'm not a Windows memory expert, but I think that means it may have been swapping, which would certainly explain the slowness.

1

1 Answer 1

1

You can use a single instance of Vim to open all the files and then use :argdo (or one of the other similar batch commands) to operate on all the files.

Start by simply opening Vim, with no files:

$ vim

Then use :args to pass it the file list. You can actually use your find command, with back ticks:

:args `find . -type f`

Then run :argdo to re-indent them, and :w after done:

:argdo exe "norm gg=G" | w

That's all you need! You need to use :execute here to be able to run both the :normal and :w command, without :execute the :normal command would try to interpret | as a Normal-mode command.

An alternative is to use :set hidden, which allows you to change buffers without saving, and then writing all of them at the end, while quitting:

:set hidden
:argdo norm gg=G
:wqa
3
  • I started this yesterday on the same file set (almost). It's still running. I think I can confidently report that this approach is MUCH slower.
    – Allen
    Jan 5, 2022 at 13:15
  • How many files do you have in total? How long did it take you with the first approach? Are you sure it's actually still going and not stuck somewhere? Can you try to run this on a small sample of ~1,000 files or so, try both approaches, see how long they take? I guess it's possible that, if you really have a huge number of files, opening them all in Vim could potentially use too much memory and slow things down for that reason, but otherwise, not opening and initializing Vim for every file should be much faster...
    – filbranden
    Jan 5, 2022 at 16:09
  • 2
    I updated the question with some results, but one thing I wanted to point out was that during my original approach of using find, the slowness I observed didn't appear to come from starting vim or writing. It spent most of its time on 1000 lines to indent, 950 lines to indent, etc.
    – Allen
    Jan 6, 2022 at 4:05

Your Answer

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

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