如何强制 vi/vim 以状态 0 干净退出

How can I force vi/vim to exit cleanly with status 0

编辑vim时,正常退出码为0,例如:

vi; echo $?

将 return 0 如果您立即 :q。但是,如果您 曾经 输入错误的命令,它将 return 1 (或其他错误代码)。例如,在 vim 中键入 :aaa 将在 vim 中给出错误 E492: Not an editor command: aaa。在那之后,无论我做什么,vim 随后都会以状态 1 退出。

这是编辑 git 提交消息时的一个问题,因为如果您在键入时出错(在 vim 中很容易做到),后续的提交消息将被丢弃。 (是的,我知道有一些方法可以找回它 - 我不想每次都知道我犯了一个错误。)

问题:是否有 vim 命令将退出代码“重置”为 0?

这里有一个类似的问题:can i force vim to exit with 0 status。但是,这是由于使用 vi 而不是 vim,如果您搜索不存在的字符串,它(显然)以非零值退出。这个问题专门针对 vim.

编辑:感谢您在这里的回答!一些额外的细节:

$ which vi
/usr/bin/vi
$ which vim
/usr/bin/vim
$ ls -l /usr/bin/vi
lrwxr-xr-x  1 root  wheel        3 Jan  1  2020 /usr/bin/vi -> vim

当我 运行 vi --versionvim --version 时,我得到 相同 相同的输出。 vim 是否会根据调用的可执行文件名称更改其行为?如果是这样,我可以在我的 .vimrc 中添加一些东西来覆盖那个开关吗?我很想知道。同时,我可以用 export EDITOR="vim".

解决这个问题

默认情况下,Vim(至少是 vi 的一些其他实现,例如 nvi),return0 如果发生“正常”错误,例如无效命令或其他正常用户输入错误。它 在这种情况下 ed 退出非零的行为,正如您所发现的,这种行为通常是不可取的,因为人类是不完美的并且会犯很多错误,这就是为什么 Vim 不会那样做。

Vim 如果你使用 :cq 应该退出非零值,它有意有这种行为,以及如果满足某些错误条件(例如,你 运行 vim -y 但是显示无法启动

您的配置设置或插件可能会导致此行为。您可以尝试 运行 vim -u NONE -U NONE 来验证这一点,然后通过注释掉 .vimrc 的部分来隔离问题。也有可能您的 Vim 分销商认为这是为您添加和修补它的理想功能,但您没有提到您的 OS 或 Vim 软件包的来源,所以很难说。

要始终强制零退出,您可以尝试 :cq 0,但这并不比标准 :q 更有效,因为它们都调用完全相同的函数(getout) 具有完全相同的值 (0).

我在 macOS 11.6 上也看到了这种行为,它仅在作为 vi 调用时发生 – 而不是 vim.

为什么会这样?

如果我们看vim --version

> vim --version                                                                                                                                                 
VIM - Vi IMproved 8.2 (2019 Dec 12, compiled Aug 30 2021 06:51:40)
macOS version
Included patches: 1-2029
Compiled by root@apple.com

这里的 macOS 版本 让我们知道可能有问题。

在 Apple 的开源存储库 (https://opensource.apple.com/source/vim/vim-91/src/main.c.auto.html) 中查看 vim 的 main.c,我们在 int main() 函数中找到:

Unix2003_compat = 0;
if (strcmp(base,"vi")==0) {
    Unix2003_compat = COMPAT_MODE("bin/vi", "Unix2003");
} else if (strcmp(base,"ex")==0) {
    Unix2003_compat = COMPAT_MODE("bin/ex", "Unix2003");
}

然后在 void getout(int exitval):

if (exmode_active || Unix2003_compat )
    exitval += ex_exitval;

此处的 Unix2003_compat 部分在 the official Vim sources 中不存在。

所以在 vim 的 macOS 版本上,如果作为 viex 调用,您将获得此错误保留行为。

注: Apple URL 令人困惑 – vim-91 确实对应 vim 8.2,可以通过查看version.h 在同一个仓库中。

解决方案

调用 vim 作为 vim 而不是 vi。在 git 的情况下,在 .bashrc/.zshrc/config.fish.

中将 EDITOR 环境变量设置为 vim

或者,通过 Homebrew 之类的工具安装官方 vim。