Search code examples
vim

Why does vim, run as the alias "vi", return a non-zero exit code when any error happened?


On my system (Mac OS X), vi is aliased to vim. However, when run as vi, the behavior of its exit code is different: it will return a non-zero exit code when any error happened during the session, as can be seen by the following test:

  • In a terminal, open any file with vim.
  • Do some editing.
  • Try to exit using :q. This should result in an error (No write since last change).
  • Exit anyway using :q! or :wq.
  • Type echo $? in the terminal.

The return code will be 0 if I used vim in the first step to open vim, but will be 1 if I used vi.

This problem is probably the root cause of Vi is aliased to vim but exit with code 1.


Solution

  • After some searching, I found the following remark in vim help, section |posix-compliance|:

    In 2005 the POSIX test suite was run to check the compatibility of Vim. ...
    ...
    - vi test 310 fails; exit code non-zero when any error occurred?
    

    This leads me to the following section of the POSIX specification of vi.

    EXIT STATUS

    The following exit values shall be returned:

    0

    Successful completion.

    >0

    An error occurred.

    Obviously, many utilities have such an exit status specification, and it is usually pretty reasonable. Not in the case of vi, though: as an interactive editor, it is entirely possible that some command results in an error ("An error occurred"), yet the whole editor exits normally ("Successful completion"). Therefore the specification itself is ambiguous and/or contradictory, depending on your viewpoint.

    Apparently, the folks writing the POSIX test suite decided that the definition of "Successful completion" should be strict: if any error occurred, it is not a successful completion. Hence vim failing that test.

    Of course, it is not hard to modify the code of vim to comply with that interpretation of the specification if it is called as vi. Since the latest version of vim seems to not exhibit this behavior, I guess the Mac OS X people may have introduced this patch themselves in order to pass the POSIX test. Any difficulty in using utilities like git commit is probably the least of their concern.