Insertモードでも気軽に←・→したい

by
カテゴリ:

本記事は3/3のVim 駅伝の記事です1

概要

通常、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を知りました。

https://matrix.to/#/!nSpBuqIwPsRatnPFsb:gitter.im/$xLEenKjUSyKjVkmFygfYfE5K6AW9ogY7q7bvriS-bDQ?via=gitter.im&via=matrix.org&via=syui.cf

Enjoy