如何通过 Vim 中的外部命令过滤不跨越整行的可视选择的内容?
Posted
技术标签:
【中文标题】如何通过 Vim 中的外部命令过滤不跨越整行的可视选择的内容?【英文标题】:How to filter the contents of a Visual selection that does not span an entire line through an external command in Vim? 【发布时间】:2012-03-09 16:53:50 【问题描述】:我想通过命令过滤 Vim 中的视觉选择。我知道的方式总是过滤视觉选择延伸的完整线条:
在该行中选择a test
this is a test
然后打字
:'<,'>!echo "the result"
将导致
the result
但我想要:
this is the result
【问题讨论】:
另见“How to execute ‘base64 --decode’ on selected text in Vim?”。 【参考方案1】:考虑以下符合!
行为的映射
过滤命令(参见:helpg \*!\*
和:help v_!
)。
nnoremap <silent> <leader>! :set opfunc=ProgramFilter<cr>g@
vnoremap <silent> <leader>! :<c-u>call ProgramFilter(visualmode(), 1)<cr>
function! ProgramFilter(vt, ...)
let [qr, qt] = [getreg('"'), getregtype('"')]
let [oai, ocin, osi, oinde] = [&ai, &cin, &si, &inde]
setl noai nocin nosi inde=
let [sm, em] = ['[<'[a:0], ']>'[a:0]]
exe 'norm!`' . sm . a:vt . '`' . em . 'x'
call inputsave()
let cmd = input('!')
call inputrestore()
let out = system(cmd, @")
let out = substitute(out, '\n$', '', '')
exe "norm!i\<c-r>=out\r"
let [&ai, &cin, &si, &inde] = [oai, ocin, osi, oinde]
call setreg('"', qr, qt)
endfunction
【讨论】:
非常好!抱歉,我的问题不太准确(同上 kev)。它实际上是针对最常见的情况,在这种情况下我想要同时执行以下操作:1)将视觉选择传递给命令 2)使用短命令在 vim 中指定此命令;即 vim 命令应将示例中的“base64 --decode”作为参数。 换句话说,它应该有效地执行与过滤命令相同的操作!,仅用于视觉选择,而不是完整的行。 @user429540:现在我明白了。查看更新的答案,列出了为实现过滤命令而编写的映射。 我怎么称呼它? :',!回声(我的领导在哪里)?对我来说,它仍然做同样的事情:'!回声(没有领导者)。 @user429540:Leader是一个可配置的key,方便创建映射(见:help mapleader
);默认情况下,它是反斜杠字符。上面的映射应该与默认的!
过滤使用相同的方式:在可视模式下选择一段文本,然后按您的前导键(同样,默认情况下为反斜杠),然后按!
;或不选择任何内容,按下此组合键,然后使用运动命令(例如w
、W
、)
等)。【参考方案2】:
您可以使用\%V
在可视区域内进行匹配:
:'<,'>s/\%V.*\%V/\=system('echo -n "the result"')
【讨论】:
谢谢,这行得通,但是有点长。以 shell 命令为参数的 vmap 会是什么样子? .. 当然,在我的示例中,该命令不依赖于通常情况下的视觉选择。那么如何将视觉选择作为参数传递给命令呢?以上是关于如何通过 Vim 中的外部命令过滤不跨越整行的可视选择的内容?的主要内容,如果未能解决你的问题,请参考以下文章