如何在可视模式下使用vim变量作为外部过滤命令的参数?

5
我想要制作一个代码美化器过滤器(如perltidy),以便根据vim变量接受任意选项。我的目标是将项目特定选项传递给在可视模式下用作过滤器(:!)的外部命令。
以下是我的意图(最后一行存在问题):
" set b:perltidy_options based on dirname of the currently edited file
function! SetProjectVars()
  if match(expand("%:p:h"), "/project-foo/") >= 0
    let b:perltidy_options = "--profile=$HOME/.perltidyrc-foo --quiet"
  elseif match(expand("%:p:h"), "/project-bar/") >= 0
    let b:perltidy_options = "--profile=$HOME/.perltidyrc-bar --quiet"
  else
    let b:perltidy_options = "--quiet"
  endif
endfunction

" first set the project specific stuff
autocmd BufRead,BufNewFile * call SetProjectVars()

" then use it
vnoremap ,t :execute "!perltidy " . b:perltidy_options<Enter>

然而,在vim中,最后一行(vnoremap)是一个错误,因为它会扩展成:
:'<,'>execute "!perltidy " . b:perltidy_options

并且 execute 命令无法接受范围参数。但是我想要这个:

:execute "'<,'>!perltidy " . b:perltidy_options

我该怎么做?
附注:我的 perltidy 配置成像 Unix 过滤器一样工作,我使用 vim 7.3。
2个回答

2
如果你想在命令(ex)模式下删除一段范围,使用CRL-u就可以了。
vnoremap ,t :execute "!perltidy " . b:perltidy_options<Enter>

变成

vnoremap ,t :<C-u>execute "!perltidy " . b:perltidy_options<CR>

:h c_CTRL-u

Happy vimming,

-Luke


2
您可以使用<C-\>egetcmdline()来保留命令行内容:
vnoremap ,t :<C-\>e'execute '.string(getcmdline()).'."!perltidy " . b:perltidy_options'<CR><CR>

但在这种情况下,我建议使用更简单的<C-r>=,它可以省去:execute的需要:

vnoremap ,t :!perltidy <C-r>=b:perltidy_options<CR><CR>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接