在vim map-operator函数中使用外部命令

时间:2013-08-20 19:28:15

标签: vim

我想创建一个vim映射,允许运动控制要输出的文本。似乎没有关于这方面的大量文档,我无法适应the sample in vim's help page我需要的东西。这就是我所拥有的,它没有错误但不替换文本。我错过了什么?

nmap ,s :set opfunc=CustomFunc<cr>g@

function! CustomFunc(type, ...)
    let sel_save = &selection
    let &selection = "inclusive"
    let reg_save = @@

    if a:type == 'line'
        silent exe "normal! '[V']!sort"
    elseif a:type == 'block'
        silent exe "normal! `[\<C-V>`]!sort"
    else
        silent exe "normal! `[v`]!sort"
    endif

    let &selection = sel_save
    let @@ = reg_save
endfunction

我使用!sort作为测试的一个非常简单的示例。这里的想法是你可以有一个像:

{
    Hello, World!
    Hello, Earth!
    Hello, Planet!
}

如果您要将光标移动到{}块中的某个位置并键入,si{,它将用

替换块
{
    Hello, Earth!
    Hello, Planet!
    Hello, World!
}

解决方法是vi{:!sort<cr>,或者如果你有vmap ,s :!sort然后vi{,s,但将它作为运算符映射(减少输入,更灵活等)会很好

2 个答案:

答案 0 :(得分:2)

我不认为使用:!的外部过滤可能是其他任何行,然后是行。

如果你需要这样的东西,我认为你需要求助于system函数和“手动”操作缓冲区内容,而不是依赖于Vim的过滤命令。

在线条的情况下,以下更简单的咒语修复了它:

'[,']!sort

即代替silent exe "normal! '[V']!sort"。我认为exec / normal隐含的额外模式切换会导致运营商挂起模式(?)。

{
    Hello, World!
    Hello, Earth!
    Hello, Planet!
}

(光标在W上,键入 S i B ):

{
    Hello, Earth!
    Hello, Planet!
    Hello, World!
}

答案 1 :(得分:1)

Ex命令总是按行进行,因此无法轻松完成您想要的操作。有一些插件可以帮助你(例如Dr. Chips VIS plugin或我的NrrwRgn插件。但我不确定,如果他们在特定的omaps情况下帮助你。