diff src/misc2.c @ 25068:0ce24f734615 v8.2.3071

patch 8.2.3071: shell options are not set properly for PowerShell Commit: https://github.com/vim/vim/commit/127950241e84c822d3c50f46a00d42a70d2d5cb6 Author: Mike Williams <mikew@globalgraphics.com> Date: Mon Jun 28 20:53:58 2021 +0200 patch 8.2.3071: shell options are not set properly for PowerShell Problem: Shell options are not set properly for PowerShell. Solution: Use better option defaults. (Mike Willams, closes https://github.com/vim/vim/issues/8459)
author Bram Moolenaar <Bram@vim.org>
date Mon, 28 Jun 2021 21:00:04 +0200
parents 7334bf933510
children beff72446e2e
line wrap: on
line diff
--- a/src/misc2.c
+++ b/src/misc2.c
@@ -1396,7 +1396,9 @@ csh_like_shell(void)
 /*
  * Escape "string" for use as a shell argument with system().
  * This uses single quotes, except when we know we need to use double quotes
- * (MS-DOS and MS-Windows without 'shellslash' set).
+ * (MS-DOS and MS-Windows not using PowerShell and without 'shellslash' set).
+ * PowerShell also uses a novel escaping for enclosed single quotes - double
+ * them up.
  * Escape a newline, depending on the 'shell' option.
  * When "do_special" is TRUE also replace "!", "%", "#" and things starting
  * with "<" like "<cfile>".
@@ -1412,6 +1414,10 @@ vim_strsave_shellescape(char_u *string, 
     char_u	*escaped_string;
     int		l;
     int		csh_like;
+# ifdef MSWIN
+    int		powershell;
+    int		double_quotes;
+# endif
 
     // Only csh and similar shells expand '!' within single quotes.  For sh and
     // the like we must not put a backslash before it, it will be taken
@@ -1419,12 +1425,18 @@ vim_strsave_shellescape(char_u *string, 
     // Csh also needs to have "\n" escaped twice when do_special is set.
     csh_like = csh_like_shell();
 
+# ifdef MSWIN
+    // PowerShell only accepts single quotes so override p_ssl.
+    powershell = strstr((char *)gettail(p_sh), "powershell") != NULL;
+    double_quotes = !powershell && !p_ssl;
+# endif
+
     // First count the number of extra bytes required.
     length = (unsigned)STRLEN(string) + 3;  // two quotes and a trailing NUL
     for (p = string; *p != NUL; MB_PTR_ADV(p))
     {
 # ifdef MSWIN
-	if (!p_ssl)
+	if (double_quotes)
 	{
 	    if (*p == '"')
 		++length;		// " -> ""
@@ -1432,7 +1444,14 @@ vim_strsave_shellescape(char_u *string, 
 	else
 # endif
 	if (*p == '\'')
-	    length += 3;		// ' => '\''
+	{
+# ifdef MSWIN
+	    if (powershell)
+		length +=2;		// ' => ''
+	    else
+# endif
+		length += 3;		// ' => '\''
+	}
 	if ((*p == '\n' && (csh_like || do_newline))
 		|| (*p == '!' && (csh_like || do_special)))
 	{
@@ -1455,7 +1474,7 @@ vim_strsave_shellescape(char_u *string, 
 
 	// add opening quote
 # ifdef MSWIN
-	if (!p_ssl)
+	if (double_quotes)
 	    *d++ = '"';
 	else
 # endif
@@ -1464,7 +1483,7 @@ vim_strsave_shellescape(char_u *string, 
 	for (p = string; *p != NUL; )
 	{
 # ifdef MSWIN
-	    if (!p_ssl)
+	    if (double_quotes)
 	    {
 		if (*p == '"')
 		{
@@ -1478,10 +1497,20 @@ vim_strsave_shellescape(char_u *string, 
 # endif
 	    if (*p == '\'')
 	    {
-		*d++ = '\'';
-		*d++ = '\\';
-		*d++ = '\'';
-		*d++ = '\'';
+# ifdef MSWIN
+		if (powershell)
+		{
+		    *d++ = '\'';
+		    *d++ = '\'';
+		}
+		else
+# endif
+		{
+		    *d++ = '\'';
+		    *d++ = '\\';
+		    *d++ = '\'';
+		    *d++ = '\'';
+		}
 		++p;
 		continue;
 	    }
@@ -1507,7 +1536,7 @@ vim_strsave_shellescape(char_u *string, 
 
 	// add terminating quote and finish with a NUL
 # ifdef MSWIN
-	if (!p_ssl)
+	if (double_quotes)
 	    *d++ = '"';
 	else
 # endif