如何进行仅适用于特定情况的键绑定?

时间:2016-09-13 01:24:56

标签: vim

注意:条形符号(|)表示整个问题中的编辑器插入符号

我制作了一个像这样的UltiSnips片段:

snippet "(\w+)" "HTML tag" r
<`!p snip.rv = match.group(1)`>$0</`!p snip.rv = match.group(1)`>
endsnippet

这允许我将任何单词扩展为HTML标记,例如输入“body”并按Tab键展开为<body>|</body>

插入符号位于标记之间。当我现在按回车时,我想最终:

<body>
    |
</body>

这可以通过这样的键绑定来完成:

:ino <buffer> <CR> <CR><Esc>O

但我不想永久重新绑定我的返回键。当我的插入符号放在开始和结束HTML标记之间时,我只希望这个特定的键绑定是活动的。

如何才能最简单地完成?

另一个例子是当我把我的插入符号放在两个大括号之间时,如下所示:

function() {|}

然后按回车键,我希望结果为:

function() {
    |
}

同样可以使用上面的键映射完成,但在这种情况下,我只希望它在我的插入符号位于两个大括号之间时处于活动状态。

2 个答案:

答案 0 :(得分:0)

您可以使用 map-expression (请参阅:h map-expression)来确定当您点击它时<CR>映射到的是什么:

例如以下插入模式映射:

inoremap <expr> <CR> strpart(getline('.'), col('.')-2, 1) =~ '[>{]' ? '<CR><ESC>O' : '<CR>'

在光标前检查charachter,如果其>{在其他情况下返回<CR><ESC>O,则只需执行<CR>

代替条件三元表达式,您可以定义一个完整的函数函数,以便在任何情况下对任何对进行响应;但是已经有很好的插件打算优雅地完成这些任务:

demilitMateauto-pairs是两个着名的。

试一试。

答案 1 :(得分:0)

我已经在lh-brackets中实现了这一点,我记得在这里回答了一个非常接近的问题:How to move opening curly braces to a new line in Vim?

我用以下方式定义:

  call lh#brackets#enrich_imap('<cr>',
        \ {'condition': 'getline(".")[col(".")-2:col(".")-1]=="{}"',
        \   'action': 'lh#brackets#_add_newline_between_brackets()'},
        \ 0,
        \ '\<cr\>'
        \ )

如果你想区分语言情况,你必须拥有c(以及所有其他基于括号的语言)的ftplugins,xml(以及其他基于标记的语言),你有inoremap <buffer> <expr>测试上下文(请参阅上面的测试)返回"<cr>""<cr><esc>O"

" to be put in c, js, java, c#... ftplugins
inoremap <buffer> <expr> <cr> getline(".")[col(".")-2:col(".")-1]=="{}" ? '<cr> : '<cr><esc>O'

" to be put in a xml and HTML ftplugin
inoremap <buffer> <expr> <cr> getline(".")[col(".")-2:col(".")-1]=="><" ? '<cr> : '<cr><esc>O'

您也可以在vimrc中全局定义它们,但是,它会一直触发 - 在这种情况下需要合并测试。