在Vim中自动插入一个匹配的大括号

我花了太多时间摸索,因为Vim不像大多数IDE那样处理闭括号。 这是我想要发生的事情:

input这个:

if( whatever ) { <CR> 

并得到这个:

 if( whatever ) { | } 

其中<CR>表示按ENTER键和| 是光标的位置。 这是Eclipse所做的。 这是Visual Studio所做的。 而这正是我想要Vim做的。

我见过几个插件,尝试了几个,他们都没有给我这种行为。 当然,我不能成为第一个想要这个的程序员。

在VimL中,你可以映射{完全按照你的意愿去做:

 inoremap { {<CR>}<Esc>ko 

根据您的autoindent设置,您可能需要在<CR>之后添加一个<BS> <CR>

为了获得更完整的解决scheme,我build议你看看Luc Hermitte的vim插件 。 到目前为止,他们从未失败过。

为了在一个新行上得到结束括号并将光标放在两个括号之间的行上,请按照题为“ 使括号和括号处理更容易 ”的文章中的第一个注释的build议。

使用AutoClose以正确的以下工作。

 inoremap {<CR> {<CR>}<Co>O 

至less我的系统是这样的(Mac OS X上的Unixterminal)。

这是我在我的vimrc:

 let s:pairs={ \'<': '>', \'{': '}', \'[': ']', \'(': ')', \'«': '»', \'„': '“', \'“': '”', \''': ''', \} call map(copy(s:pairs), 'extend(s:pairs, {v:val : v:key}, "keep")') function! InsertPair(left, ...) let rlist=reverse(map(split(a:left, '\zs'), 'get(s:pairs, v:val, v:val)')) let opts=get(a:000, 0, {}) let start = get(opts, 'start', '') let lmiddle = get(opts, 'lmiddle', '') let rmiddle = get(opts, 'rmiddle', '') let end = get(opts, 'end', '') let prefix = get(opts, 'prefix', '') let start.=prefix let rmiddle.=prefix let left=start.a:left.lmiddle let right=rmiddle.join(rlist, '').end let moves=repeat("\<Left>", len(split(right, '\zs'))) return left.right.moves endfunction noremap! <expr> ,f InsertPair('{') noremap! <expr> ,h InsertPair('[') noremap! <expr> ,s InsertPair('(') noremap! <expr> ,u InsertPair('<') 

而且,对于一些文件types:

 inoremap {<CR> {<Co>o}<Co>O 

//我知道InsertPair函数是微不足道的,但是它节省了时间,因为使用它我可以用一个命令定义命令模式和普通模式映射,而不必写很多<Left>

对于像我这样运行的任何人,并且正在寻找比AutoClose更新的东西: delimitMate我发现,不仅是AutoClose的一个可取的解决scheme,行为明智的,而且还在积极的开发中。 根据vim.org ,AutoClose自2009年以来没有更新。

delimitMate有一个这样的设置。

我已经尝试了不同的插件,但我发现最准确和最容易使用的自动配对 。 这是非常直观的,当你安装它,你会得到你所期望的开箱即用。

正如你将会在维基提示中看到的那样:对这个经常性问题有许多解决scheme(我甚至有我的 )。

这是如果你限制自己的括号对。 在这里你是在一个控制语句的上下文中。 因此,您更可能find代码片断系统,当input“if”语句时,不会指望您input“){”。 Vim的快捷键往往比我在你的问题中读到的要短。 在这里再次有很多select,你会发现最有可能的snipmate,可能是我的C&C ++套件 。

按照标题为自动追加结束字符的文章中的build议安装和使用Vim脚本AutoClose 。

只是对@Bob的一个说明。

Karl Guertin的AutoClose有一个名为“double brace''的函数,也就是说,你可以input两次大括号,如下所示。

 int func_name(void) {{ ==> Type `{' twice here. 

会导致:

 int func_name(void) { | ==> Cursor here. } 

然后,你可以input一个Tab,按照'shiftwidth'设置缩进,然后input。

Vim补丁7.4.849添加了一个绑定,允许光标移动,而无需重新启动撤销序列。 一旦更新到> = 7.4.849,那么这样的事情很好。

 inoremap ( ()<CG>U<Left> 

请注意,我从修补程序中包含的文档中直接获取了该信息。 这个function的最简单的解决scheme呢。

  • 提交补丁7.4.849: https : //github.com/vim/vim/commit/8b5f65a527c353b9942e362e719687c3a7592309
  • 邮件列表主题: http : //vim.1045645.n5.nabble.com/Any-automatic-bracket-insertion-plugins-not-breaking-undo-td5723654.html

我总是喜欢什么样的崇高的文本做附加括号作为下一个字符,所以我添加了以下内容到我的.vimrc:

 inoremap ( ()hli 

将光标移动到两个大括号之间。

你不需要一个特殊的插件来做到这一点,但这是一个两步的过程。

首先,将以下内容添加到.vimrc以使用触发字符:

 " eat characters after abbreviation function! Eatchar(pat) let c = nr2char(getchar(0)) return (c =~ a:pat) ? '' : c endfunction 

然后将这个缩写添加到您的.vimrc

 inoreabbr <silent> { { \<cr><space><space> \<cr><esc>0i}<esc>k$i<cr>=Eatchar('\m\s\<bar>\r')<cr> 

第二行和第三行的开头只是一个连续的字符。 你可以在一行上完成这一切,但是我添加了它,这样我就可以用缩写的方式来反映你正在寻找的输出 – 只是让事情变得更直观。

将以下内容放在.vimrc文件中:

 inoremap { {}<ESC>ha 

无论何时按下{在插入模式下,都会生成{} ,并将光标放在右边的大括号上,以便您可以立即在它们之间打字。 通过按顺序放置花括号而不是按不同的行,可以手动将标签放在}前面。 这样,你永远不会有错误的标签在它的前面。

也许有人可以弄清楚如何计算光标所在的标签数量,然后在新行的前面生成等量的标签。