概要
通常、Vim/NeovimのInsertモードで←や→を使うと、Undo blockが途切れます。
これではUndoやドットリピートが直感に反するケースがあるので、以下のようにマッピングしておくと便利です。 Insertモード中で水平移動してタイポ修正する人や、自動入力された閉括弧の外側へ→で移動した後、NormalモードでUndoやドットリピートする時に活躍します。
inoremap <Left> <C-G>U<Left>
inoremap <Right> <C-G>U<Right>
解説
Undo blockはu
などで戻せる変更の単位です。
←などの影響でInsertモード中のUndo blockが分割されるとこれの何が厄介か、タイポ修正を例に見てみましょう。
以下の例では、「あいうえお」という行を作りたかったが、「あいお」と入力してしまい、やむなく「い」と「お」の間に←で移動して「あいうえお」を完成させノーマルモードに戻っています。
oあいお<Left>うえ<Esc>
この時やっぱり今のなし!と思ってu
すると「あいうえお」の行が消えず「あいお」という行に変わります。
最後に←、すなわちi_<Left>
した時の状態に戻ったわけです。
あるいは、「あいうえお」の行を増やしたくて.
でリピートすると、「あいうえお」の行が「あいううええお」になってしまいます。
やはり最後に←して以降の変更、すなわちうえ
という入力を繰り返したわけです。
知っていれば納得の挙動ですが、あまり使い勝手が良いとも言えません。
そこでi_CTRL-G_U
してから水平移動するとUndo blockを継続できます。
これをデフォルト挙動にしたい人はinoremap
を使って<Left>
や<Right>
の前に<C-G>U
をつけてあげればいいのです。
inoremap <Left> <C-G>U<Left>
inoremap <Right> <C-G>U<Right>
別の例で、autopairsなどと呼ばれる、閉括弧などを補完するプラグインの利用を考えてみましょう。筆者はechasnovski/mini.pairsを使っているので、これの動作を基準に(1 + 1) * 2
という行を作成してみます。
プラグインが)
を自動入力してくれますが、)
の右側に移動したい場合、)
と入力するか<Right>
するか選べます。
o(1 + 1) * 2<Esc>
o(1 + 1<Right> * 2<Esc>
前者の場合はUndo blockが途切れないのでu
も.
もInsertモードでの変更全体に及びます。
一方後者では<Right>
でUndo blockが途切れてしまうので、u
すると(1 + 1)
になりますし、.
すると(1 + 1) * * 22
になります。厄介ですね。
一方、先のマッピングをしておけば、直感的にu
や.
ができます。便利。
おまけ
本記事のきっかけは毎週土曜日23時から開催されている「vimrc読書会」です。
インサートモード中のUndo blockをわざと区切るi_CTRL-G_u
の存在を知り、周辺のヘルプを読んでいて、ここで紹介したi_CTRL-G-U
を知りました。
Enjoy
Vim 駅伝の概要は右記から https://thinca.hatenablog.com/entry/vim-ekiden-is-launched↩︎