如何在映射的rhs中转义shell命令?

时间:2014-05-07 06:05:05

标签: vim

我正在尝试在vim中创建一个简单的映射来执行shell命令。我想要执行的命令是:

ruby -e "Dir.glob('./spec/*_spec.rb').each {|f| require f}"

当我在命令行运行它时工作正常。

但是,如果我在vim中运行以下命令:

nmap ,t :!ruby -e "Dir.glob('./spec/*_spec.rb').each {|f| require f}"<cr>

我收到错误:

E492: Not an editor command: require f}"<cr>

注意:我在Windows上,如果相关的话。

  1. 我做错了什么?

  2. 奖励:如何改变上述命令,使其不依赖于包含&#34; spec&#34;的目录中的当前文件?理想情况下,如果当前文件的目录不包含&#34; spec&#34;,它将以递归方式检查父目录,依此类推,直到找到包含&#34; spec&#34;的目录为止。 。此时它将使用&#34;来运行命令。&#34;替换为我在上面的代码中找到的目录。

  3. 最终解决方案

    根据Ingo的回答,我的最终解决方案是:

    nnoremap ,tt :call RunAllMinitestSpecs()<cr>
    
    function! RunAllMinitestSpecs()
      let l:dir = finddir('spec', '.;')
      let l:dir = substitute(l:dir, '\', '/', 'g') " so it works on windows
      let l:ruby_cmd = "\"Dir.glob('" . l:dir . "/*_spec.rb').each {|f| require f}\""
      exe('!ruby -e ' . l:ruby_cmd)
    endfunction
    

1 个答案:

答案 0 :(得分:1)

|分隔Vim命令;对于Vim,映射在第一个|结束,Vim尝试将余数解释为命令(显然失败)。您需要通过\或(更好)使用映射中的特殊<Bar>表示法进行转义:

:nnoremap ,t :!ruby -e "Dir.glob('./spec/*_spec.rb').each {<Bar>f<Bar> require f}"<cr>

提示

You should use :noremap;它使映射不受重映射和递归的影响。

奖金回答

您可以通过:help file-searching进行向上搜索目标(finddir()),然后将结果传递给glob()。参见

:echo finddir('spec', '.;')

(然后我会将实现移动到:function,并从映射中调用它。这也可以避免|转义问题。)