haya14busa

haya14busa’s memo

かゆいところに手が届く、vim-submodeでxの挙動をカイゼンする

Vim Advent Calendarです

この記事はVim Advent Calendar 2013 : ATNDの 108 日目の記事になります。日付がおかしいとか細かいことは気にしてはいけません。Vim Advent CalendarはVim記事を書きたいという人がいるかぎり続きます。しかしいったい、いつまで続くんでしょう…気になります!

Vimに関することであれば基本的に何を書いてもよいはずなので、興味がある方は気軽に書いてみるとよいのではないでしょうか。

vim-submodeで x の挙動をカイゼンする

kana/vim-submode

Lingrで発言したときに若干反応があったのでVAC Tipsとして簡単なものですが紹介します。

Vimデフォルトのxはカーソル下の文字を消すという機能です。

xの挙動のちょっとした不満点として1文字消すためだけにレジスタを汚してしまうというものがあり、それをカイゼンするためにnnoremap x "_xを設定しているvimrcをたまに見かけます。

しかし、よくみるレジスタの問題の他にも不満点がありました。それはx後のundoの挙動です。

xで1文字消すごとにundo履歴が区切られてしまい、いざxを連打した後に間違っていると判明して、undoしたい!と思っても、xを押した分だけ何回も何回もuを押さなくてはいけません。

連続したxで一気に消した分は、1回のundoで戻せたら素敵じゃないでしょうか?

そんな機能を実現できる、かゆいところに手が届くプラグインがvim-submodeです。

コード

1
2
3
4
5
6
7
8
NeoBundle 'kana/vim-submode'
function! s:my_x()
    undojoin
    normal! "_x
endfunction
nnoremap <silent> <Plug>(my-x) :<C-u>call <SID>my_x()<CR>
call submode#enter_with('my_x', 'n', '', 'x', '"_x')
call submode#map('my_x', 'n', 'r', 'x', '<Plug>(my-x)')

簡単に解説すると、最初にxを押した時に"_xでブラックホールレジスタに放り込んで1文字消すと同時にmy_xというsubmodeに入るようにし、このmy_xというsubmode下でのxは事前に定義した<Plug>(my-x)を呼んで、undojoinを使用することによりundo履歴を1つにまとめています。

:undoj[oin] 以降の変更を直前の undo ブロックにつなげる。

Vim documentation: undo

欠点

x連打してここまで消したい!というときに1〜2カラム分行きすぎてしまったなどといった場合、undoすると初めから全部戻ってしまいます。一長一短ですね…

しかし、undo履歴が汚れ無いようになるし、結構気に入っています。ピンと来た方は使ってみてはいかがでしょうか?

Comments