Vim
rust
WSL

rust-doc.vimでrust-doc-open: Failed to open URL, xdg-open: no method available for opening / WSLからrust-doc.vim

エラー全文

rust-doc-open: Failed to open URL: Unescaped left brace in regex is deprecated, passed through in regex; marked by <-- HERE in m/%{ <-- HERE (.*?)}/ at usr/bin/run-mailcap line 528.^@Couldn't find a suitable web browser!^@Set the BROWSER environment variable to your desired browser.^@Warning: program returned non-zero exit code #1^@/usr/bin/xdg-open: 771: /usr/bin/xdg-open: www-browser: not found^@/usr/bin/xdg-open: 771: /usr/bin/xdg-open: links2: not found^@/usr/bin/xdg-open: 771: /usr/bin/xdg-open: elinks: not found^@/usr/bin/xdg-open: 771: /usr/bin/xdg-open: links: not found^@/usr/bin/xdg-open: 771: /usr/bin/xdg-open: lynx: not found^@/usr/bin/xdg-open: 771: /usr/bin/xdg-open: w3m: not found^@xdg-open: no method available for opening '/home/miyagaw61/docs/rust-docs/share/doc/rust/html/std/vec/index.html'^@

環境

  • WSL
  • NeoVim

原因

  • BROWSER環境変数が宣言されていなかった
  • xdg-open が ローカルファイルからの読み込みに対応していない
  • WSLから叩くchrome.exeがパスを解釈できない

解決方法

$ export PATH=$PATH:/path/to
$ cat << EOF > /path/to/chrome
/mnt/c/Program\ Files\ \(x86\)/Google/Chrome/Application/chrome.exe $@
EOF
$ export BROWSER=chrome
$ nvim /path/to/rust.vim/autoload/rust_doc.vim # 僕の場合は~/.cache/dein/repos/github.com/rhysd/rust-doc.vim/autoload/rust_doc.vim

# 以下の4行を該当部分に追記

function! s:open(item) abort
    echomsg printf("rust-doc: '%s' is found", a:item.name)

    let url = shellescape(a:item.path)
    if g:rust_doc#vim_open_cmd != ''
        execute g:rust_doc#vim_open_cmd url
        return
    endif

    if g:rust_doc#open_cmd != ''
        let output = system(g:rust_doc#open_cmd . ' ' . url)
        if v:shell_error
            call s:error("Failed to open URL: " . output)
        endif
        return
    endif

+    call system('cp ' . url . ' ./rust_doc.html')
+    call system('chrome rust_doc.html')
+    call system('rm -rf rust_doc.html')
+    return

    try
        call openbrowser#open(url)
    catch /^Vim\%((\a\+)\)\=:E117/
        if has('win32') || has('win64')
            let cmd = 'rundll32 url.dll,FileProtocolHandler ' . url
        elseif executable('xdg-open') && has('unix')
            let cmd = 'xdg-open ' . url
        elseif executable('open') && has('mac')
            let cmd = 'open ' . url
        elseif executable('google-chrome')
            let cmd = 'google-chrome ' . url
        elseif executable('firefox')
            let cmd = 'firefox ' . url
        else
            call s:error("No command is found to open URL. Please set g:rust_doc#open_cmd")
            return
        endif

        let output = system(cmd)
        if v:shell_error
            call s:error("Failed to open URL: " . output)
        endif
    endtry
endfunction

パスを解釈できないchrome.exeでもファイル名だけを引数に渡せば成功するので、無理矢理カレントディレクトリにhtmlファイルをコピーしてchrome.exe <file_name>を実行してその後ファイルを削除しているだけです。