From 1cfbf104f509854a66a12ca070d388b7374632bc Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Fri, 19 Jun 2026 08:57:03 +0800 Subject: [PATCH] vim-patch:9.2.0676: MS-Windows: cannot switch to a buffer with '%' in its name (#40315) Problem: On MS-Windows it is not possible to switch to a buffer by name with ":b" (including via command-line completion) when the buffer name contains '%'. Solution: Do not escape '%' and '#' for the ":buffer" command on MS-Windows. Since ":buffer" has no EX_XFILE these are not expanded, and escaping them as "\%"/"\#" makes buffer name matching fail when '%'/'#' is in 'isfname' (the backslash is treated as a path separator). fixes: vim/vim#20529 closes: vim/vim#20548 https://github.com/vim/vim/commit/1a96e07bf6ba46f4b6f50a861d755d0fbc89dabb Co-authored-by: Hirohito Higashi Co-authored-by: Claude Opus 4.8 (1M context) --- src/nvim/ex_getln.c | 5 ++++- test/old/testdir/test_buffer.vim | 15 +++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c index 4590b86f18..7a3cf52a1a 100644 --- a/src/nvim/ex_getln.c +++ b/src/nvim/ex_getln.c @@ -4192,7 +4192,10 @@ char *vim_strsave_fnameescape(const char *const fname, const int what) { #ifdef BACKSLASH_IN_FILENAME # define PATH_ESC_CHARS " \t\n*?[{`%#'\"|!<" -# define BUFFER_ESC_CHARS (" \t\n*?[`%#'\"|!<") +// '%' and '#' are not escaped for ":buffer": it has no EX_XFILE, so they are +// not expanded, and escaping them as "\%"/"\#" breaks buffer name matching +// when '%'/'#' is in 'isfname' (backslash treated as a path separator). +# define BUFFER_ESC_CHARS (" \t\n*?[`'\"|!<") char buf[sizeof(PATH_ESC_CHARS)]; int j = 0; diff --git a/test/old/testdir/test_buffer.vim b/test/old/testdir/test_buffer.vim index e71907ff39..c025811b53 100644 --- a/test/old/testdir/test_buffer.vim +++ b/test/old/testdir/test_buffer.vim @@ -937,4 +937,19 @@ func Test_split_window_in_BufLeave_from_switching_buffer() bwipe! Xb endfunc +" Switch to a buffer whose name contains '%' via completion (#20529). +func Test_buffer_switch_to_name_with_percent() + CheckMSWindows + + let bufnr = bufadd('Xpercent%name') + call setbufvar(bufnr, '&buflisted', 1) + call bufload(bufnr) + enew + + call feedkeys(":b Xpercent\\", 'xt') + call assert_equal(bufnr, bufnr('%')) + + exe 'bwipe! ' .. bufnr +endfunc + " vim: shiftwidth=2 sts=2 expandtab