]> granicus.if.org Git - vim/commitdiff
patch 8.2.3530: ":buf \{a}" fails while ":edit \{a}" works v8.2.3530
authorBram Moolenaar <Bram@vim.org>
Sun, 17 Oct 2021 16:20:23 +0000 (17:20 +0100)
committerBram Moolenaar <Bram@vim.org>
Sun, 17 Oct 2021 16:20:23 +0000 (17:20 +0100)
Problem:    ":buf \{a}" fails while ":edit \{a}" works.
Solution:   Unescape "\{". (closes #8917)

src/cmdexpand.c
src/evalfunc.c
src/ex_getln.c
src/normal.c
src/proto/ex_getln.pro
src/session.c
src/terminal.c
src/testdir/test_cmdline.vim
src/version.c
src/vim.h
src/vim9execute.c

index c36c21a3d854a12471f58f8ccc191459d04b12ea..c98e126a5c2b0fbe389ea6d000c978812b6dd2d2 100644 (file)
@@ -48,6 +48,8 @@ ExpandEscape(
 {
     int                i;
     char_u     *p;
+    int                vse_what = xp->xp_context == EXPAND_BUFFERS
+                                                      ? VSE_BUFFER : VSE_NONE;
 
     // May change home directory back to "~"
     if (options & WILD_HOME_REPLACE)
@@ -84,9 +86,10 @@ ExpandEscape(
                    }
                }
 #ifdef BACKSLASH_IN_FILENAME
-               p = vim_strsave_fnameescape(files[i], FALSE);
+               p = vim_strsave_fnameescape(files[i], vse_what);
 #else
-               p = vim_strsave_fnameescape(files[i], xp->xp_shell);
+               p = vim_strsave_fnameescape(files[i],
+                                         xp->xp_shell ? VSE_SHELL : vse_what);
 #endif
                if (p != NULL)
                {
index 4abbdb90f62953c85d81361e5b7104ab6b6d5a05..08438242b6ed5a07024260d956cbbed81c653b5f 100644 (file)
@@ -3886,7 +3886,7 @@ f_fnameescape(typval_T *argvars, typval_T *rettv)
        return;
 
     rettv->vval.v_string = vim_strsave_fnameescape(
-                                          tv_get_string(&argvars[0]), FALSE);
+                                        tv_get_string(&argvars[0]), VSE_NONE);
     rettv->v_type = VAR_STRING;
 }
 
index 07eac908635936f7c824d76f56531b01167870ff..258548ed8a1897d6f1aa8c2ec48aebbbe4230907 100644 (file)
@@ -3894,27 +3894,32 @@ ccheck_abbr(int c)
 }
 
 /*
- * Escape special characters in "fname" for when used as a file name argument
- * after a Vim command, or, when "shell" is non-zero, a shell command.
+ * Escape special characters in "fname", depending on "what":
+ * VSE_NONE: for when used as a file name argument after a Vim command.
+ * VSE_SHELL: for a shell command.
+ * VSE_BUFFER: for the ":buffer" command.
  * Returns the result in allocated memory.
  */
     char_u *
-vim_strsave_fnameescape(char_u *fname, int shell UNUSED)
+vim_strsave_fnameescape(char_u *fname, int what)
 {
     char_u     *p;
 #ifdef BACKSLASH_IN_FILENAME
     char_u     buf[20];
     int                j = 0;
 
-    // Don't escape '[', '{' and '!' if they are in 'isfname'.
-    for (p = PATH_ESC_CHARS; *p != NUL; ++p)
+    // Don't escape '[', '{' and '!' if they are in 'isfname' and for the
+    // ":buffer" command.
+    for (p = what == VSE_BUFFER ? BUFFER_ESC_CHARS : PATH_ESC_CHARS;
+                                                               *p != NUL; ++p)
        if ((*p != '[' && *p != '{' && *p != '!') || !vim_isfilec(*p))
            buf[j++] = *p;
     buf[j] = NUL;
     p = vim_strsave_escaped(fname, buf);
 #else
-    p = vim_strsave_escaped(fname, shell ? SHELL_ESC_CHARS : PATH_ESC_CHARS);
-    if (shell && csh_like_shell() && p != NULL)
+    p = vim_strsave_escaped(fname, what == VSE_SHELL ? SHELL_ESC_CHARS
+                   : what == VSE_BUFFER ? BUFFER_ESC_CHARS : PATH_ESC_CHARS);
+    if (what == VSE_SHELL && csh_like_shell() && p != NULL)
     {
        char_u      *s;
 
index 9cc2ea92489904dd0572b39662136943d554cbae..eafd1fddb628fdf2412fd4669ebedaef8bf4d34f 100644 (file)
@@ -3741,7 +3741,7 @@ nv_ident(cmdarg_T *cap)
        ptr = vim_strnsave(ptr, n);
        if (kp_ex)
            // Escape the argument properly for an Ex command
-           p = vim_strsave_fnameescape(ptr, FALSE);
+           p = vim_strsave_fnameescape(ptr, VSE_NONE);
        else
            // Escape the argument properly for a shell command
            p = vim_strsave_shellescape(ptr, TRUE, TRUE);
index faecab2a74b4448e1605c0082d104a97d1f2abc0..d047e39dab44c0bd814cf5993b82e053d43c2c67 100644 (file)
@@ -26,7 +26,7 @@ void redrawcmd(void);
 void compute_cmdrow(void);
 void cursorcmd(void);
 void gotocmdline(int clr);
-char_u *vim_strsave_fnameescape(char_u *fname, int shell);
+char_u *vim_strsave_fnameescape(char_u *fname, int what);
 void escape_fname(char_u **pp);
 void tilde_replace(char_u *orig_pat, int num_files, char_u **files);
 cmdline_info_T *get_cmdline_info(void);
index 03b57f0e1918823ab09777d31f3ef5de2568644b..d2b360df8953e49cceb6a3aa426097b2fabd65c7 100644 (file)
@@ -43,7 +43,7 @@ ses_put_fname(FILE *fd, char_u *name, unsigned *flagp)
     }
 
     // escape special characters
-    p = vim_strsave_fnameescape(sname, FALSE);
+    p = vim_strsave_fnameescape(sname, VSE_NONE);
     vim_free(sname);
     if (p == NULL)
        return FAIL;
index cabcf9d1b754cb7103ce8d27469c3ae5b1a9743d..e9dd8ea166aab83655f86c50b68734dd37f9548d 100644 (file)
@@ -667,7 +667,7 @@ term_start(
 
            if (s == NULL)
                break;
-           p = vim_strsave_fnameescape(s, FALSE);
+           p = vim_strsave_fnameescape(s, VSE_NONE);
            if (p == NULL)
                break;
            ga_concat(&ga, p);
index a0f3ffda42ed38803b23e814674106b052f83675..5975bcdf3ab456e7854ca0a96f503071bb6fa32b 100644 (file)
@@ -900,6 +900,12 @@ func Test_cmdline_complete_various()
   call feedkeys(":unlet one two\<C-A>\<C-B>\"\<CR>", 'xt')
   call assert_equal("\"unlet one two", @:)
 
+  " completion for the :buffer command with curlies
+  edit \{someFile}
+  call feedkeys(":buf someFile\<C-A>\<C-B>\"\<CR>", 'xt')
+  call assert_equal("\"buf {someFile}", @:)
+  bwipe {someFile}
+
   " completion for the :bdelete command
   call feedkeys(":bdel a b c\<C-A>\<C-B>\"\<CR>", 'xt')
   call assert_equal("\"bdel a b c", @:)
index 77eb6e1d9881c3c82b82bc1d2ec97e9f0bac4b6c..5758bf979053319dccbe4cd9e224d7e42370840e 100644 (file)
@@ -757,6 +757,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    3530,
 /**/
     3529,
 /**/
index b7a638828071909871709ae56a1cfc26302c8cbe..d2e0d9be352d5f9c899b167c63736c267f0f2597 100644 (file)
--- a/src/vim.h
+++ b/src/vim.h
 #endif
 #ifdef BACKSLASH_IN_FILENAME
 # define PATH_ESC_CHARS ((char_u *)" \t\n*?[{`%#'\"|!<")
+# define BUFFER_ESC_CHARS ((char_u *)" \t\n*?[`%#'\"|!<")
 #else
 # ifdef VMS
     // VMS allows a lot of characters in the file name
 #  define PATH_ESC_CHARS ((char_u *)" \t\n*?[{`$\\%#'\"|!<")
 #  define SHELL_ESC_CHARS ((char_u *)" \t\n*?[{`$\\%#'\"|!<>();&")
 # endif
+#  define BUFFER_ESC_CHARS ((char_u *)" \t\n*?[`$\\%#'\"|!<")
 #endif
 
 // length of a buffer to store a number in ASCII (64 bits binary + NUL)
@@ -2766,5 +2768,9 @@ long elapsed(DWORD start_tick);
 #define UC_BUFFER      1       // -buffer: local to current buffer
 #define UC_VIM9                2       // {} argument: Vim9 syntax.
 
+// flags used by vim_strsave_escaped()
+#define VSE_NONE       0
+#define VSE_SHELL      1       // escape for a shell command
+#define VSE_BUFFER     2       // escape for a ":buffer" command
 
 #endif // VIM__H
index 481c94fde64dbb4f6b176e2210d8db70f0bbe3a1..8a14a856b155a8f6d09ec3a59e96e5de74602ec3 100644 (file)
@@ -1147,7 +1147,8 @@ do_2string(typval_T *tv, int is_2string_any, int tolerant)
                                    while ((e = vim_strchr(s, '\n')) != NULL)
                                    {
                                        *e = NUL;
-                                       p = vim_strsave_fnameescape(s, FALSE);
+                                       p = vim_strsave_fnameescape(s,
+                                                                    VSE_NONE);
                                        if (p != NULL)
                                        {
                                            ga_concat(&ga, p);