この記事は Vim 8.0 Advent Calendar の 13 日目の記事です。
普段はあまり気にしないかもしれませんが、undo の単位は重要です。この undo について、新しい機能が追加されました。
挿入モードでの操作の分割
挿入モードでの操作中に、<Left> などでカーソル位置を動かすと、undo 情報や . でのリピートが壊れてしまいます。
例えば以下のキーマッピングがあった場合、
inoremap ( ()<Left>
挿入モードで foo(bar と入力することで foo(bar) が入力できます。
入力: afoo(bar<Esc>
↓
foo(bar)
しかし、ここで u コマンドで undo を行うとfoo() となってしまいます。また、. コマンドでリピートを実行すると、bar が挿入されます。
foo(bar)
↓
入力: u
↓
foo()
foo(bar)
↓
入力: j.
↓
foo(bar)
bar
これは <Left> により入力情報が途切れてしまうためです。つまり、<Left> を行った時点で、挿入モードを一旦抜けて入り直したのと同じことになります。
挿入モードでの <C-g>U コマンド
この問題を避けるために、<C-g>U コマンドが追加されました。これはカーソルを動かすコマンドの直前で使用します。
このコマンドを使うために、キーマッピングを以下のように書き換えます。
inoremap ( ()<C-g>U<Left>
最初の例と同様に foo(bar を入力し、その後それぞれ u コマンドや . コマンドを実行すると、入力された foo(bar) 全体が 1 つの入力として動作します。
foo(bar)
↓
入力: u
↓
foo(bar)
↓
入力: j.
↓
foo(bar)
foo(bar)
この <C-g>U コマンドは、カーソルが行を跨がない移動をする場合のみ有効です。
<C-g>U コマンドは便利ですが、手で入力するにはちょっと複雑です。今回の例のように、キーマッピングで使うとよいでしょう。