motemen さんの ターミナルの作業中ディレクトリにOSの「ファイルを開く」からもアクセスしたい を見ていいなと思ったので自分もやってみた。ただ、WSL 内で動く tmux の作業ディレクトリを Windows 側に同期したいので、若干ややこしいことをすることになる。

以下のように wsl-update-cwds をつくる。

#!/usr/bin/env ruby

is_wsl = ENV.has_key?('WSLENV')
if !is_wsl
    exit 0
end

# PWSH = '/mnt/c/Windows/System32/WindowsPowerShell/v1.0/powershell.exe'
PWSH = '/mnt/c/Program Files/PowerShell/7/pwsh.exe'

dirs = `tmux list-windows -F '\#{pane_current_path}'`.split("\n").uniq

command = <<~CMD
$WshShell = New-Object -COMObject WScript.Shell
function Create-Shortcut($targetPath, $shortcutPath) {
	$Shortcut = $WshShell.CreateShortcut($shortcutPath)
	$Shortcut.TargetPath = $targetPath
	$Shortcut.Save()
}

Remove-Item -Path $env:USERPROFILE/cwds/*.lnk
CMD
dirs.each do |dir|
    basename =  File.basename(dir)
    win_path = `wslpath -aw '#{dir}'`.chomp
    command << "Create-Shortcut '#{win_path}' $env:USERPROFILE/cwds/#{basename}.lnk\n"
end

# Since pwsh takes a bit of time to start up, run it asynchronously using spawn.
pid = spawn(PWSH, '-NoProfile', '-NoLogo', '-Command', command)
  1. tmux から作業ディレクトリをひっぱってくる
  2. wslpath コマンドで Windows 側のパスに変換する
  3. ↑の情報から PowerShell のコードを生成し、pwsh でショートカットとして生成する

なんでショートカットなのか? というと Junction だと UNC パスにリンクを貼れず、Symlink だと管理者権限が必要になって嫌なので、ほかに方法がない。

あとは zsh の chpwd フックで実行させる。WSLENV 環境変数を見て、存在しないなら実行しないように

chpwd () {
	if [[ -n "${WSLENV+x}" ]]; then
		# in WSL
		$HOME/dotfiles/bin/wsl-update-cwds
	fi
}
  1. トップ
  2. tech
  3. (zsh/tmux/WSL) ターミナルの作業中ディレクトリにOSの「ファイルを開く」からもアクセスしたい
▲ この日のエントリ