如何在视觉模式下在外部过滤器命令中使用vim变量



我正试图让一个代码漂亮的打印机过滤器(例如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>

然而,最后一行(vnoremap)是vim中的一个错误,因为它扩展到:

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

并且执行命令不能接受范围。但我想要这个:

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

我该怎么做?

p.s.我的perltidy被配置为像unix过滤器一样工作,我使用vim 7.3。

您可以使用<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>

如果您想在命令(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

快乐的活力,

-Luke

最新更新