我正在配置 vimrc 文件以进行 C++ 竞争性编程。
autocmd filetype cpp nnoremap <F5> :w <CR>
:!g++ -o %:r % <CR> :!./%:r < input.txt <CR>
Run Code Online (Sandbox Code Playgroud)
以下映射是当我按 F5 时,它保存、编译(%:r 是不带 .cpp 的文件名),并使用 input.txt 文件运行。
但是,并非每个 cpp 文件都有 input.txt,因此我只想仅当当前目录中存在 input.txt 时才通过管道传输 input.txt。
总而言之,在映射过程中检查文件的最佳方法是什么?
除非您在 gnu make 不可用或配置不当 (mingw) 的环境中工作,否则您不需要任何Makefile单文件项目。在这种情况下,它们不是强制性的,而且在我看来,这比其他任何事情都更麻烦。
:make %<\nRun Code Online (Sandbox Code Playgroud)\n这样,任何错误都会直接进入快速修复窗口。这将提高您查找错误的效率 ( :h quickfix)。另外,无论您当前的文件是 C、C++、Fortran...还是默认 gnumake 配置识别的任何语言,您都不必根据当前文件类型指定您希望使用的编译器。例如,如果您确实想为 C++ 选择另一个编译器,您可以使用
:let $CXX =\'clang++\'\n" $CC for C, and so on\nRun Code Online (Sandbox Code Playgroud)\n如果您想更改编译选项
\n:let $CXXFLAGS = \'-std=c++17 -Wall -Werror\'\n" $CFLAGS for C, $LDLIBS, $LDFLAGS for the linker, and so on\nRun Code Online (Sandbox Code Playgroud)\n另请注意,如果您有Makefile,它将自动使用。
:!make %< && ./%<确实很简单,可以链接这两个步骤。唉,我们没有与 直接等效的东西:make。我们必须分析快速修复列表以查看是否存在任何问题
如果filter(getqflist(), \'v:val.valid != 0\')不为空就可以知道是否检测到问题。但它并不能说明它们是警告还是错误。我们可以通过以下方式获得完整的信息
" From my build-tools-wrapper plugin\nfunction! lh#btw#build#_get_metrics() abort\n let qf = getqflist()\n let recognized = filter(qf, \'get(v:val, "valid", 1)\')\n " TODO: support other locales, see lh#po#context().tranlate()\n let errors = filter(copy(recognized), \'v:val.type == "E" || v:val.text =~ "\\\\v^ *(error|erreur)"\')\n let warnings = filter(copy(recognized), \'v:val.type == "W" || v:val.text =~ "\\\\v^ *(warning|attention)"\')\n let res = { \'all\': len(qf), \'errors\': len(errors), \'warnings\': len(warnings) }\n return res\nendfunction\nRun Code Online (Sandbox Code Playgroud)\n由此我们可以决定仅在错误或错误和警告时停止。
\n通过filereadable()我们可以知道输入文件是否在这里。
因此它变成:
\nlet exec_line = \'!./\' . expand(\'%<\') " we could also use the complete path instead\nlet input = expand(\'%:p:h\')/.\'input.txt\'\nif filereadable(input)\n let exec_line .= \' < \' . input\nendif\nexe exec_line\nRun Code Online (Sandbox Code Playgroud)\n如果你想在 :terminal 中重定向结果,不幸的是,重定向不能与 Vim 一起使用(尽管它可以与 nvim 一起使用)
\n最终代码(给出了之前检测错误和警告的函数)。
\nfunction s:build_and_run(file) abort\n let tgt = fnamemodify(a:file, \':r\')\n " to make sure the buffer is saved\n exe \'update \' . a:file\n exe \'make \' . tgt\n if lh#btw#build#_get_metrics().errors\n echom "Error detected, execution aborted"\n copen\n return\n endif\n\n let path = fnamemodify(a:file, \':p:h\')\n let exec_line = \'!./\' . tgt\n let input = path.\'/input.txt\'\n if filereadable(input)\n let exec_line .= \' < \' . input\n endif\n exe exec_line\nendfunction\n\nnnoremap \xc2\xb5 :<C-U>call <sid>build_and_run(expand(\'%\'))<cr>\nRun Code Online (Sandbox Code Playgroud)\n