From b2133cf2ec935c55de0c3a306a6b7dc3546226da Mon Sep 17 00:00:00 2001
From: Jan Edmund Lazo <jan.lazo@mail.utoronto.ca>
Date: Mon, 20 Jul 2020 07:59:29 -0400
Subject: [PATCH] Support Windows shell without extension (#997)

Close https://github.com/junegunn/vim-plug/issues/995

Vim supports omitting file extensions for its option.
I omitted the file extension in Neovim's documentation for powershell.
---
 plug.vim              | 14 +++++++-------
 test/functional.vader |  4 ++++
 2 files changed, 11 insertions(+), 7 deletions(-)

diff --git a/plug.vim b/plug.vim
index 69033ec..7914bfe 100644
--- a/plug.vim
+++ b/plug.vim
@@ -179,7 +179,7 @@ function! s:define_commands()
   endif
   if has('win32')
   \ && &shellslash
-  \ && (&shell =~# 'cmd\.exe' || &shell =~# 'powershell\.exe')
+  \ && (&shell =~# 'cmd\(\.exe\)\?$' || &shell =~# 'powershell\(\.exe\)\?$')
     return s:err('vim-plug does not support shell, ' . &shell . ', when shellslash is set.')
   endif
   if !has('nvim')
@@ -419,7 +419,7 @@ if s:is_win
     let batchfile = s:plug_tempname().'.bat'
     call writefile(s:wrap_cmds(a:cmd), batchfile)
     let cmd = plug#shellescape(batchfile, {'shell': &shell, 'script': 0})
-    if &shell =~# 'powershell\.exe'
+    if &shell =~# 'powershell\(\.exe\)\?$'
       let cmd = '& ' . cmd
     endif
     return [batchfile, cmd]
@@ -890,9 +890,9 @@ function! s:chsh(swap)
     set shell=sh
   endif
   if a:swap
-    if &shell =~# 'powershell\.exe' || &shell =~# 'pwsh$'
+    if &shell =~# 'powershell\(\.exe\)\?$' || &shell =~# 'pwsh$'
       let &shellredir = '2>&1 | Out-File -Encoding UTF8 %s'
-    elseif &shell =~# 'sh' || &shell =~# 'cmd\.exe'
+    elseif &shell =~# 'sh' || &shell =~# 'cmd\(\.exe\)\?$'
       set shellredir=>%s\ 2>&1
     endif
   endif
@@ -2128,9 +2128,9 @@ function! plug#shellescape(arg, ...)
   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 script = get(opts, 'script', 1)
-  if shell =~# 'cmd\.exe'
+  if shell =~# 'cmd\(\.exe\)\?$'
     return s:shellesc_cmd(a:arg, script)
-  elseif shell =~# 'powershell\.exe' || shell =~# 'pwsh$'
+  elseif shell =~# 'powershell\(\.exe\)\?$' || shell =~# 'pwsh$'
     return s:shellesc_ps1(a:arg)
   endif
   return s:shellesc_sh(a:arg)
@@ -2182,7 +2182,7 @@ function! s:system(cmd, ...)
         return system(a:cmd)
       endif
       let cmd = join(map(copy(a:cmd), 'plug#shellescape(v:val, {"shell": &shell, "script": 0})'))
-      if &shell =~# 'powershell\.exe'
+      if &shell =~# 'powershell\(\.exe\)\?$'
         let cmd = '& ' . cmd
       endif
     else
diff --git a/test/functional.vader b/test/functional.vader
index e928d7e..3742788 100644
--- a/test/functional.vader
+++ b/test/functional.vader
@@ -13,6 +13,7 @@ Execute (plug#shellescape() ignores invalid optional argument):
 Execute (plug#shellescape() depends on the shell):
   AssertEqual "'foo'\\'''", plug#shellescape("foo'", {'shell': 'sh'})
   AssertEqual '^"foo''^"', plug#shellescape("foo'", {'shell': 'cmd.exe'})
+  AssertEqual "'foo'''", plug#shellescape("foo'", {'shell': 'powershell'})
   AssertEqual "'foo'''", plug#shellescape("foo'", {'shell': 'powershell.exe'})
   AssertEqual "'foo'''", plug#shellescape("foo'", {'shell': 'pwsh'})
 
@@ -32,6 +33,9 @@ Execute (plug#shellescape() supports non-trivial cmd.exe escaping):
   \ }),
 
 Execute (plug#shellescape() supports non-trivial powershell.exe escaping):
+  AssertEqual '''\"Foo\\''''\\Bar\"''', plug#shellescape('"Foo\''\Bar"', {
+  \ 'shell': 'powershell',
+  \ }),
   AssertEqual '''\"Foo\\''''\\Bar\"''', plug#shellescape('"Foo\''\Bar"', {
   \ 'shell': 'powershell.exe',
   \ }),