Paper Plane xUI(PPx)とVimの連携

この記事では、PPxからVimで選択ファイルを開いたり、Vimで開いているファイルパスへPPxでジャンプさせたりする方法を紹介します。
なお、記事中のデモ等ではGVimを使ってますが、Vimでも動作します。

# PPxからVimで選択ファイルを開く

Vimを起動する際、起動オプションにファイルパスを渡せばそのファイルを開いた状態で起動できます。

## Vimの起動オプションにファイルパスを渡す(シンプル版)

一番簡単な方法が、恐らく次のような設定になるかと思います。
*※「%'vim'」はVimへのフルパスが書かれたエイリアスです*

```:PPx.CFG(Vimで開く)
KC_main	= {	; PPcメイン窓
\E	,  %Ob %'vim' %FCD
}
```

これでも開く事はできますが、ここではgrep -nの検索結果にも対応してみようと思います。


## Vimの起動オプションにファイルパスを渡す(grep -n対応版)

次のようなファイルがあるとします、これらにはいくらかのソースコードが書かれています。

```
.
|-- foo.cpp
`-- foo.h
```

これらのファイルから「grep -n 'foo'」で検索すると、次のような結果になります。[^1]
[^1]: 検索結果をエントリーに表示する方法は6日目「[Paper Plane xUI(PPx)からエントリーへのgrep](http://qiita.com/wordijp/items/d90a64b807a7b39e4d1b)」

![vim.png](https://qiita-image-store.s3.amazonaws.com/0/51728/e11e33f3-fa4d-1aa8-4b7b-43a5244573a6.png)

ここで、3つ目の検索結果は「foo.h」ファイルの「2行目」を指しています、Vimの起動引数にこれらを渡せれば、目的のファイルを開く際にカーソルを指定行へ移動できます。

    # Vimでfoo.hを開いて2行目にカーソル移動
    $ vim.exe +2 foo.h

*※画像はgvimです*
![vim_open.png](https://qiita-image-store.s3.amazonaws.com/0/51728/15c5e75c-b6b5-7469-c751-a6522b526cd5.png)

ここでは「grep -n」結果の場合にVimの起動引数に変換するスクリプトを利用して対応しています[entry2vimargs.js](#entry2vimargsjs)。


# Vimで開いているファイルパスへPPxでジャンプ

PPx -> Vimはできたので、逆のVim -> PPxも欲しくなります、こちらもPPxの起動オプションを利用します。


PPxでファイルパスへジャンプするには、以下のようにします。

    > PPCW.EXE -r /k *jumppath E:\path\to\foo.h

このコマンドをVimから叩けば、PPxで指定のファイルパスへジャンプできます。

## デモ

*※GVim内でのファイル移動はVimFilerを使っています*
![vim_ppx.gif](https://qiita-image-store.s3.amazonaws.com/0/51728/7b02da70-2ba9-6fcd-a772-439b371bd8c9.gif)

Vimで開いているファイルパスでPPxへジャンプできています、ちなみに「:ppx」で関数Open_ppx()を呼び出し、その関数内でvimprocを使ってファイルパスへジャンプするコマンドを実行しています。

# ツール構成

## Vim

コマンドをバックグラウンド動作をさせる為に[Shougo/vimproc](https://github.com/Shougo/vimproc.vim)経由で実行しています。
PPxへのパスを各自の環境に合わせて下さい、実行方法もカスタマイズできます。

```vim:.vimrc
" PPxで開く
function! Open_ppx()
  " NOTE : PPxに渡すパス区切りは「\」じゃないといけない
  "        Windows版のVim以外だとexpand('%:p')のパス区切りの修正が必要
  call vimproc#system_bg("E:/tool/favorite/PPX/PPCW.EXE -r /k *jumppath '".expand('%:p')."'")
endfunction
" 「:PPx」「:ppx」の両対応
nnoremap :ppx :call Open_ppx()
command! -bar PPx call Open_ppx()
```

## entry2vimargs.js

```js:entry2vimargs.js
//!script

//
// エントリーをvim用の起動引数へと変換する
//
// 従来のパスのみの他に、行番号付きのgrep検索結果にも対応
// * 行番号付きのgrep検索結果の場合
//   パス:行番号:内容 -> パス +行番号
//

function getPath(str) {
	return str.split(/\:[^\\]/)[0];
}

function getLineNumber(str) {
	var m = str.match(/:\d+:/);
	if (!m) return null;

	return parseInt(str.substring(m.index + 1, m.lastIndex - 1));
}

///

var line_path = (function() {
	var arg = PPx.Arguments.item(0);
	if (arg == "") {
		PPx.Echo('arg is empty');
		PPx.Quit(-1);
	}

	return [getLineNumber(arg), getPath(arg)];
})();

var args = [];
if (line_path[0] != null) args.push('+' + line_path[0]);
args.push(line_path[1]);

PPx.Result = args.join(' ');
```

## PPx設定

エイリアス「%'gvim'」はGVimへのフルパスです、--remote-tab-silentは起動中のVimで別Tabとして開く起動オプションです、スクリプトのパスと共に各自の環境に合わせて下さい。

**※自身の設定が消えないように、適用前にバックアップを取るか、追加取り込みをしてください**
**※スクリプトのパスは自身の環境へと合わせて下さい**

```:PPx.CFG
KC_main	= {	; PPcメイン窓
\E	,*set VIM_ARGS=%*script(%0\script\entry2vimargs.js, "%FCD")
	%Ob %'gvim' --remote-tab-silent %'VIM_ARGS'
}
```

# おわりに

今回の連携ですが、他のエディタでも起動オプションに行番号が渡せたり、マクロ機能があれば乗り換える事ができます。
一例ですが、notepad++やサクラエディタなどでも可能な連携です。