0
0
mirror of https://github.com/vim/vim.git synced 2025-08-31 20:53:42 -04:00

patch 8.2.3530: ":buf \{a}" fails while ":edit \{a}" works

Problem:    ":buf \{a}" fails while ":edit \{a}" works.
Solution:   Unescape "\{". (closes #8917)
This commit is contained in:
Bram Moolenaar 2021-10-17 17:20:23 +01:00
parent 34a364877f
commit 21c1a0c2f1
11 changed files with 38 additions and 15 deletions

View File

@ -48,6 +48,8 @@ ExpandEscape(
{ {
int i; int i;
char_u *p; char_u *p;
int vse_what = xp->xp_context == EXPAND_BUFFERS
? VSE_BUFFER : VSE_NONE;
// May change home directory back to "~" // May change home directory back to "~"
if (options & WILD_HOME_REPLACE) if (options & WILD_HOME_REPLACE)
@ -84,9 +86,10 @@ ExpandEscape(
} }
} }
#ifdef BACKSLASH_IN_FILENAME #ifdef BACKSLASH_IN_FILENAME
p = vim_strsave_fnameescape(files[i], FALSE); p = vim_strsave_fnameescape(files[i], vse_what);
#else #else
p = vim_strsave_fnameescape(files[i], xp->xp_shell); p = vim_strsave_fnameescape(files[i],
xp->xp_shell ? VSE_SHELL : vse_what);
#endif #endif
if (p != NULL) if (p != NULL)
{ {

View File

@ -3886,7 +3886,7 @@ f_fnameescape(typval_T *argvars, typval_T *rettv)
return; return;
rettv->vval.v_string = vim_strsave_fnameescape( 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; rettv->v_type = VAR_STRING;
} }

View File

@ -3894,27 +3894,32 @@ ccheck_abbr(int c)
} }
/* /*
* Escape special characters in "fname" for when used as a file name argument * Escape special characters in "fname", depending on "what":
* after a Vim command, or, when "shell" is non-zero, a shell command. * 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. * Returns the result in allocated memory.
*/ */
char_u * char_u *
vim_strsave_fnameescape(char_u *fname, int shell UNUSED) vim_strsave_fnameescape(char_u *fname, int what)
{ {
char_u *p; char_u *p;
#ifdef BACKSLASH_IN_FILENAME #ifdef BACKSLASH_IN_FILENAME
char_u buf[20]; char_u buf[20];
int j = 0; int j = 0;
// Don't escape '[', '{' and '!' if they are in 'isfname'. // Don't escape '[', '{' and '!' if they are in 'isfname' and for the
for (p = PATH_ESC_CHARS; *p != NUL; ++p) // ":buffer" command.
for (p = what == VSE_BUFFER ? BUFFER_ESC_CHARS : PATH_ESC_CHARS;
*p != NUL; ++p)
if ((*p != '[' && *p != '{' && *p != '!') || !vim_isfilec(*p)) if ((*p != '[' && *p != '{' && *p != '!') || !vim_isfilec(*p))
buf[j++] = *p; buf[j++] = *p;
buf[j] = NUL; buf[j] = NUL;
p = vim_strsave_escaped(fname, buf); p = vim_strsave_escaped(fname, buf);
#else #else
p = vim_strsave_escaped(fname, shell ? SHELL_ESC_CHARS : PATH_ESC_CHARS); p = vim_strsave_escaped(fname, what == VSE_SHELL ? SHELL_ESC_CHARS
if (shell && csh_like_shell() && p != NULL) : what == VSE_BUFFER ? BUFFER_ESC_CHARS : PATH_ESC_CHARS);
if (what == VSE_SHELL && csh_like_shell() && p != NULL)
{ {
char_u *s; char_u *s;

View File

@ -3741,7 +3741,7 @@ nv_ident(cmdarg_T *cap)
ptr = vim_strnsave(ptr, n); ptr = vim_strnsave(ptr, n);
if (kp_ex) if (kp_ex)
// Escape the argument properly for an Ex command // Escape the argument properly for an Ex command
p = vim_strsave_fnameescape(ptr, FALSE); p = vim_strsave_fnameescape(ptr, VSE_NONE);
else else
// Escape the argument properly for a shell command // Escape the argument properly for a shell command
p = vim_strsave_shellescape(ptr, TRUE, TRUE); p = vim_strsave_shellescape(ptr, TRUE, TRUE);

View File

@ -26,7 +26,7 @@ void redrawcmd(void);
void compute_cmdrow(void); void compute_cmdrow(void);
void cursorcmd(void); void cursorcmd(void);
void gotocmdline(int clr); 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 escape_fname(char_u **pp);
void tilde_replace(char_u *orig_pat, int num_files, char_u **files); void tilde_replace(char_u *orig_pat, int num_files, char_u **files);
cmdline_info_T *get_cmdline_info(void); cmdline_info_T *get_cmdline_info(void);

View File

@ -43,7 +43,7 @@ ses_put_fname(FILE *fd, char_u *name, unsigned *flagp)
} }
// escape special characters // escape special characters
p = vim_strsave_fnameescape(sname, FALSE); p = vim_strsave_fnameescape(sname, VSE_NONE);
vim_free(sname); vim_free(sname);
if (p == NULL) if (p == NULL)
return FAIL; return FAIL;

View File

@ -667,7 +667,7 @@ term_start(
if (s == NULL) if (s == NULL)
break; break;
p = vim_strsave_fnameescape(s, FALSE); p = vim_strsave_fnameescape(s, VSE_NONE);
if (p == NULL) if (p == NULL)
break; break;
ga_concat(&ga, p); ga_concat(&ga, p);

View File

@ -900,6 +900,12 @@ func Test_cmdline_complete_various()
call feedkeys(":unlet one two\<C-A>\<C-B>\"\<CR>", 'xt') call feedkeys(":unlet one two\<C-A>\<C-B>\"\<CR>", 'xt')
call assert_equal("\"unlet one two", @:) 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 " completion for the :bdelete command
call feedkeys(":bdel a b c\<C-A>\<C-B>\"\<CR>", 'xt') call feedkeys(":bdel a b c\<C-A>\<C-B>\"\<CR>", 'xt')
call assert_equal("\"bdel a b c", @:) call assert_equal("\"bdel a b c", @:)

View File

@ -757,6 +757,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
3530,
/**/ /**/
3529, 3529,
/**/ /**/

View File

@ -291,6 +291,7 @@
#endif #endif
#ifdef BACKSLASH_IN_FILENAME #ifdef BACKSLASH_IN_FILENAME
# define PATH_ESC_CHARS ((char_u *)" \t\n*?[{`%#'\"|!<") # define PATH_ESC_CHARS ((char_u *)" \t\n*?[{`%#'\"|!<")
# define BUFFER_ESC_CHARS ((char_u *)" \t\n*?[`%#'\"|!<")
#else #else
# ifdef VMS # ifdef VMS
// VMS allows a lot of characters in the file name // VMS allows a lot of characters in the file name
@ -300,6 +301,7 @@
# define PATH_ESC_CHARS ((char_u *)" \t\n*?[{`$\\%#'\"|!<") # define PATH_ESC_CHARS ((char_u *)" \t\n*?[{`$\\%#'\"|!<")
# define SHELL_ESC_CHARS ((char_u *)" \t\n*?[{`$\\%#'\"|!<>();&") # define SHELL_ESC_CHARS ((char_u *)" \t\n*?[{`$\\%#'\"|!<>();&")
# endif # endif
# define BUFFER_ESC_CHARS ((char_u *)" \t\n*?[`$\\%#'\"|!<")
#endif #endif
// length of a buffer to store a number in ASCII (64 bits binary + NUL) // 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_BUFFER 1 // -buffer: local to current buffer
#define UC_VIM9 2 // {} argument: Vim9 syntax. #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 #endif // VIM__H

View File

@ -1147,7 +1147,8 @@ do_2string(typval_T *tv, int is_2string_any, int tolerant)
while ((e = vim_strchr(s, '\n')) != NULL) while ((e = vim_strchr(s, '\n')) != NULL)
{ {
*e = NUL; *e = NUL;
p = vim_strsave_fnameescape(s, FALSE); p = vim_strsave_fnameescape(s,
VSE_NONE);
if (p != NULL) if (p != NULL)
{ {
ga_concat(&ga, p); ga_concat(&ga, p);