From aab8f15cf713b46d8007f315e787bfd45347984d Mon Sep 17 00:00:00 2001 From: Christian Brabandt Date: Thu, 13 Jun 2024 20:08:03 +0200 Subject: [PATCH] Problem: globbing() not sufficiently tested Problem: globbing() not sufficiently tested Solution: Add more tests for directory containing [] chars, fix a similar issue in netrw, slightly update the documentation for mkdir() fixes: #14952 Signed-off-by: Christian Brabandt --- runtime/autoload/netrw.vim | 23 ++++++++++++++--------- runtime/doc/builtin.txt | 19 ++++++++----------- src/testdir/test_functions.vim | 27 +++++++++++++++++++++++++++ 3 files changed, 49 insertions(+), 20 deletions(-) diff --git a/runtime/autoload/netrw.vim b/runtime/autoload/netrw.vim index 300729eba8d8fb..ef574773a4a1a4 100644 --- a/runtime/autoload/netrw.vim +++ b/runtime/autoload/netrw.vim @@ -14,6 +14,7 @@ " 2024 May 10 by Vim Project: recursively delete directories by default " 2024 May 13 by Vim Project: prefer scp over pscp " 2024 Jun 04 by Vim Project: set bufhidden if buffer changed, nohidden is set and buffer shall be switched (#14915) +" 2024 Jun 13 by Vim Project: glob() on Windows fails when a directory name contains [] (#14952) " Former Maintainer: Charles E Campbell " GetLatestVimScripts: 1075 1 :AutoInstall: netrw.vim " Copyright: Copyright (C) 2016 Charles E. Campbell {{{1 @@ -5798,16 +5799,20 @@ fun! s:NetrwGlob(direntry,expr,pare) let filelist= w:netrw_treedict[a:direntry] endif let w:netrw_liststyle= keep_liststyle - elseif v:version > 704 || (v:version == 704 && has("patch656")) - let filelist= glob(s:ComposePath(fnameescape(a:direntry),a:expr),0,1,1) - if a:pare - let filelist= map(filelist,'substitute(v:val, "^.*/", "", "")') - endif else - let filelist= glob(s:ComposePath(fnameescape(a:direntry),a:expr),0,1) - if a:pare - let filelist= map(filelist,'substitute(v:val, "^.*/", "", "")') - endif + let path= s:ComposePath(fnameescape(a:direntry),a:expr) + if has("win64") + " escape [ so it is not detected as wildcard character, see :h wildcard + let path= substitute(path, '[', '[[]', 'g') + endif + if v:version > 704 || (v:version == 704 && has("patch656")) + let filelist= glob(path,0,1,1) + else + let filelist= glob(path,0,1) + endif + if a:pare + let filelist= map(filelist,'substitute(v:val, "^.*/", "", "")') + endif endif " call Dret("s:NetrwGlob ".string(filelist)) return filelist diff --git a/runtime/doc/builtin.txt b/runtime/doc/builtin.txt index dd46430e93bb3b..a7b95a6a595251 100644 --- a/runtime/doc/builtin.txt +++ b/runtime/doc/builtin.txt @@ -7329,17 +7329,14 @@ mkdir({name} [, {flags} [, {prot}]]) *mkdir()* *E739* When {flags} is present it must be a string. An empty string has no effect. - If {flags} contains "p" then intermediate directories are - created as necessary. - - If {flags} contains "D" then {name} is deleted at the end of - the current function, as with: > - defer delete({name}, 'd') -< - If {flags} contains "R" then {name} is deleted recursively at - the end of the current function, as with: > - defer delete({name}, 'rf') -< Note that when {name} has more than one part and "p" is used + {flags} can contain these character flags: + "p" intermediate directories will be created as necessary + "D" {name} will be deleted at the end of the current + function, but not recursively + "R" {name} will be deleted recursively at the end of the + current function + + Note that when {name} has more than one part and "p" is used some directories may already exist. Only the first one that is created and what it contains is scheduled to be deleted. E.g. when using: > diff --git a/src/testdir/test_functions.vim b/src/testdir/test_functions.vim index fd82801e652084..c4b2da2f51cbfe 100644 --- a/src/testdir/test_functions.vim +++ b/src/testdir/test_functions.vim @@ -3795,6 +3795,33 @@ func Test_glob() call assert_fails("call glob('*', 0, {})", 'E728:') endfunc +func Test_glob2() + call mkdir('[XglobDir]', 'R') + call mkdir('abc[glob]def', 'R') + + call writefile(['glob'], '[XglobDir]/Xglob') + call writefile(['glob'], 'abc[glob]def/Xglob') + if !has("win64") + call assert_equal([], (glob('[XglobDir]/*', 0, 1))) + call assert_equal([], (glob('abc[glob]def/*', 0, 1))) + call assert_equal(['[XglobDir]/Xglob'], (glob('\[XglobDir]/*', 0, 1))) + call assert_equal(['abc[glob]def/Xglob'], (glob('abc\[glob]def/*', 0, 1))) + else + let _sl=&shellslash + call assert_equal([], (glob('[XglobDir]\*', 0, 1))) + call assert_equal([], (glob('abc[glob]def\*', 0, 1))) + call assert_equal([], (glob('\[XglobDir]\*', 0, 1))) + call assert_equal([], (glob('abc\[glob]def\*', 0, 1))) + set noshellslash + call assert_equal(['[XglobDir]\Xglob'], (glob('[[]XglobDir]/*', 0, 1))) + call assert_equal(['abc[glob]def\Xglob'], (glob('abc[[]glob]def/*', 0, 1))) + set shellslash + call assert_equal(['[XglobDir]/Xglob'], (glob('[[]XglobDir]/*', 0, 1))) + call assert_equal(['abc[glob]def/Xglob'], (glob('abc[[]glob]def/*', 0, 1))) + let &shellslash=_sl + endif +endfunc + " Test for browse() func Test_browse() CheckFeature browse