c++ - 使用可选输入文件运行 C++ 的 vim 映射

标签 c++ vim

我正在配置 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。

总而言之,在映射过程中检查文件的最佳方式是什么?

最佳答案

除非您在 gnu make 不可用或配置不当 (mingw) 的环境中工作,否则您不需要任何 Makefile对于单文件项目。在那种情况下,它们不是强制性的,IMO 比其他任何事情都更麻烦。

编译最好用:

:make %<

这样任何错误都会直接转到快速修复窗口。这将提高您定位错误的效率 (: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 的直接等价物| .我们必须分析 quickfix 列表以查看是否有任何问题

如果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>

关于c++ - 使用可选输入文件运行 C++ 的 vim 映射,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56988941/

相关文章:

C++ 避免对未使用的代码部分发出警告

c++ - 禁用特定语言功能的自动完成

vim - 重新映射 :help in Vim to open in a new tab

Vim 删除从字符开始到行尾

vim - vi/vim 中的 s、c 和 r 命令有什么区别?

c++ - 使用静态成员函数访问静态数据成员

c++ - 使用缓存内存。映射技术

linux - Vim 保存文件时的行为有所不同

c++ - 如何将 CodeSynthesis-XSD 包含到自己的应用程序中?

c++ - 如何在 vim 中使用 cmake/gcc 编译/跳转调试