一致するブレースをvimで自動的に作成する


17

一致するブレースをvimで自動的に作成するにはどうすればよいですか?

次のように機能するはずです:開き中かっこを入力すると、閉じ中かっこが自動的に表示され、カーソルがその間に置かれます。ブレースのペアから飛び出すには、組み合わせCtrl-jが使用されます。

自動ブレース挿入を提供するプラグインはたくさんあります。だけどあの人達

  • Ctrl-jブレースペアから飛び出すためとは異なるキーの組み合わせを使用するか、
  • UltiSnipsキーバインディングを妨害します。

以下は期待どおりに動作します

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

ただし、これらの設定ではUltiSnipsスニペットは機能しなくなります。そこで、UltiSnipsを使用して閉じブレースを挿入しました。

inoremap ( (<C-R>=UltiSnips_Anon('($1)$0', '(')<CR>

これはほとんど機能します。一致するブレースが挿入され、を使用して閉じているブレースをスキップできCtrl-jます。ただし、これは、開きブレースの前にスペースがある場合にのみ機能します。

main () // works, the closing parentheses is added
main(   // fails without a space

私の解決策は、閉じ括弧を飛び越えるために異なるキーバインディングを必要とするか、開いている括弧の前にスペースを必要とします。これを修正する方法は?

注:例として括弧を使用しました。かっこ、中かっこ、角かっこ、小なり記号で動作し、UltiSnipsプラグインを妨害しません。


1
オートクローズを試しましたか?を使用してペアから飛び出すことができ)、それへの再マッピングc-jが機能する可能性があります。
ケビン

回答:


4

一致するブレースをvimで自動的に作成するにはどうすればよいですか?

あなたが見るように、この問題は自明ではありません。簡単な答えは、autoclosesmartinputなどのプラグインを使用することです。([..キーは、数行でエッジケースを表示します。これが、これらのプラグインが作成される理由であり、通常は非常に複雑です(もし良ければ))。

そこで、UltiSnipsを使用して閉じブレースを挿入しました

代わりにこれを試すことができます(これは私の最初の提案とは異なります)。

inoremap ( ()<CR>=UltiSnips_Anon('$1)$0', ')')<CR>

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

この場合、Ctrl-jループ本体に到達するには5回押す必要があります。対応するペアからジャンプするために閉じ括弧を使用すると、実際にカーソルを移動させたい場所をより細かく制御できます。スタックを実装して、挿入されたペアを追跡し、Ctrl-jポップおよび移動に使用できますが、スタックから削除せずにブレースを手動で削除し始めると問題が発生します。したがって、ブレースプラグインが解決しようとしている問題の解決を開始します。これは再発明するのが難しいホイールです。

これを展開すると、最初に求めたものを取得Ctrl-jして、ブレーススニペットから飛び出すことができます。スニペットの位置を表すためにダミー値を使用しCtrl-j、スニペットまたはブレースの処理に対応するための動的な再マッピングを使用して、それらを閉じブレースに加えてスタックにプッシュする場合。しかし、その後、基本的には2つの問題を同時に抱えているため、かなり高度なヒューリスティックを実装して、魔法がどうあるべきかを把握する必要があります。利便性と魔法を実現するために、それらのソリューションに加えてこれらの問題を再度解決します。

制御と利便性の問題です。この場合、コントロールがより役立つと思います。つまり、これらの問題とそれに関連するプラグインとキーマッピングを別々にしておく必要があります。それでも利便性が必要な場合、それは実行可能ですが、難しいです。


1

delimitMateは必要なことを行うと思います。

括弧または引用符を自動的に閉じ、カーソルを間に置きます。(挿入モードのときに)括弧のペアから飛び出すにはCtrl-g+をg実行しますが、これをにCtrl-j追加することで再マッピングできますvimrc

% Jump out of a block of parentheses (uses delimitMate)
imap <C-j> <C-g>g

ここで詳細を提供し、さらに読むための参照としてリンクを使用することをお勧めします。そうすることで、リンクが無効になったときにあなたの答えがすべての価値を失うことはありません。
アントン14年

1

自動クローズが少し遅れを追加し、セットアップ(UltisnipsとSupertab)に干渉することもわかりましたが、Eclipse CDTをエミュレートするアプローチが気に入っています。

次のマップでdelimitMateを使用してナビゲーションとインデントを支援し、同じ結果を得ようとしています:

imap <C-F> <C-G>g           " To jump out brackets in same line.
inoremap <C-K> <ESC>ki<TAB> " To move and insert an indent on the line before the current cursor (assuming empty line)

私はこれをこのように使用します。オープニング{ <CR><CR><C-K>を挿入し、インデントされた内側の行で書き込みを開始します。


delimitMateがわずかな遅れを追加していることがわかりました
icc97

1

個人的には、かっこと引用符の自動挿入にsmartinputを使用しています。たとえば、{どこに入力しても{}、カーソルが中央になります。終了するには{ブラケットグループをあなただけの入力}時に挿入された隣}

ただし、これはタブストップの要件とブラケットの外側へのジャンプをサポートします。また、括弧の間に新しいものは作成されませんが、とにかく1つの追加キーが必要です<CR>

<C-J>次の行にジャンプするようにマッピングできます。

:inoremap <C-J> <C-O>j

または、次の行の先頭に移動する場合:

:inoremap <C-J> <C-O>+

0

このような何かがあなたのためにうまくいくかもしれません。

inoremap {      {}<Left>
inoremap {<CR>  {<CR>}<Esc>O
inoremap {{     {
inoremap {}     {}

提案するのは、閉じ括弧を飛び越えられない単純なマッピングです。
マルコ

0

実際、Ultisnipsはほぼ完全にそれを行うことができます(これは新しい可能性があります)。上記の回答を少し修正して、私は

inoremap () ()<C-R>=UltiSnips#Anon('($1)$0', '()', 'double parentheses', 'i')<CR>

()より良いとタイプする必要がありますが、(同様に変更できます。次に、追加のオプション引数UltiSnips#Anonは、説明とiインワード拡張を許可する修飾子です。

<c-j>作品とともに括弧から飛び出し、他のスニペット内にもネストします。ただし、入れ子になった()かっこを呼び出すと、この機能が壊れるように見えますが、大したことではありません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.