お断り
以下の方法は本質的に下記サイトの内容をWindows10 1803アップデートに合わせて更新しつつ,パスに空白が含まれる場合に対応し,SendTo版を加えたものです.
また以下ではvimを例に説明していますが,vim固有の機能を使うわけではないので,ファイル名を引数として受け取る別のコマンド(emacsなど)にも応用できます.
目的
ちょっとしたテキストファイルの編集に,Windows Subsystem for Linux(以下WSL)のvim(≠gvim)を使いたい.しかもエクスプローラーから直接vimを起動したい.
理由
- Windows版のvimをインストールしてSendToにでも入れておけば良いだけではある.しかしWSL側で作業するときは必ずvimを使うのでもともとvimは入っている.2つのvimをインストールするのは避けたい.
- WSL側のvimなら,Linuxで作業しているときと全く同じようにコマンドを呼べる(範囲指定して
:'<,'>:!sort|uniqでソートして重複を削除するとか).
方法1:レジストリを編集してコンテキストメニューに加える
以下の2点を実現するように,レジストリにキーを追加することで,コンテキストメニューからvimでファイルを開くことができるようにする.
- bash.exeを起動して,その中でvimを起動する.
- vimの引数にはエクスプローラで選択していたファイル名をWSL形式に変換して渡す.
まずregeditを起動してHKEY_CLASSES_ROOT\*\shellに新規キーとしてOpenWithVimを作る(名前は適当でよい).作成したら名前が(規定)な文字列値(REG_SZ)がその下にできているはずなので,値(データ)をOpen with Vim (&W)にする.これもエクスプローラ上でファイルを右クリックした際に表示されるコンテキストメニュー上での項目名なので何でもよい.ただし末尾の(&W)はショートカットキーを決める文字列なので,好みのものに変更するとよい1.
続けてキーOpenWithVimの下に新規キーとしてcommandを作成し,(規定)文字列値のデータを
C:\Windows\System32\bash.exe -c "vim \"$(wslpath -a -u "%1")\""
にする.なお冒頭の参考サイトでは1803アップデート以前のWSLを想定して同様の処理を以下のようにsedで行っている.
C:\Windows\System32\bash.exe -c "vim $(lower=$(echo "%1" | sed 's/\\/\//g' | sed 's/://') && echo /mnt/${lower,})"
以上を行うと,
- ファイルを選択した状態でアプリケーションキー/メニューキーを押す(もしくはファイルを右クリックする)
- コンテキストメニューが表示される
-
Wキーを押す
という操作でvimが起動する.
参考までに,以下をOpenWithVim.regなど適当な名前のテキストファイルとして作成してダブルクリックすれば,上記のregeditによるキー追加を行うことができる.
Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT\*\shell\OpenWithVim]
@="Open with Vim (&W)"
[HKEY_CLASSES_ROOT\*\shell\OpenWithVIM\command]
@="C:\\Windows\\System32\\bash.exe -c \"vim \\\"$(wslpath -a -u \"%1\")\\\"\""
方法2:「送る」メニューに加える
手順1のcommandと同じ内容を持つバッチファイルを作成してSendToに配置すれば,コンテキストメニューの「送る」からvimで開くことができるようになる.
まずWin+Rを押して「ファイル名を指定して実行」を開き,shell:sendtoを実行するとSendToフォルダが開く.このフォルダに下記の内容でバッチファイルを作る.ファイル名は適当でもよいが,先頭の文字がそのままショートカットキーになるので,使いやすいものを選ぶとよい.
@C:\Windows\System32\bash.exe -c "vim \"$(wslpath -a -u "%1")\""
以上を行うと,
- ファイルを選択した状態でアプリケーションキー/メニューキーを押す(もしくはファイルを右クリックする)
- コンテキストメニューが表示される
-
Nキーで「送る」サブメニューが開く -
Vキーを押す
という操作でvimが起動する.
方法2’:複数ファイル対応版
バッチファイルを以下のように変更すると,複数のファイルを同時にタブで開くことができる.
@echo off
setlocal enabledelayedexpansion
set i=1
set WSLENV=Xa/u
set Xa=
for %%f in (%*) do (
set X!i!=%%~f
set WSLENV=!WSLENV!:X!i!/p
set Xa=\"$X!i!\" !Xa!
set /A i+=1
)
C:\Windows\System32\bash.exe -c "vim -p %Xa%"
行っていることは以下の通り.
- バッチファイルの引数
%1,%2, ...を,変数X1,X2, ...に入れる.ただしダブルクォートを除去する(%%~fの~による機能.これがないとWSLENVによる変換に失敗する). -
WSLENVにX1/p,X2/p, ...を追加し,これらの変数がWSL側の環境変数として現れるように指示(/pはWindows側からWSL側へのパスの変換). - vimを起動する際に,
WSLENVを介して変換された環境変数$X1,$X2, ...を引数とする.
wslpathが複数のファイル名を一括変換してくれないので,WSLENVの/pによって実現している.またWSLENVの/lでもPATH変数の書式で一括変換ができるが,却って面倒な実装になりそうだったので断念.またwslpathをWSL側で複数回呼び出す方法も考えられるかもしれない.
参考
- https://situsali.com/membuat-shortcut-open-vim-dari-wsl/ (インドネシア語)
- Windows 10のコマンドプロンプトからWSL上のLinuxコマンドを呼び出す(バージョン1803対応版)
- 【Windows】右クリックメニュー[送る]の活用方法、追加・設定方法(SendToディレクトリの場所一覧) | onocom
-
たとえばvimの頭文字から
(&V)としてもよい.しかし「以前のバージョンの復元」とキーが重複するため,Vキーを押した後にEnterを押す手間が増える. ↩