执行外部命令后 Vim 进程停止

执行外部命令后 Vim 进程停止

我最近一直在使用 vim 进行 C 语言编程。我已经创建了在 vim 内部编译和运行程序的快捷方式,但是最近执行程序后 vim 的进程一直停止。

foo.c:

#include <stdio.h>

int main() {
    printf("Hello World!\n");
    return 0;
}

.vimrc:

set shellcmdflag=-ic

syntax on

autocmd FileType c map <F6> :!gcc -o "%:p:r.out" "%:." <bar> more<CR>
autocmd FileType c map <F7> :!%:p:r.out<CR>

如果我点击F6,程序可以正常编译。但是如果我点击F7,我得到以下结果:

Hello World!
[1]+  Stopped                 vim test.c

我可以使用fg重新启动该过程,但这样做有点烦人。有人知道如何解决这个问题吗?

答案1

不要使用交互式 shell 来执行命令。(这就是i-ic

默认的 shellcmdflag ( -c) 应该可以正常工作。

如果您指定是-i为了让 bash 读取您的.bashrc文件(这是启动交互式 shell 的副作用),那么您最好只告诉 bash 读取启动环境脚本。引用 bash 手册页:

例如,当以非交互方式启动 bash 以运行 shell 脚本时,它会BASH_ENV在环境中查找变量,如果变量出现则扩展其值,并使用扩展的值作为要读取和执行的文件的名称。Bash 的行为就像执行了以下命令一样:

          if [ -n "$BASH_ENV" ]; then . "$BASH_ENV"; fi

但变量的值PATH不用于搜索文件名。

您可以使用以下方式在 vim 中设置环境变量:let

答案2

我同意不应该使用交互式子 shell,因为rici 在他的回答中指出。(我特别欣赏对他评论中的问题的分析

但是,设置BASH_ENV是危险的:如果你这样做,你必须确保 Bash绝不直接或间接地从该文件调用,否则您将陷入生成 Bash 进程的无限循环。如果您的设置相当复杂,这可能会很困难,因为很容易没有意识到您正在调用的程序实际上是 Bash 脚本。

我的解决方案很简单set shell=bash-rcc,即以下脚本:

#!/usr/bin/env bash
#
#   bash-rcc - source ~/.bashrc and run bash -c command
#
#   This is used as the shell by programs such as vim where we want
#   `:!` commands to be able to use shell functions and aliases
#   defined in `~/.bashrc` but do not want the shell started in
#   interactive mode. Interactive mode does various things, such as
#   setting up its own process group, that can cause problems when
#   used to run a single command from another program.

[[ $1 = -c ]] && shift
. ~/.bashrc
eval "$1"

相关内容