如何从VIM运行C程序?

Cod*_*der 40 c vim

有没有办法从VIM编译和运行C程序而不键入其文件名?

tst*_*ner 98

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

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

  • +1表示%被文件名替换. (18认同)
  • @Coder:不,你可以接受答案.只需点击支票即可.你不需要任何投票数. (9认同)

ung*_*ban 42

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

 map <F8> : !gcc % && ./a.out <CR>
Run Code Online (Sandbox Code Playgroud)

F8键用于运行映射."%"是获取当前文件名.

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

map <F8> :w <CR> :!gcc % && ./a.out <CR>
Run Code Online (Sandbox Code Playgroud)

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

map <F8> :w <CR> :!gcc % -o %< && ./%< <CR>
Run Code Online (Sandbox Code Playgroud)

在上面的命令中,"%"之后的"<"删除了扩展名和点(foo.c => foo),因此"%<"是文件基本名称.

您可以在cmdline.txt中找到此类似的信息.vim中的命令:help: cmdline.txt.您还可以:help filename-modifiers在vim中找到有关使用"%"的具体详细信息.

  • 请注意,空格字符是有效的正常模式命令,可将光标向右移动一个空格。因此,如果可能,您在第二个映射中链接在一起的两个 ex 命令之间的空间将在编译之前移动光标。如果向右移动光标失败,则编译步骤将永远不会运行。 (2认同)

Luc*_*tte 9

TL; DR没有Makefile是必需的,调整&makeprg也完全没用,但:make %<足以从Vim编译.

答案很长:

我在一个封闭的"重复问题"中复制了我给出的答案.

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

在类Linux(它也适用于在cygwin,而不是在Windows上的MinGW -在MinGW的情况下,看到改变其他的答案&makeprg,不要管它否则)在安装gnumake的系统中,如果你没有在一个Makefile您的项目,如果您的项目只由一个文件组成,请输入:make %<.这就足够了(你可以玩$CXXFLAGS,$CFLAGS并$LDFLAGS调整编译选项).然后运行程序,键入:!./%<或使用后一版本的vim,运行:terminal ./%<.

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

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

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

最后,如果你想在单个按键上编译那些单文件项目,你可以添加.vimrc:

nnoremap <silent> <f7> :make %<<cr>
Run Code Online (Sandbox Code Playgroud)

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

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


sky*_*000 7

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

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

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

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

快速设置

将以下行复制并粘贴到您的 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>
Run Code Online (Sandbox Code Playgroud)

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

在这里看到捕获

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

编译并运行单个文件

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

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

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

noremap <silent> <F5> :AsyncRun -raw -cwd=$(VIM_FILEDIR) "$(VIM_FILEDIR)/$(VIM_FILENOEXT)" <cr>
Run Code Online (Sandbox Code Playgroud)

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

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

构建 C/C++ 项目

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

let g:asyncrun_rootmarks = ['.svn', '.git', '.root', '_darcs'] 
Run Code Online (Sandbox Code Playgroud)

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

noremap <silent> <F7> :AsyncRun -cwd=<root> make <cr>
Run Code Online (Sandbox Code Playgroud)

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

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

noremap <silent> <F8> :AsyncRun -cwd=<root> -raw make run <cr>
Run Code Online (Sandbox Code Playgroud)

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

noremap <silent> <F6> :AsyncRun -cwd=<root> -raw make test <cr>
Run Code Online (Sandbox Code Playgroud)

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

nnoremap <silent> <F4> :AsyncRun -cwd=<root> cmake . <cr>
Run Code Online (Sandbox Code Playgroud)

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

setbuf(stdout, NULL);
Run Code Online (Sandbox Code Playgroud)

同时,如果您正在编写 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>
Run Code Online (Sandbox Code Playgroud)

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

  • F4:使用 cmake 更新 Makefile。
  • F5:运行单个文件
  • F6:运行项目测试
  • F7:构建项目
  • F8:运行项目
  • F9:编译单个文件
  • F10:切换快速修复窗口

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

高级用法

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

nnoremap <F3> :AsyncRun -cwd=<root> sh /path/to/your/dotfiles/script/build_advanced.sh <cr>
Run Code Online (Sandbox Code Playgroud)

以下 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
Run Code Online (Sandbox Code Playgroud)

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

Grep 符号

有时,如果您在远程 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
Run Code Online (Sandbox Code Playgroud)

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

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

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

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


tol*_*ius 6

因为大多数时候你会使用Makefile,除了给定的答案之外,我还希望在"清除"屏幕上看到我的结果:

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

  • :w<CR> 保存文件

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

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


yas*_*ask 5

vimrc在您的文件中添加此行

nnoremap <silent> <F8> :!clear;gcc % -o % && ./%<CR>
Run Code Online (Sandbox Code Playgroud)

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

  • 最后两个 %s 使用 %:r 而不是 %,否则会覆盖您的源文件。我会编辑你的答案,但评论者今天心情不好。 (2认同)