quickrun.vimの出力先をtabpageにする

#はじめに
[quickrun.vim](https://github.com/thinca/vim-quickrun)とっても便利ですが、デフォルトの設定では画面が分割され結果が左半分に表示されます。
意外と消すのが大変だったり(:onlyとか)プログラムの表示部が減ったりするので意外と不便です。(わがまま)
最初は、outputterにmessageを指定して解決していたのですが、これだとうっかりキーを入力したりするとおじゃんになるし検索とかが使えないのでやっぱり不便です。
そこで、vimにある[tabpage機能](https://vim-jp.org/vimdoc-ja/tabpage.html)を使って、quickrun.vimの結果を~~強引に~~tabpageに出力したいと思います。
##注意
本記事はプラグインのソースを変えず設定側の変更だけで出力先を強引にtabpageにしている~~のと筆者のvimに対する知識が未熟な~~ため、かなり無駄と無茶があります。お許し下さい。
#環境
```
#nvim -v                                                                                                                                       [18:32:44]
NVIM v0.3.4
Build type: Release
LuaJIT 2.1.0-beta3
# head -n 4 quickrun.vim
" Run commands quickly.
" Version: 0.7.0
" Author : thinca <thinca+vim@gmail.com>
" License: zlib License
------------------------------------------------------------
vimproc.vim
ver 9.3 (https://github.com/Shougo/vimproc.vim/releases)
```

#とりあえず出力にtabコマンドを指定してみる
quickrunのヘルプを見ると"outputter/buffer/split"に設定すれば良さそうです。

```vim
:tab help quickrun-module-outputter/buffer
- "outputter/buffer"                    quickrun-module-outputter/buffer
  出力専用バッファを開いてそこへ出力します。このバッファは同じものが再利用されます。
  オプション
  outputter/buffer/name                 デフォルト: "[quickrun output]"
        バッファ名です。
  outputter/buffer/filetype             デフォルト: "quickrun"
        バッファに設定される 'filetype' の値です。
  outputter/buffer/append               デフォルト: 0
        1 の場合は追記を行います。
  outputter/buffer/split
        デフォルト: '%{winwidth(0) * 2 < winheight(0) * 5 ? "" : "vertical"}'
        出力専用バッファを開く際の補助コマンドを指定します。バッファを開く際に
        :split コマンドの前に挿入されます。

```
デフォルトではverticalコマンドで出力になっています。
早速、vimrc/init.vimに設定しましょう。
##vimrc/init.vimに設定を追記
vimの場合はvimrcに、neovimの場合はinit.vimに以下を追加します。
既に項目がある場合は、そこに追加してください。

```vim
let g:quickrun_config = {
			\   "_" : {
			\	"outputter":"buffered",
			\	"outputter/buffered/target":"buffer",
			\	"outputter/buffer/split":"tab",
			\	}
			\}
```
追加したら準備完了です。早速実行してみましょう。

##うーん
確かに、実行結果がtabpageに出てはいますが何故か二つ出ています。
気持ち悪い。
[作者の過去のhelp](https://github.com/ujihisa/quickrun/blob/master/doc/quickrun.jax)でも確かにおすすめはしてないようです。(今はこの項目はない)

>
split (*) 
出力専用バッファを開く際の補助コマンドを指定します。バッファを開く際に |:split| コマンドの前に挿入されます。
|:tab| も指定できますが、タブページ内に出力専用バッファが存在しない場合常に新しく開くのでおすすめしません。

#改善
重複が起こってしまうなら、重複が起こらないようにtabを開くコマンドを作ってそれを指定すれば良いのです。(暴論)
##コマンドを作成
vimscriptから作成するので一応手順を書いておきます。
わかる人は飛ばして下さい。
###vimscriptを置くディレクトリを作成する
既にある人は飛ばしてください。
作成するところは適当なところで構いません。僕は~/.vimにmy_scriptというディレクトリで作成しました。

```zsh
# mkdir ~/.vim/my_script 
```
###ファイルを作成し、設定する
そうしたら、vimscriptを記述するファイルを適当に作成し、

```zsh
# touch ~/.vim/my_script/uniqtab.vim
```
vimを使っている人はvimrcにneovimを使っている人はinit.vimに以下の一文を追加します。

```vim
"source さっき作成したファイルのパス
source ~/.vim/my_script/uniqtab.vim
```
##コマンドを記述
さっき作成したファイルに記述していきます。
無い脳でいろいろ考えましたが、出力バッファには名前が設定されているので、それとtabpage名を参照して同じなら、既に存在していると見なしてそのtabを閉じてから新しくtabを開くようにしました。~~(上書きの方法が見つからなかった)~~

```vimscript:uniqtab.vim
command! -nargs=1 Uniqtab call Unique_open_tab(<f-args>)

function! Unique_open_tab(option)
	for i in range(1,tabpagenr('$'))
		let bufnrs=tabpagebuflist(i)
		let currentbuf=bufnrs[tabpagewinnr(i)-1]
		"設定されたtab名(デフォルトは[quickrun output])と比べて同じなら消す
		if "[quickrun output]" == bufname(currentbuf)
			execute "tabclose ".i
		endif
	endfor
	tabnew a:option
endfunction
```
tabpage名をいじってる人は変えるなり、変数を参照するなりしてください。
##設定しなおす
さっき設定したバッファを開くコマンドを今作ったコマンドに置き換えます。
"outputter/buffer/split"を"Uniqtab"に変更します。

```vim
let g:quickrun_config = {
			\   "_" : {
			\	"outputter":"buffered",
			\	"outputter/buffered/target":"buffer",
			\	"outputter/buffer/split":"Uniqtab",
			\	}
			\}
```
これで結果がtabpageに出力されたはず。
#反省
方法がかなり強引ですが、一応納得できる動作になったのでここに残すことにしました。
元のプラグインがvimscriptなのでかなり頑張って読んだのですが、プラグインのファイルをいじらずに設定の範囲でやるのはこれが限界でした。
動作は読めたので何故一度に複数開くのかとかは分かったのですが、重複しないようにtabpageを開くのがかなり鬼門でした。
自分は出力用のtabは一つで十分だと思っているのでむしろ都合が良いですが、複数に分ける場合処理に困るのでそこは考える必要がありそうですね。
tabpageにこだわらず、便利な出力先やプラグインがないか考えるのも問題解決につながりそうです。
#最後に
もっとこうした方が良いとか、こんな方法があるという方はぜひコメントお願いします。
##quickrun関係の過去記事
[quickrun.vimで非同期実行している時に実行中かどうか分かるようにする](https://qiita.com/Seigenkousya/items/db19696d6eacd28252f1)