powersell 7 で set shell=pwsh をしてあると、system() を呼ぶ際にしばしば問題が出る。 今回は vim-plug で PlugStatus するとエラーが出ることがわかった。下記パッチを当てて解決。

PS C:\Users\rollman\vimfiles\autoload> & 'C:\Program Files (x86)\GnuWin32\bin\diff.exe' -u plug.vim.org .\plug.vim
--- plug.vim.org        2023-12-19 10:19:18.270949700 +0900
+++ .\plug.vim  2023-12-19 16:41:03.117028000 +0900
@@ -1415,7 +1415,11 @@
     if has_key(a:opts, 'dir')
       let job.cwd = a:opts.dir
     endif
-    let argv = a:cmd
+    let argv = s:is_powershell(&shell)
+                \ ? ['pwsh'] + split(&shellcmdflag, " ") +  ['"'.a:cmd.'"']
+                \ : s:is_win
+                  \ ? ['cmd', '/s', '/c', '"'.a:cmd.'"']
+                  \ : a:cmd
     call extend(job, {
     \ 'on_stdout': function('s:nvim_cb'),
     \ 'on_stderr': function('s:nvim_cb'),
@@ -2228,7 +2232,7 @@
     return a:arg
   endif
   let opts = a:0 > 0 && type(a:1) == s:TYPE.dict ? a:1 : {}
-  let shell = get(opts, 'shell', s:is_win ? 'cmd.exe' : 'sh')
+  let shell = 'pwsh' "get(opts, 'shell', s:is_win ? 'cmd.exe' : 'sh')
   let script = get(opts, 'script', 1)
   if shell =~# 'cmd\(\.exe\)\?$'
     return s:shellesc_cmd(a:arg, script)
@@ -2269,7 +2273,7 @@

 function! s:with_cd(cmd, dir, ...)
   let script = a:0 > 0 ? a:1 : 1
-  return printf('cd%s %s && %s', s:is_win ? ' /d' : '', plug#shellescape(a:dir, {'script': script}), a:cmd)
+  return printf('cd%s %s && %s', s:is_powershell(&shell) ? '' : s:is_win ? ' /d' : '', plug#shellescape(a:dir, {'script': script}), a:cmd)
 endfunction

 function! s:system(cmd, ...)

ほとんど該当 issue [1] のままだが、Ungerfall が最後に付け足している通り &shellcmdflag で書いて動作を確認した。あとは let shell = ... の部分を generalize すれば PR にできる。

ここまで書いて思ったが、vim-plug は最近あまりメンテナンスされてないらしい。 PR はつくられ続けているものの、2023-12-19 現在、最後に merge されたのは Apr. 1 である。しかも、vim-plug は個人レポジトリであり、push access ができる人はどうやら少ないようだ。一応11 月にメンテナが PR にコメントはしているが、今 PR を出していつ merge されるかは結構暗雲立ち込める。

結局、vim-plug をやめて vim の純正機能である packages を使うことにした。 .vim ディレクトリを git で管理してプラグインはサブモジュール化すれば機能としては十分だろう。

References