Execute a command within Vim from the command line

Vim

Vim Problem Overview


Is there a way to execute a Vim command on a file from the command line?

I know the opposite is true like this:

:!python %

But what if I wanted to :retab a file without opening it in Vim? For example:

> vim myfile.c
:retab | wq

This will open myfile.c, replace the tabs with spaces, and then save and close. I'd like to chain this sequence together to a single command somehow.

It would be something like this:

> vim myfile.c retab | wq

Vim Solutions


Solution 1 - Vim

This works:

gvim -c "set et|retab|wq" foo.txt

set et (= set expandtab) ensures the tab characters get replaced with the correct number of spaces (otherwise, retab won't work).

I don't normally use it, but vim -c ... also works

The solution as given above presumes the default tab stop of eight is appropriate. If, say, a tab stop of four is intended, use the command sequence "set ts=4|set et|retab|wq".

Solution 2 - Vim

You have several options:

  • -c "commands" : will play Ex commands as you entered them in the command line.
    In your example : vim myfile -c 'retab | wq'. This is what Firstrock suggested.

  • -S "vim source file" : will source given vim script
    (like running vim -c "source 'vim source file'"):

If you have a file script.vim containing:

    retab
    wq
Then you can use `vim myfile.c -s script.vim` (the extension does not really matter)
  • -s "scriptin file": will play contents of file as it contains normal mode commands: If you have script.txt containing:

    :retab
    ZZ
    

    with end of lines consisting of a single ^M character (for example you saved the script using the :set fileformat=mac | w), then you can run: vim myfile.c -S script.txt (ZZ is another way to exit vim and save current file).
    Note that you can record those scripts with vim my_file -W script.txt, but it suffers a bug if you happen to use gvim (the GUI).

Solution 3 - Vim

Not a direct answer to your question, but if you want to replace tabs with spaces (or do any other regex search/replace) for a list of files, you can just use in-place sed search/replace:

sed -i 's/\t/   /g' foo1.txt foo2.txt

or

ls *.txt | xargs sed -i 's/\t/   /g'

(In this example I am replacing each tab character with three spaces.)


NOTE: the -i flag means operate in-place.

From the sed man page:

   -i[SUFFIX], --in-place[=SUFFIX]

          edit files in place (makes backup if  extension
          supplied)

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionsyvexView Question on Stackoverflow
Solution 1 - VimFirstrockView Answer on Stackoverflow
Solution 2 - VimBenoitView Answer on Stackoverflow
Solution 3 - Vimarr_seaView Answer on Stackoverflow