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

发布于 2025-01-03 23:32:40 字数 1040 浏览 1 评论 0原文

我正在尝试使代码漂亮的打印机过滤器(例如 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

我该怎么做?

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

I'm trying to make a code pretty printer filter (e.g. perltidy) accept arbitrary options depending on vim variables. My goal is to pass project specific options to an external command used as a filter (:!) in visual mode.

The following expresses my intention (the last line is problematic):

" 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>

However, the last line (vnoremap) is an error in vim, because it expands to:

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

and the execute command cannot accept a range.
But I'd like to have this:

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

How can I do this?

p.s. My perltidy is configured to act like a unix filter and I use vim 7.3.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

对岸观火 2025-01-10 23:32:40

您可以使用 egetcmdline() 来保留命令行内容:

vnoremap ,t :<C-\>e'execute '.string(getcmdline()).'."!perltidy " . b:perltidy_options'<CR><CR>

,但在这种情况下,我建议更简单的 < Cr>= 消除了对 :execute 的需要:

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

You can use <C-\>e and getcmdline() to preserve command-line contents:

vnoremap ,t :<C-\>e'execute '.string(getcmdline()).'."!perltidy " . b:perltidy_options'<CR><CR>

, but in this case I would suggest simpler <C-r>= which purges out the need for :execute:

vnoremap ,t :!perltidy <C-r>=b:perltidy_options<CR><CR>
み零 2025-01-10 23:32:40

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

快乐 vimming,

-Luke

If you ever want to get rid of a range in command (ex) mode,
CRL-u will do just that.

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

becomes

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

:h c_CTRL-u

Happy vimming,

-Luke

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文