我在 Vim 中的典型日常工作流程包括两个垂直窗格;左边是生产代码,右边是测试。
我经常切换语言(和测试框架),所以我喜欢创建一个新的映射来在每个会话中运行我的测试代码。假设我正在做一些 Ruby 项目并且我正在lib/importer.rb. 随附的规范位于spec/lib/importer_spec.rb.
要创建用于运行规范的映射,我将关注显示规范的窗格,然后输入以下内容:
:nnoremap -g :!rspec %<cr>
Run Code Online (Sandbox Code Playgroud)
注意:我使用连字符/减号作为我的主键。
这有效,但仅当我点击时规范窗格具有焦点-g。如果生产窗格具有焦点并且我点击了映射,则rspec将尝试运行生产代码,这是没有意义的。
要解决此问题,我可以将绝对路径写入规范文件:
:nnoremap -g :!rspec spec/lib/importer_spec.rb<cr>
Run Code Online (Sandbox Code Playgroud)
这行得通,虽然写起来有点麻烦。
昨晚在阅读Practical Vim 时,我意识到在命令模式下你可以使用%扩展——你写%然后点击tab,百分比被替换为当前聚焦窗格中文件的绝对路径。
如果我这样做:
:!rspec %
Run Code Online (Sandbox Code Playgroud)
……然后点击tab,我明白了:
:!rspec spec/lib/importer_spec.rb
Run Code Online (Sandbox Code Playgroud)
这太棒了!但是,如果我这样做:
:nnoremap -g :!rspec %
Run Code Online (Sandbox Code Playgroud)
……然后点击tab,我明白了:
:nnoremap -g :!rspec %^I
Run Code Online (Sandbox Code Playgroud)
我是个好人,我纳税。为什么这会发生在我身上?
默认情况下,映射中无法识别命令完成(并记录在宏中)。您可以在晦涩的'wildcharm'选项中定义一个替代键并使用它。但是,可以以更简单、更直接的方式插入当前文件名。无需完成%,只需通过<C-r>以下方式插入等效的 Vimscript 表达式:
:nnoremap -g :!rspec <C-r>=expand('%')<cr><cr>
Run Code Online (Sandbox Code Playgroud)
PS:要妥善处理所有种类的文件名,另外使用shellescape():
:nnoremap -g :!rspec <C-r>=shellescape(expand('%'), 1)<cr><cr>
Run Code Online (Sandbox Code Playgroud)
PPS:我希望你不是每次都手动输入映射,而是使用文件类型插件或:autocmd为测试缓冲区自动定义它。我绝对建议以这种方式使其自动化。