C语言 如何从 VIM 运行 C 程序?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2627886/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 05:09:30  来源:igfitidea点击:

How do I run a C program from VIM?

cvim

提问by Coder

Is there a way to compile and run a C program from VIM without typing its filename ?

有没有办法在不输入文件名的情况下从 VIM 编译和运行 C 程序?

回答by tstenner

:!gcc -o somename % && ./somename
When using :!, % will be substituted by the name of the currently opened file.

:!gcc -o somename % && ./somename
使用时:!, % 将被当前打开的文件名替换。

When your project becomes larger, you can also write a makefile and compile the current project with :make, if there are any errors, vim will jump to them automatically.

当你的项目变大时,你也可以写一个makefile,用 编译当前项目:make,如果有任何错误,vim会自动跳转到它们。

回答by ungalnanban

Use the following mapping code in your .vimrc file for compiling and running a c programming file.

在 .vimrc 文件中使用以下映射代码来编译和运行 ac 编程文件。

 map <F8> : !gcc % && ./a.out <CR>

F8 key is for run the mapping. "%" is to take the current file name.

F8 键用于运行映射。“%”是取当前文件名。

Or, if you want to save the current file before compiling it, use

或者,如果要在编译之前保存当前文件,请使用

map <F8> :w <CR> :!gcc % && ./a.out <CR>

Or more ideally, if you want to use the file basename not the default 'a.out' as the executable file name, use the following:

或者更理想的是,如果您想使用文件 basename 而不是默认的“a.out”作为可执行文件名,请使用以下命令:

map <F8> :w <CR> :!gcc % -o %< && ./%< <CR>

In the above command, "<" after "%" removes extension and dot (foo.c => foo), so "%<" is the file basename.

在上面的命令中,“%”之后的“<”删除扩展名和点(foo.c => foo),所以“%<”是文件的基本名称。

You can find this and similar infos in cmdline.txt. Command in vim:help: cmdline.txt. You can also find specific details about the use of "%" by using :help filename-modifiersin vim.

您可以在 cmdline.txt 中找到此信息和类似信息。vim 中的命令:help: cmdline.txt. 您还可以通过:help filename-modifiers在 vim 中使用来找到有关“%”使用的具体细节。

回答by Luc Hermitte

TL;DRNo Makefile is required, tweaking &makeprgis also completely useless, and yet :make %<is enough to compile from Vim.

TL;DR不需要 Makefile,调整&makeprg也完全没用,但:make %<足以从 Vim 编译。

Long answer:

长答案:

I duplicate an answer I gave in a closed "duplicate question".

我复制了我在一个封闭的“重复问题”中给出的答案。

Considering we are using vim, and not vi, :makeis the way to go.

考虑到我们使用的是 vim 而不是 vi,这:make是要走的路。

On Linux-like (it also applies to cygwin, but not to mingw on windows -- in mingw case, see the other answers that alter &makeprg, leave it alone otherwise) systems where gnumake is installed, if you don't have a Makefile in your project, and if your project is made of only one file, just type :make %<. It will be enough (you can play with $CXXFLAGS, $CFLAGSand $LDFLAGSto tune the compilation options). Then to run the program, type :!./%<, or with latter versions of vim, run :terminal ./%<.

在类似 Linux 的(它也适用于 cygwin,但不适用于 Windows 上的 mingw - 在 mingw 的情况下,请参阅其他更改的答案,&makeprg否则不要管它)安装了 gnumake 的系统,如果您没有 Makefile您的项目,如果您的项目仅由一个文件组成,只需键入:make %<. 就足够了(您可以使用$CXXFLAGS,$CFLAGS$LDFLAGS调整编译选项)。然后要运行该程序,请键入:!./%<,或者使用更高版本的 vim,运行:terminal ./%<.

If your project is made of several files, then you'll need a Makefile to take advantage of :make.

如果您的项目由多个文件组成,那么您将需要一个 Makefile 来利用:make.

If you manage your project with CMake, and if you compile your project in a directory (or several -> debug, release, ...) outside the sources tree, then the integration will require a plugin. AFAIK, I'm the only one to propose such a plugin: BuildToolsWrapperintegrates the management of CMake (choice of the build directory, possibility to chose between the debug, or release, or whatever build directory). It has to be coupled with one of the local_vimrcplugin.

如果您使用 CMake 管理您的项目,并且如果您在源代码树之外的目录(或多个 -> 调试、发布、...)中编译您的项目,那么集成将需要一个插件。AFAIK,我是唯一提出这样一个插件的人:BuildToolsWrapper集成了 CMake 的管理(构建目录的选择,在调试、发布或任何构建目录之间进行选择的可能性)。它必须与local_vimrc插件之一结合使用。

In all cases, calling directly the compiler from within (or outside) Vim with :!g++ -o %< %or whatever is what we used to do 15 years ago on vi. Vim has a wonderful feature: it can integrate (yes, like in IDE) the compiler. See :h quickfix. Navigating between errors directly from the editor is much easier than extracting one error line with our eyes, typing back the line number into the editor, going back to the shell to see what exactly was rejected, ... It may be enough in C, but In C++ when we are "trying to call an overload that doesn't exist", we can't work this way (switching back and forth between the editor and the shell).

在所有情况下,直接从 Vim 内部(或外部)调用编译器,:!g++ -o %< %或者使用我们 15 年前在 vi 上所做的任何事情。Vim 有一个很棒的功能:它可以集成(是的,就像在 IDE 中一样)编译器。见:h quickfix。直接从编辑器在错误之间导航比用我们的眼睛提取一个错误行容易得多,在编辑器中输入行号,回到 shell 看看究竟是什么被拒绝,......在 C 中可能就足够了,但是在 C++ 中,当我们“尝试调用不存在的重载”时,我们不能以这种方式工作(在编辑器和 shell 之间来回切换)。

Finally, if you want to compile on a single keystroke those mono-file projects, you can add in your .vimrc:

最后,如果你想通过一次按键编译那些单文件项目,你可以在你的 .vimrc 中添加:

nnoremap <silent> <f7> :make %<<cr>

If you want to adapt automatically the compilation command depending of the kind of project mono-file pet project, or real world multi-file project, well, more wiring is needed, and this is what BTW does-- it reads various options to know what to do.

如果您想根据项目类型的单文件宠物项目或现实世界的多文件项目自动调整编译命令,那么需要更多的布线,这就是BTW 所做的- 它会读取各种选项以了解该怎么办。

Last note: &makeprgis best left alone, at least not set to g++/gcc/clang/clang++/gfortran/... Because, every time you change your language, you'll have to change it (unless you use :setlocal). With the solution I recommend, if I want to use clang++ instead of g++, all I have to do is to set: :let $CXX='clang++'(or $CCin C), and then call :make %<. I can even define :let $CXXFLAGS='-std=c++11'to compile in C++11 -- the same variable will be used to turn warnings on, to use a sanitizer, etc.

最后一点:&makeprg最好不要管,至少不要设置为 g++/gcc/clang/clang++/gfortran/... 因为,每次更改语言时,都必须更改它(除非您使用:setlocal)。使用我推荐的解决方案,如果我想使用 clang++ 而不是 g++,我所要做的就是设置:(:let $CXX='clang++'$CC在 C 中),然后调用:make %<. 我什:let $CXXFLAGS='-std=c++11'至可以定义在 C++11 中编译——相同的变量将用于打开警告、使用消毒剂等。

回答by tolitius

since most of the time you would use a Makefile, in addition to the given answers, I also like to see my results in a "cleared" screen:

由于大多数情况下您会使用 Makefile,因此除了给出的答案之外,我还希望在“清除”屏幕中看到我的结果:

map <F10> :w<CR> :!clear; make<CR> :!./%<<CR>

map <F10> :w<CR> :!clear; make<CR> :!./%<<CR>

  • :w<CR>saves the file

  • :!clear; make<CR>clears the screen and runs make

  • :!./%<<CR>runs a program (%) without the extension (<)

  • :w<CR>保存文件

  • :!clear; make<CR>清除屏幕并运行 make

  • :!./%<<CR>运行%没有扩展名 ( <)的程序 ( )

回答by skywind3000

It's 2018 now, vim 8 has released for 2 years and shipped with all the Linux distributions and Mac OS X. But a lot of vim tutorials are still teaching people something ten years ago.

现在是 2018 年,vim 8 已经发布了 2 年,并且随所有 Linux 发行版和 Mac OS X 一起提供。但是很多 vim 教程仍然在教人们十年前的东西。

You can compile your C++/Java programs in vim as convenience as Sublime Text or NotePad++ with some dedicated plugins for Vim 8 or NeoVim.

你可以在 vim 中编译你的 C++/Java 程序,就像 Sublime Text 或 NotePad++ 一样方便,使用一些专门的 Vim 8 或 NeoVim 插件。

For example, the AsyncRunplugin will allow you run shell commands in background and read output from quickfix window in realtime. See the screen capture.

例如,AsyncRun插件将允许您在后台运行 shell 命令并实时从 quickfix 窗口读取输出。 请参阅屏幕截图

Just like compiling programs in IDEs, the compilation errors will be matched by errorformat and be highlighted and become selectable. You can navigate errors in the quickfix window or continue editing while compiling.

就像在 IDE 中编译程序一样,编译错误将通过 errorformat 进行匹配并突出显示并变为可选。您可以在 quickfix 窗口中导航错误或在编译时继续编辑。

Quick setup

快速设置

Copy & paste the lines below to your vimrc:

将以下行复制并粘贴到您的 vimrc 中:

Plug 'skywind3000/asyncrun.vim'

" open quickfix window automatically when AsyncRun is executed
" set the quickfix window 6 lines height.
let g:asyncrun_open = 6

" ring the bell to notify you job finished
let g:asyncrun_bell = 1

" F10 to toggle quickfix window
nnoremap <F10> :call asyncrun#quickfix_toggle(6)<cr>

When you input “:AsyncRun echo hello ” in the command line:

当你在命令行中输入“:AsyncRun echo hello”时:

see the capture here

在这里看到捕获

You will see the realtime command output in the open quickfix window.

您将在打开的 quickfix 窗口中看到实时命令输出。

Compile and run a single file

编译并运行单个文件

Compiling a single file with AsyncRun is much simpler than Sublime Text's build system. We can setup F9 for this:

使用 AsyncRun 编译单个文件比 Sublime Text 的构建系统简单得多。我们可以为此设置 F9:

noremap <silent> <F9> :AsyncRun gcc -Wall -O2 "$(VIM_FILEPATH)" -o "$(VIM_FILEDIR)/$(VIM_FILENOEXT)" <cr>

The macros in $(..)form will be expanded as the real file name or directory, and then we will have F5 to run the executable:

$(..)form 中的宏会被扩展为真实的文件名或目录,然后我们将有 F5 来运行可执行文件:

noremap <silent> <F5> :AsyncRun -raw -cwd=$(VIM_FILEDIR) "$(VIM_FILEDIR)/$(VIM_FILENOEXT)" <cr>

The double quotation mark is used to handle path names containing spaces. The option -cwd=$(VIM_FILEDIR)means running the file in the file's directory. The absolute path name $(VIM_FILEDIR)/$(VIM_FILENOEXT)is used because linux needs a ./prefix to running executables in current directory, but windows doesn't . Using the absolute path name of the binary file can handle this crossing platform issue.

双引号用于处理包含空格的路径名。该选项-cwd=$(VIM_FILEDIR)表示在文件目录中运行该文件。使用绝对路径名$(VIM_FILEDIR)/$(VIM_FILENOEXT)是因为 linux 需要一个./前缀才能在当前目录中运行可执行文件,但 windows 不需要。使用二进制文件的绝对路径名可以处理这个跨平台问题。

Another option -rawmeans the output will not be matched by vim's errorformat, and will be displayed in quickfix as what it is. Now you can compile your file with F9, check the compilation errors in quickfix window and press F5 to run the binary.

另一个选项-raw意味着输出将不会与 vim 的错误格式匹配,并将在 quickfix 中显示为原样。现在你可以用 F9 编译你的文件,检查 quickfix 窗口中的编译错误,然后按 F5 运行二进制文件。

Build C/C++ Projects

构建 C/C++ 项目

No matter what build tool you are using, make or cmake, project building means acting to a group of files. It requires locating the project root directory. AsyncRun uses a simple method called root markers to identify the project root. The Project Root is identified as the nearest ancestor directory of the current file which contains one of these directories or files:

无论您使用什么构建工具,make 还是 cmake,项目构建都意味着对一组文件进行操作。它需要找到项目根目录。AsyncRun 使用一种称为根标记的简单方法来标识项目根。项目根目录被标识为当前文件的最近祖先目录,其中包含以下目录或文件之一:

let g:asyncrun_rootmarks = ['.svn', '.git', '.root', '_darcs'] 

If none of the parent directories contains these root markers, the directory of the current file is used as the project root. This enables us to use either <root>or $(VIM_ROOT)to represent the project root. and F7 can be setup to build the current project:

如果没有父目录包含这些根标记,则将当前文件的目录用作项目根。这使我们能够使用<root>$(VIM_ROOT)代表项目根。可以设置 F7 来构建当前项目:

noremap <silent> <F7> :AsyncRun -cwd=<root> make <cr>

What if your current project is not in any git or subversion repository ? How to find out where is my project root ? The solution is very simple, just put an empty .root file in your project root, it will be located easily.

如果您当前的项目不在任何 git 或 subversion 存储库中怎么办?如何找出我的项目根在哪里?解决方法很简单,只要在你的项目根目录下放一个空的 .root 文件,就很容易找到了。

Let's move on, setup F8 to run the current project:

让我们继续,设置 F8 来运行当前项目:

noremap <silent> <F8> :AsyncRun -cwd=<root> -raw make run <cr>

The project will run in its root directory. Of course, you need define the run rule in your own makefile. then remap F6 to test:

该项目将在其根目录中运行。当然,您需要在自己的 makefile 中定义运行规则。然后重新映射 F6 进行测试:

noremap <silent> <F6> :AsyncRun -cwd=<root> -raw make test <cr>

If you are using cmake, F4 can be map to update your Makefile:

如果您使用的是 cmake,可以映射 F4 来更新您的 Makefile:

nnoremap <silent> <F4> :AsyncRun -cwd=<root> cmake . <cr>

Due to the implementation of c runtime, if the process is running is a non-tty environment, all the data in stdout will be buffered until process exits. So, there must be a fflush(stdout)after your printfstatement if you want to see the real-time output. or you can close the stdout buffer at the beginning by

由于c runtime的实现,如果进程运行的是非tty环境,stdout中的所有数据都会被缓存,直到进程退出。因此,如果您想查看实时输出,则必须有一个fflush(stdout)afterprintf语句。或者您可以在开始时关闭标准输出缓冲区

setbuf(stdout, NULL);

At the mean time, if you are writing C++ code, a std::endl can be appended to the end of std::cout. It can force flush the stdout buffer. If you are developing on windows, AsyncRun can open a new cmd window for the child process:

同时,如果您正在编写 C++ 代码,则可以将 std::endl 附加到 std::cout 的末尾。它可以强制刷新标准输出缓冲区。如果你是在windows上开发,AsyncRun可以为子进程打开一个新的cmd窗口:

nnoremap <silent> <F5> :AsyncRun -cwd=$(VIM_FILEDIR) -mode=4 "$(VIM_FILEDIR)/$(VIM_FILENOEXT)" <cr>
nnoremap <silent> <F8> :AsyncRun -cwd=<root> -mode=4 make run <cr>

Using the option -mode=4on windows will open a new prompt window to run the command, just like running command line programs in Visual Studio. Finally, we have these key mappings below:

-mode=4在 windows 上使用该选项将打开一个新的提示窗口来运行命令,就像在 Visual Studio 中运行命令行程序一样。最后,我们在下面有这些键映射:

  • F4: update Makefile with cmake.
  • F5: run the single file
  • F6: run project test
  • F7: build project
  • F8: run project
  • F9: compile the single file
  • F10: toggle quickfix window
  • F4:使用 cmake 更新 Makefile。
  • F5:运行单个文件
  • F6:运行项目测试
  • F7:构建项目
  • F8:运行项目
  • F9:编译单个文件
  • F10:切换快速修复窗口

It is more like build system in NotePad++ and GEdit. If you are using cmake heavily, you can write a simple shell script located in ~/.vim/script/build.shto combine F4 and F7 together: it will update Makefile if CMakeList.txt has been changed, then exectute make.

它更像是 NotePad++ 和 GEdit 中的构建系统。如果你大量使用 cmake,你可以写一个简单的 shell 脚本~/.vim/script/build.sh来将 F4 和 F7 组合在一起:如果 CMakeList.txt 被更改,它将更新 Makefile,然后执行 make。

Advanced usage

高级用法

You can also define shell scripts in your dotfiles repository and execute the script with F3:

您还可以在 dotfiles 存储库中定义 shell 脚本并使用 F3 执行脚本:

nnoremap <F3> :AsyncRun -cwd=<root> sh /path/to/your/dotfiles/script/build_advanced.sh <cr>

The following shell environment variables are defined by AsyncRun:

以下 shell 环境变量由 AsyncRun 定义:

$VIM_FILEPATH  - File name of current buffer with full path
$VIM_FILENAME  - File name of current buffer without path
$VIM_FILEDIR   - Full path of current buffer without the file name
$VIM_FILEEXT   - File extension of current buffer
$VIM_FILENOEXT - File name of current buffer without path and extension
$VIM_CWD       - Current directory
$VIM_RELDIR    - File path relativize to current directory
$VIM_RELNAME   - File name relativize to current directory 
$VIM_ROOT      - Project root directory
$VIM_CWORD     - Current word under cursor
$VIM_CFILE     - Current filename under cursor
$VIM_GUI       - Is running under gui ?
$VIM_VERSION   - Value of v:version
$VIM_COLUMNS   - How many columns in vim's screen
$VIM_LINES     - How many lines in vim's screen
$VIM_SVRNAME   - Value of v:servername for +clientserver usage

All the above environment variables can be used in your build_advanced.sh. Using the external shell script file can do more complex work then a single command.

以上所有环境变量都可以在你的build_advanced.sh. 使用外部 shell 脚本文件可以完成比单个命令更复杂的工作。

Grep symbols

Grep 符号

Sometimes, If you don't have a well setup environment in you remote linux box, grep is the most cheap way to search symbol definition and references among sources. Now we will have F2 to search keyword under cursor:

有时,如果您在远程 linux 机器中没有良好的设置环境,grep 是在源中搜索符号定义和引用的最便宜的方法。现在我们将有 F2 来搜索光标下的关键字:

if has('win32') || has('win64')
    noremap <F2> :AsyncRun! -cwd=<root> grep -n -s -R <C-R><C-W> --include='*.h' --include='*.c*' '<root>' <cr>
else
    noremap <F2> :AsyncRun! -cwd=<root> findstr /n /s /C:"<C-R><C-W>" "\%CD\%\*.h" "\%CD\%\*.c*" <cr>
endif

The above script will run grep or findstr in your project root directory, and find symbols in only .c, .cppand .hfiles. Now we move around the cursor and press F2, the symbol references in current project will be displayed in the quickfix window immediately.

上面的脚本将在您的项目根目录中运行 grep 或 findstr,并仅在.c,.cpp.h文件中查找符号。现在我们移动光标并按F2,当前项目中的符号引用将立即显示在quickfix窗口中。

This simple keymap is enough for most time. And you can improve this script to support more file types or other grep tools in your vimrc .

大多数情况下,这个简单的键盘映射已经足够了。您可以改进此脚本以在 vimrc 中支持更多文件类型或其他 grep 工具。

That's the practical way to build/run C/C++ projects in Vim 8 or NeoVim. Just like Sublime Text's build system and NotePad++'s NppExec.

这是在 Vim 8 或 NeoVim 中构建/运行 C/C++ 项目的实用方法。就像 Sublime Text 的构建系统和 NotePad++ 的 NppExec。

No more outdated vim tutorials again, try something new.

不再有过时的 vim 教程,尝试新的东西。

回答by yask

Add this line in your vimrcfile

在您的vimrc文件中添加这一行

nnoremap <silent> <F8> :!clear;gcc % -o % && ./%<CR>

Now you only have to press f8 key to compile and run your c program.

现在您只需按 f8 键即可编译和运行您的 c 程序。

回答by Alpaca

Just thought I would add this to these answers here. As has been mentioned, you can use the :makecommand in vim. What has not been mentioned yet, is that :makecan invoke other programs, other than make.

只是想我会把这个添加到这些答案中。如前所述,您可以:make在 vim 中使用该命令。还没有提到的是,:make可以调用其他程序,而不是make.

:set makeprg=gcc\ %

Will cause :maketo execute gccwith the %symbol replaced by the current file name.

将导致用当前文件名替换的符号:make执行。gcc%

You can then get fancy and do

然后你可以花心思做

:set makeprg=gcc\ %\ &&\ ./a.out

and simply typing :makewill compile and execute your program. You can do this for other languages as well of course.

只需键入即可:make编译并执行您的程序。当然,您也可以为其他语言执行此操作。

:set makeprg=cabal\ repl
:set makeprg=python\ %

回答by Dr Beco

After doing some research (including this very page), I made my mind to add this shortcut:

在做了一些研究(包括这个页面)之后,我决定添加这个快捷方式:

map <F9> :w<CR> :!gcc % -o %<.x -Wall -Wextra 2>errors.err; cat errors.err<CR>

You can also include -ansi -pedantic-errorsif you will.

-ansi -pedantic-errors如果愿意,您也可以包括在内。

The errors.errfile will help you with vi quickfix.

errors.err文件将帮助您使用 vi quickfix。

回答by Christopher Geiger

I looked through all of these solutions and I found that they didn't work (as far as I could tell) for the case of editing a file in a different directory -- I wrote some vimscript that does this in a kinda clunky way, but hopefully someone can find this useful:

我查看了所有这些解决方案,我发现它们在编辑不同目录中的文件时不起作用(据我所知)——我写了一些 vimscript,它以一种笨拙的方式来实现这一点,但希望有人能发现这很有用:

let mycommand = ':!gcc % -o %< && echo "%<" && [ $(pwd) == "." ] && %< || ./%< '
nnoremap <silent> <F8> :execute mycommand <CR>

or if the commands above work for you in multiple directories feel free to just ignore this.

或者如果上面的命令在多个目录中对您有用,请随意忽略它。

回答by Prashant Nidgunde

Add these three lines to your .vimrcfile

将这三行添加到您的.vimrc文件中

au FileType c set makeprg=gcc\ % 

au FileType cpp set makeprg=g++\ %

map <F7>:make && ./a.out<CR>

You can compile and run your program by pressing the F7button.

您可以通过按下F7按钮来编译和运行您的程序。