我最近一直在使用 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"