我正在配置vimrc文件,以便使用c ++进行竞争性编程。
autocmd filetype cpp nnoremap <F5> :w <CR>
:!g++ -o %:r % <CR> :!./%:r < input.txt <CR>
下面的映射是当我按F5键时,它保存,编译(%:r是不带.cpp的文件名),并与input.txt文件一起运行。
但是,并不是每个cpp文件都具有input.txt,因此,仅在当前目录中存在input.txt时,我才希望通过管道传输input.txt。
总而言之,在映射过程中检查文件的最佳方法是什么?
答案 0 :(得分:2)
除非您正在无法使用gnu make或配置不正确(mingw)的环境中工作,否则单文件项目将不需要任何Makefile
。在这种情况下,它们不是强制性的,并且IMO比其他任何事情都更加麻烦。
:make %<
这样,任何错误都会直接转到quickfix窗口。这样可以提高查找错误(:h quickfix
)的效率。另外,无论您的当前文件是C,C ++,Fortran ...还是默认gnumake配置识别的任何语言,都不必根据当前文件类型指定要使用的编译器。例如,如果您确实想为C ++选择另一个编译器,则可以使用
:let $CXX ='clang++'
" $CC for C, and so on
如果您想更改编译选项
:let $CXXFLAGS = '-std=c++17 -Wall -Werror'
" $CFLAGS for C, $LDLIBS, $LDFLAGS for the linker, and so on
请注意,如果您有Makefile
,它将被自动使用。
:!make %< && ./%<
确实很简单,可以链接两个步骤。 las,我们没有:make
的直接等价物。我们必须分析快速修复列表以查看是否存在任何问题
如果filter(getqflist(), 'v:val.valid != 0')
不为空,我们可以知道是否已检测到问题。但这并不能说明它们是警告还是错误。我们可以提供以下完整的信息
" From my build-tools-wrapper plugin
function! lh#btw#build#_get_metrics() abort
let qf = getqflist()
let recognized = filter(qf, 'get(v:val, "valid", 1)')
" TODO: support other locales, see lh#po#context().tranlate()
let errors = filter(copy(recognized), 'v:val.type == "E" || v:val.text =~ "\\v^ *(error|erreur)"')
let warnings = filter(copy(recognized), 'v:val.type == "W" || v:val.text =~ "\\v^ *(warning|attention)"')
let res = { 'all': len(qf), 'errors': len(errors), 'warnings': len(warnings) }
return res
endfunction
由此,我们可以决定仅停止出现错误,或者停止出现错误和警告。
使用filereadable()
,我们可以知道输入文件是否在这里。
因此变成:
let exec_line = '!./' . expand('%<') " we could also use the complete path instead
let input = expand('%:p:h')/.'input.txt'
if filereadable(input)
let exec_line .= ' < ' . input
endif
exe exec_line
如果您想在:terminal中重定向结果,那么不幸的是,这次重定向不能与Vim一起使用(尽管它可以与nvim一起使用)
最终代码(赋予先前的功能以检测错误和警告)成为
function s:build_and_run(file) abort
let tgt = fnamemodify(a:file, ':r')
" to make sure the buffer is saved
exe 'update ' . a:file
exe 'make ' . tgt
if lh#btw#build#_get_metrics().errors
echom "Error detected, execution aborted"
copen
return
endif
let path = fnamemodify(a:file, ':p:h')
let exec_line = '!./' . tgt
let input = path.'/input.txt'
if filereadable(input)
let exec_line .= ' < ' . input
endif
exe exec_line
endfunction
nnoremap µ :<C-U>call <sid>build_and_run(expand('%'))<cr>
答案 1 :(得分:1)
通过输入文件运行它是什么意思? 我认为您应该考虑使用Makefile。在这里,对所有构建依赖项(包括包含,链接路径,测试执行等)进行建模。
您的绑定将如下所示,并且对于包含Makefile的所有文件夹来说都是相同的
autocmd filetype cpp nnoremap <F5> :w <CR> :!make all<CR>
答案 2 :(得分:1)
我为此专门创建了一个插件。 Link to Repo
通过一次击键(默认为 F9),它从名为 input.txt 的文件中获取输入并将输出转储到本地目录中名为 output.txt 的文件中。这适用于编译和运行单个 .cpp 文件。
这使用 vim 的 rysnc 和 local vimrc 插件作为依赖项,尽管您可以使用任何本地 vimrc 插件。
答案 3 :(得分:0)