1. Qiita
  2. 投稿
  3. Vim

Vim 8.0 Advent Calendar 13 日目 undo を分割せずにカーソルを移動

  • 7
    いいね
  • 0
    コメント
に投稿

この記事は 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 コマンドは便利ですが、手で入力するにはちょっと複雑です。今回の例のように、キーマッピングで使うとよいでしょう。

この投稿は Vim 8.0 Advent Calendar 201613日目の記事です。
Comments Loading...