Ack.vim と qfreplace で気軽に複数ファイルの一括置換

Vim での複数ファイルの一括置換については、何となく ```:argdo``` などを使うっぽいということだけ知っていた状態で、あまり使ったことはありませんでした。

しかし、複数ファイル一括置換をするような場面に出くわし、簡単にできる方法は無いかと探していたところ、<a href="https://github.com/mileszs/ack.vim" target="_blank" rel="nofollow noopener">Ack.vim</a> と <a href="https://github.com/thinca/vim-qfreplace" target="_blank" rel="nofollow noopener">qfreplace</a> の組み合わせが簡単そうだったので紹介します。

## 利用する Vim プラグインについて

### <a href="https://github.com/mileszs/ack.vim" target="_blank" rel="nofollow noopener">Ack.vim</a>

自分のお気に入りの検索ツール(<a href="https://github.com/ggreer/the_silver_searcher" target="_blank" rel="nofollow noopener">ag</a> や <a href="https://github.com/BurntSushi/ripgrep" target="_blank" rel="nofollow noopener">ripgrep</a>など)による検索結果を、Quickfix ウインドウに表示してくれるプラグインです。
Quickfix ウインドウの検索結果から、対象ファイルを直接開くことも可能です。

### <a href="https://github.com/thinca/vim-qfreplace" target="_blank" rel="nofollow noopener">qfreplace</a>

Quickfix ウインドウに一覧表示されたリストを一括置換できるプラグインです。
Quickfix ウインドウのリストから置換バッファを作成し、こちらを編集・保存することで、該当のファイルを一括置換することができます。

## 複数ファイル一括置換の流れ

以下の流れで一括置換していきます。

1. Ack.vim で検索したい文字列で検索、Quickfix ウインドウ表示
2. qfreplace で Quickfix ウインドウから置換バッファウインドウ作成
3. 置換バッファ内で置換
4. 置換バッファを保存
5. 置換を確認

## 手順

例として、以下では <a href="https://github.com/puma/puma-dev" target="_blank" rel="nofollow noopener">puma-dev</a> リポジトリ以下全ファイルの ```darwin``` という文字列を、 ```charles``` という文字列に変更する手順で書こうと思います。

### 環境

* Mac OS X 10.13.6
* Vim 8.1.202

### 0. 下準備

手順実施前に、お好みの Vim プラグインマネージャーなどを使って Ack.vim と qfreplace をインストールしておきます。
以下では dein.vim の例で記載します。

```vim

call dein#add('mileszs/ack.vim')
call dein#add('thinca/vim-qfreplace')
```

Ack.vim で ag を使いたいという方は、ag をインストールした状態で```.vimrc``` に下記を追記します。
(特に変更はいらないという方は飛ばしていただいて構いません)

```vim
if executable('ag')
  let g:ackprg = 'ag --vimgrep'
endif
```

### 1. Ack.vim で検索したい文字列で検索、Quickfix ウインドウ表示

それでは実施していきます。まず puma-dev リポジトリをクローンし、Vim を起動します。

```bash
$ git clone https://github.com/puma/puma-dev
$ cd puma-dev
$ vim
```

Vim が起動したら、```:Ack darwin``` と入力し実行します。
すると検索ヒットした結果が Quickfix ウインドウに表示されます。

<img width="724" alt="1_ack.png" src="https://qiita-image-store.s3.amazonaws.com/0/222030/e52c58a1-8059-3076-be1e-aec47c00cec1.png">

### 2. qfreplace で Quickfix ウインドウから置換バッファウインドウ作成

次に、Quickfix ウインドウが開いた状態で、```:Qfreplace``` と入力し実行します。
すると、Quickfix ウインドウの上部にさらに qfreplace の置換バッファウインドウが開きます。

<img width="752" alt="2_qf.png" src="https://qiita-image-store.s3.amazonaws.com/0/222030/013aae5f-441a-79c0-a48e-f3846f26dea8.png">

内容は Ack.vim の Quickfix ウインドウに表示された検索行がそのまま表示された形になります。
置換バッファの表示ができたら、Ack.vim の Quickfix ウインドウは閉じてもOKです。

### 3. 置換バッファ内で置換

qfreplace の置換バッファ内で置換を実行します。この置換バッファ内ではインサートモードで手動編集もできるのですが、今回はコマンドで置換します。

```:% s/darwin/charles/g``` と入力し実行します。
すると、置換バッファ内の ```darwin``` という文字列がすべて ```charles``` という文字列に置換されます。

<img width="752" alt="3_replace.png" src="https://qiita-image-store.s3.amazonaws.com/0/222030/c2a659ca-b1a0-68e6-8997-783e1dc2dbd2.png">


### 4. 置換バッファを保存

最後に、置換バッファ内で、```:w``` を入力し保存を実行します。
すると、検索ヒットした行に該当するファイルに一括で保存処理が走り、変更が保存されます。

<img width="724" alt="4_save.png" src="https://qiita-image-store.s3.amazonaws.com/0/222030/ea3b0a57-9198-fa32-c8a1-08b5323e09f7.png">

### 5. 置換を確認

最後に置換ができているかを確認してみます。

Vim を終了し、```git diff``` してみると、確かに置換ができていることが確認できます。

<img width="752" alt="5_diff.png" src="https://qiita-image-store.s3.amazonaws.com/0/222030/a4ddd343-4c6b-4759-438c-37b93f43b230.png">


## 終わりに

僕はこれで気軽に複数ファイル一括置換ができるようになりました。また検索結果を確認しながら作業ができるのもいい感じです！

## 参考URL

* <a href="http://archiva.jp/web/tool/vim_grep2.html" target="_blank" rel="nofollow noopener">Vim: 複数ファイル検索/置換をもうちょい詳しく</a>
* <a href="http://atasatamatara.hatenablog.jp/entry/2013/03/06/213604" target="_blank" rel="nofollow noopener">Ag.vim と Qfreprece.vim の組み合わせで簡単置換処理する</a>