如何强制 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
.
编辑:感谢您在这里的回答!一些额外的细节:
- 这是在 MacOS 11.2.1.
- 我没有
~/.vimrc
所以我只是回到 Mac 提供的 /usr/share/vim/vimrc
,这看起来很基本。
- 调用
vi -u NONE
仍然会导致上述行为。
- (most interesting) 调用
vim
解决了问题。是的,我知道我在上面提到过另一个答案是使用 vi
而不是 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 --version
或 vim --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 版本上,如果作为 vi
或 ex
调用,您将获得此错误保留行为。
注: Apple URL 令人困惑 – vim-91
确实对应 vim 8.2,可以通过查看version.h
在同一个仓库中。
解决方案
调用 vim 作为 vim
而不是 vi
。在 git
的情况下,在 .bashrc
/.zshrc
/config.fish
.
中将 EDITOR
环境变量设置为 vim
或者,通过 Homebrew 之类的工具安装官方 vim。
编辑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
.
编辑:感谢您在这里的回答!一些额外的细节:
- 这是在 MacOS 11.2.1.
- 我没有
~/.vimrc
所以我只是回到 Mac 提供的/usr/share/vim/vimrc
,这看起来很基本。 - 调用
vi -u NONE
仍然会导致上述行为。 - (most interesting) 调用
vim
解决了问题。是的,我知道我在上面提到过另一个答案是使用vi
而不是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 --version
或 vim --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 版本上,如果作为 vi
或 ex
调用,您将获得此错误保留行为。
注: Apple URL 令人困惑 – vim-91
确实对应 vim 8.2,可以通过查看version.h
在同一个仓库中。
解决方案
调用 vim 作为 vim
而不是 vi
。在 git
的情况下,在 .bashrc
/.zshrc
/config.fish
.
EDITOR
环境变量设置为 vim
或者,通过 Homebrew 之类的工具安装官方 vim。