新年度から使いたい Vim プラグイン：operator プラグイン編

[ブログ記事](http://secret-garden.hatenablog.com/entry/2015/04/16/000000)からの転載です。

#### 前回

* [新年度から使いたい Vim プラグイン：自作プラグイン編 - Secret Garden(Instrumental)](http://secret-garden.hatenablog.com/entry/2015/04/06/235038)
* [新年度から使いたい Vim プラグイン：自作以外のプラグイン編 - Secret Garden(Instrumental)](http://secret-garden.hatenablog.com/entry/2015/04/08/234634)
* [新年度から使いたい Vim プラグイン：textobj プラグイン編 - Secret Garden(Instrumental)](http://secret-garden.hatenablog.com/entry/2015/04/11/235802)
<br>
<br>
さて、今回は Vim の特徴的な機能である operator を拡張するプラグインを紹介したいと思います。  
Vim は operator（と textobj ）を理解するかで Vim の使い勝手が全然変わるのでよくわからない人もこの機会に調べてみるとよいと思います。

* [Vim Advent Calendar 2013 97日目:モモンガでもわかるテキストオブジェクトとオペレータ - C++でゲームプログラミング](http://d.hatena.ne.jp/osyo-manga/20140307/1394204974)

## はじめに : Vim プラグインを管理するプラグイン

プラグインを導入する前にプラグインを管理するプラグインを入れましょう。

* __[Shougo/neobundle.vim](https://github.com/Shougo/neobundle.vim)__

使い方などはドキュメントや__[ここら辺](http://kaworu.jpn.org/vim/NeoBundle)__を参考にするとよいでしょう。
また、他のプラグイン管理プラグインには以下のようなものもあります。

* __[junegunn/vim-plug](https://github.com/junegunn/vim-plug)__
* __[tpope/vim-pathogen](https://github.com/tpope/vim-pathogen)__

neobundle.vim があわないと感じたらこの2つも試してみるとよいと思います。  
特に vim-pathogen は単純な管理システムで git に依存しないので git を使いたくない方は vim-pathogen を使うとよいでしょう。
<br>
<br>
あと今回は紹介するプラグインはプラグインに依存しているので、予め導入しておくとよいでしょう。

```vim
NeoBundle "kana/vim-operator-user"
```

## __[kana/vim-operator-replace](https://github.com/kana/vim-operator-replace)__

```vim
NeoBundle "kana/vim-operator-replace"
```

operator-replace は textobj のテキストにヤンクレジスタのテキストをはりつける operator です。  
かなり有名な operator 。  
ビジュアルモードからテキストをペーストするのとは違い、ヤンクレジスタを汚染しないのが特徴です。  
ヤンクレジスタを汚染しないので dot repeat 等で連続して同じテキストをペーストしたい場合に有効です。  


#### 設定例

```vim
nmap s <Plug>(operator-replace)
```


## __[rhysd/vim-operator-surround](https://github.com/rhysd/vim-operator-surround)__

```vim
NeoBundle "rhysd/vim-operator-surround"
```

operator-surround は対象の textobj を括弧で囲むための operator です。  
surround.vim の operator 版のようなプラグインです。  

```vim
" 括弧を追加する
map <silent> sa <Plug>(operator-surround-append)
" 括弧を削除する
map <silent> sd <Plug>(operator-surround-delete)
" 括弧を入れ替える
map <silent> sr <Plug>(operator-surround-replace)
```

例えば、`saiw(`（`sa` + `iw` + `(`）と入力することでカーソル下の単語を `()` で囲う事ができます。  
また、この operator は前回紹介した __[textobj-multiblock](https://github.com/osyo-manga/vim-textobj-multiblock)__ と組み合わせることでより強力になります。

```vim
" カーソル位置から一番近い括弧を削除する
nmap <silent> sdd <Plug>(operator-surround-delete)<Plug>(textobj-multiblock-a)

" カーソル位置から一番近い括弧を変更する
nmap <silent> srr <Plug>(operator-surround-replace)<Plug>(textobj-multiblock-a)
```

#### もうちょっと便利な設定

上記の使い方でも十分便利なのですが、branch/input_in_advance を使うことでもっと便利になります。

```vim
NeoBundle "rhysd/vim-operator-surround", {
\	"rev" : "input_in_advance"
\}
```

これで `<Plug>(operator-surround-append-input-in-advance)` が使えるようになります。  
operator-surround は通常  

* operator の入力→ textobj の入力→括弧の入力

という順番で処理されます。  
`<Plug>(operator-surround-append-input-in-advance)` を使用する場合、この順番がちょっと異なり。

* operator の入力→括弧の入力→ textobj の入力

と、いう風に括弧を入力するタイミングを先にすることができます。  
これにより何が便利なのかというと例えば、以下のように設定すると

```vim
nmap sa <Plug>(operator-surround-append-input-in-advance)
nmap s( <Plug>(operator-surround-append-input-in-advance)(
nmap sb <Plug>(operator-surround-append-input-in-advance)(
nmap s{ <Plug>(operator-surround-append-input-in-advance){
nmap s[ <Plug>(operator-surround-append-input-in-advance)[
nmap s" <Plug>(operator-surround-append-input-in-advance)"
nmap s' <Plug>(operator-surround-append-input-in-advance)'
```

`s` + 任意の括弧 + `testobj` みたいな入力を行う事ができるようになります。  


## __[osyo-manga/vim-operator-stay-cursor](https://github.com/osyo-manga/vim-operator-stay-cursor)__

```vim
NeoBundle "osyo-manga/vim-operator-stay-cursor"
```

operator を実行するとカーソル位置が対象の textobj の先頭へと移動します。  
operator-stay-cursor は任意の operator を実行した場合にカーソルを移動させないようにするための operator になります。  
例えば、ヤンク operator 時にカーソルを移動しないようにする場合は 

```vim
map y <Plug>(operator-stay-cursor-yank)
```

と、することで `y` 時にカーソルが移動しなくなります。  
地味なんですが結構便利です。

#### 関連

* [Vim で operator 実行時にカーソルを移動させないような operator をつくった - Secret Garden(Instrumental)](http://secret-garden.hatenablog.com/entry/2015/03/18/232847)


## __[oyos-manga/vim-operator-exec_command](https://github.com/oyos-manga/vim-operator-exec_command)__

```vim
NeoBundle "oyos-manga/vim-operator-exec_command"
```

operator-exec_command は任意のコマンドを実行する operator です。  
例えば、以下のように設定すると textobj のテキストを help する事ができるようになります。

```vim
" %t が textobj の範囲のテキストに置き換わる
nmap <expr> K operator#exec_command#mapexpr(":help %t")
```

他には

```vim
nmap <expr> <Space>* operator#exec_command#mapexpr("Unite line -input=%t")
```

と、することで絞りこみをした状態で unite-line を起動したりすることもできます。  
単純な機能で結構応用が効くので便利です。

#### 関連

* [Vim Advent Calendar 2013 179日目: 任意のコマンドを実行する operator をつくった - C++でゲームプログラミング](http://d.hatena.ne.jp/osyo-manga/20140528/1401287116)

## まとめ

と、いう感じで日頃便利に使っている operator 系プラグインをいくつか紹介してみました。  
textobj と同様に operator も Vim 独自の機能のひとつなのでぜひ使いこなせるようになるとよいと思います。

## 参照

* [Vim の operator プラグインをまとめた - Qiita](http://qiita.com/rbtnn/items/a47ed6684f1f0bc52906)