0

I have a few shell scripts where I find files and open them in vim, with the filenames being stored in shell variables that are passed to vim. Since I don't want to start a vim session unless at least one file is found, I find myself checking to see if the variable is empty every time, like so:

...
if [ -z "$files" ] ; then 
    echo no files found
    exit 1
else 
   vim $files
fi

I was wondering if it would be possible to eliminate the need for this by having vim quit if the buffer is empty (no lines and the modified option is not set) using the -c command line flag to which one can pass a vim command. However I do not think vim can process if statements from the command line. (I was thinking of something like this:)

vim $files -c "if line('$') == 1 && &modified == 0 then :quitall endif"

I tried to see if there was an autocommand event for this, but couldn't find one. Any thoughts ?

2

In fact, it's more correct to handle this by shell script, so you can skip creating Vim process completely.

However, if you wonder if Vim is able to process conditions on command-line - yes, why not? The problem is you misuse some kind of arbitrary syntax, while Vim wants only VimScript.

So the following should be okay:

vim $files -c 'if !argc() | qa | endif'

See :h :if and :h :bar

2

Yes, it's possible to do an if check in a -c from the command-line, you just need to get the syntax right with the Vim command separator which is actually |. (Also, there's no then in Vim's if syntax.)

You probably also want to reserve the use of single quotes for the shell (use them on the outside), to prevent the shell from trying to interpret $ as a meta-character introducing a variable.

So this syntax would be valid:

vim $files -c 'if line("$") == 1 && &modified == 0 | quitall | endif'

There are problems with this approach... For one, it's not actually checking that no files were passed to edit, but that the current buffer is empty and unmodified. All files start unmodified in Vim, and if you do open a file that's empty, this check will trigger... (This will actually happen even if you're editing multiple files and the first one happens to be empty.)

A check that's more similar to the one you're currently using would be to check the arguments passed to Vim (which you can do with the argc() function) and see whether that's zero, which would indicate that no files were passed in the command-line:

vim -c 'if argc() == 0 | quit | endif' $files

You also can't tell from the shell whether any files were edited or not, since Vim will just quit successfully in this case. If you want to be able to detect whether this case was triggered, you can use the :cquit command instead (see :h :cq), which will exit Vim with a non-zero return code.

vim -c 'if argc() == 0 | cquit | endif' $files

Then you can check the $? variable from the shell to detect this case.

But I really wonder if it's worth this much trouble, especially if you'll want to handle the case where there are no files in the shell anyways... But hopefully that explains what's possible to do in Vim's -c.

2
  • this was very helpful. thanks! I have one question though: when would be using <bar> preferable to using the literal pipe character | ? – First User Jan 1 at 17:43
  • 1
    The <Bar> syntax works in :map commands. (See :help <bar> then scroll up, you'll see it says: "They can also be used with the :map command.") – filbranden Jan 1 at 19:26

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.