在vim中自动创建匹配的大括号

Mar*_*rco 18 vim

如何在vim中自动创建匹配的大括号?

它应该如下工作:如果我输入一个左括号,右括号应该自动出现并且光标应该放在中间。为了跳出大括号对,Ctrl-j使用了组合。

有很多插件提供自动大括号插入。但他们

  • 要么使用Ctrl-j与跳出括号对不同的组合键,要么
  • 干扰UltiSnips键绑定。

以下按预期工作

:inoremap ( ()<Esc>:let leavechar=")"<CR>i
:imap <C-j> <Esc>:exec "normal f" . leavechar<CR>a
Run Code Online (Sandbox Code Playgroud)

但是使用这些设置,UltiSnips 片段不再起作用。所以我使用 UltiSnips 插入右括号:

inoremap ( (<C-R>=UltiSnips_Anon('($1)$0', '(')<CR>
Run Code Online (Sandbox Code Playgroud)

这几乎有效。插入了匹配的大括号,我可以跳过结束的大括号Ctrl-j。但是,这仅在开放式支架前面有空间时才有效。

main () // works, the closing parentheses is added
main(   // fails without a space
Run Code Online (Sandbox Code Playgroud)

我的解决方案要么需要不同的键绑定来跳过右括号,要么需要在打开的前面留一个空间。如何解决这个问题?

注意:我以括号为例。它应该与圆括号、大括号、方括号和小于号一起使用,并且不会干扰 UltiSnips 插件。

akt*_*ivb 5

如何在 vim 中自动创建匹配的大括号?

正如您将看到的,这个问题并不简单。简单的答案是:使用插件,例如autoclosesmartinput。只需天真地重新映射 ( [ .. 键就会在几行中向您呈现边缘情况,这就是制作这些插件的原因,以及为什么它们通常非常复杂(如果它们有什么好处的话)。

所以我使用 UltiSnips 插入右大括号

你可以尝试这个(这与我最初的建议不同):

inoremap ( ()<CR>=UltiSnips_Anon('$1)$0', ')')<CR>
Run Code Online (Sandbox Code Playgroud)

UltiSnips 将在其中分割线(而不是包含main在匹配中。为此使用片段插件的问题是它们(通常)不支持嵌套,因此当插入下一个(嵌套)片段时它们会忘记任何跳转位置。

要跳出大括号对,Ctrl-j请使用组合。

您可以重新映射Ctrl-jUltiSnips 或冲突的插件。如果文档中未列出映射,您可以使用:map/imap/nmap <key>显示映射。如果您想Ctrl-j挑选并完成这两个插件的工作,您需要:

  1. 比我怀疑你想象的要先进得多
  2. 我怀疑你并不真正想要的东西

考虑这个 bash 循环:

while (( ${arr1[i]} < ${arr2[i<CURSOR>]} )); do
  [next_snippet_position_marker]
done
Run Code Online (Sandbox Code Playgroud)

在这种情况下,您需要按Ctrl-j5 次才能到达循环体。使用右大括号跳出相应的大括号可以让您更好地控制光标实际移动的位置。您可以实现一个堆栈来跟踪插入的对并用于Ctrl-j弹出和移动,但是如果您开始手动删除大括号而不将它们从堆栈中删除,那么您会遇到问题。因此,您将开始解决大括号插件试图解决的问题。这是一个很难重新发明的轮子。

Ctrl-j在此基础上进行扩展,您可以使用跳出大括号片段来获得最初要求的内容。如果您使用一些虚拟值来表示片段位置,并将它们除了右大括号之外推入堆栈,并动态重新映射Ctrl-j来对应片段或大括号的处理。但是,然后您需要实现一些相当先进的启发式方法来弄清楚应该发生什么魔法,因为您本质上是同时解决两个问题,目前正在由代码片段插入插件和大括号匹配插件的创建者分别解决,并且在他们的解决方案之上再次重新解决这些问题,以实现便利和神奇。

这归结为控制与便利。我认为在这种情况下控制会更好地为您服务,这意味着您应该将这些问题及其相关的插件和键映射分开。如果你仍然想要方便,这是可行的,但很难。


Mar*_*hen 0

像这样的事情可能适合你。

inoremap {      {}<Left>
inoremap {<CR>  {<CR>}<Esc>O
inoremap {{     {
inoremap {}     {}
Run Code Online (Sandbox Code Playgroud)