マージされました ->previm をWSLから使えるようにwsl_modeを追加/pull reqしてみた

# はじめに
vim でマークダウンを書くときに、previm を利用している。
WSL 上に環境を作ったが、previm がうまく動かなかったので、修正して動くようにしてみた。

**2019/11/08追記**
[add previm_wsl_mode by hirano00o · Pull Request #135 · previm/previm](https://github.com/previm/previm/pull/135)
昨日マージされました！
WSLモードの有効化は、[使い方](#使い方)を参照ください。

# 環境
|key|value|
|---|-----|
|OS | Win 10 Pro|
|WSL ver.| 2|
|WSL OS | Ubuntu 18.04.3 LTS|
|vim ver.| 8.0 (デフォルト)|
|open-browser.vim| 未利用|
|Windowsで使うブラウザ| Google Chrome |

# previm on .vimrc
[previm/previm: Realtime preview by Vim. (Markdown, reStructuredText, textile)](https://github.com/previm/previm)
によると、`.vimrc` では下記を指定する必要がある。
ちなみに指定していない場合は、`open-browser` が呼ばれる。
`open-browser` もない場合は、エラーとなるみたい。

```vim:.vimrc
let g:previm_open_cmd = 'ブラウザを開くコマンド'
```

# ブラウザを開くコマンド on WSL
さて、WSL で`ブラウザを開くコマンド`は何だろうかと。

WSL では、Windowsのディレクトリがマウントされている。
デフォルトだと、`/mnt` にマウントされている。
ということは、Chrome の exe ファイルも見つけることが可能。

```bash
% ll /mnt/c/Program\ Files\ \(x86\)/Google/Chrome/Application/chrome.exe
-r-xr-xr-x 1 hirano00o hirano00o 1694704 10月  9 12:52 '/mnt/c/Program Files (x86)/Google/Chrome/Application/chrome.exe'
```

これを bash 上で実行すると、新規ウィンドウで Chrome が開く。
引数に、相対パスでファイルを渡すと、新規タブでそのファイルが開かれる。

```bash
% /mnt/c/Program\ Files\ \(x86\)/Google/Chrome/Application/chrome.exe .vim/plugged/previm/README.mkd
```
![previm.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14266/c22beb52-86d8-afba-c366-052e5d34da88.png)

**Chrome の URL に見慣れない文字列が**
**wsl%24/Ubuntu/home/... とは？**

# WSL のパスと Windows のパス

> WSL/Linux環境のファイルシステムは、“¥¥wsl\$¥（ディストリビューションの名前）¥”というUNCパスで表現される。たとえば、「Debian」を利用している場合は“¥¥wsl$¥Debian¥”となる。
[WindowsからLinuxファイルへのアクセスが可能に ～「Windows 10 19H1」におけるWSLの改善 - 窓の杜](https://forest.watch.impress.co.jp/docs/news/1170221.html)

とのことで、つまり Windows の Chrome から WSL 上のファイルを開くためには、上記の形にパスを変える必要がある。

Ubuntu on WSL 上の previm では、ファイルパスは `/home`から始まるため、これに何とかして `\\wsl$\Ubuntu` を付与する必要がある。

ところで WSL にはデフォルトで `wslpath` という WSL <-> Windows パス変換するコマンドがインストールされているらしい。
[【WSL】パスのフォーマットを変換する wslpath コマンドの使い方 | ラボラジアン](https://laboradian.com/wslpath-command-for-wsl/)

これを使うと、

```bash
% wslpath -w .vimrc
\\wsl$\Ubuntu\home\hirano00o\.vimrc
```
見事変換される。

# previm の修正

まず、どのように追加するかだが、せっかくなので汎用的にしたい。
vim では、Linux かどうかの判別はできても、WSL かどうかの判別はできない。
通常の Linux では、wslpath はない。
ということで、オプションを追加することにする。

```bash
% grep open_cmd */*.vim
autoload/previm.vim:  if exists('g:previm_open_cmd') && !empty(g:previm_open_cmd)
autoload/previm.vim:    if has('win32') && g:previm_open_cmd =~? 'firefox'
autoload/previm.vim:      call s:system(g:previm_open_cmd . ' "file:///'  . fnamemodify(a:preview_html_file, ':p:gs?\\?/?g') . '"')
autoload/previm.vim:      call s:system(g:previm_open_cmd . ' '''  . system('cygpath -w ' . a:preview_html_file) . '''')
autoload/previm.vim:      call s:system(g:previm_open_cmd . ' '''  . a:preview_html_file . '''')
```
autoload/previm.vim を修正すれば良さそう。
で、追記してみた。

```bash
% git diff HEAD
diff --git a/autoload/previm.vim b/autoload/previm.vim
index cc1b473..53786e9 100644
--- a/autoload/previm.vim
+++ b/autoload/previm.vim
@@ -17,6 +17,8 @@ function! previm#open(preview_html_file) abort
       call s:system(g:previm_open_cmd . ' "file:///'  . fnamemodify(a:preview_html_file, ':p:gs?\\?/?g') . '"')
     elseif has('win32unix')
       call s:system(g:previm_open_cmd . ' '''  . system('cygpath -w ' . a:preview_html_file) . '''')
+    elseif get(g:, 'previm_wsl_mode', 0) ==# 1
+      call s:system(g:previm_open_cmd . ' '''  . system('wslpath -w ' . a:preview_html_file) . '''')
     else
       call s:system(g:previm_open_cmd . ' '''  . a:preview_html_file . '''')
     endif
```

# 使い方
.vimrc には下記のように、記述することで無事に動いた。

```vim:.vimrc
let g:previm_open_cmd = '/mnt/c/Program\ Files\ \(x86\)/Google/Chrome/Application/chrome.exe'
let g:previm_wsl_mode = 1
```

せっかく WSL に対応させたので、プルリク出してみた。
~~果たしてマージされるかな..~~マージ済
[add previm_wsl_mode by hirano00o · Pull Request #135 · previm/previm](https://github.com/previm/previm/pull/135)