mirror of
https://github.com/neovim/neovim.git
synced 2025-09-06 03:18:16 +00:00
Merge pull request #29668 from zeertzjq/vim-9.1.0562
vim-patch:9.1.{0562,0565,0566,0567}: file search fixes
This commit is contained in:
@@ -349,23 +349,24 @@ void *vim_findfile_init(char *path, char *filename, char *stopdirs, int level, i
|
|||||||
search_ctx->ffsc_stopdirs_v = xmalloc(sizeof(char *));
|
search_ctx->ffsc_stopdirs_v = xmalloc(sizeof(char *));
|
||||||
|
|
||||||
do {
|
do {
|
||||||
char *helper;
|
char *helper = walker;
|
||||||
void *ptr;
|
void *ptr = xrealloc(search_ctx->ffsc_stopdirs_v,
|
||||||
|
(dircount + 1) * sizeof(char *));
|
||||||
helper = walker;
|
|
||||||
ptr = xrealloc(search_ctx->ffsc_stopdirs_v,
|
|
||||||
(dircount + 1) * sizeof(char *));
|
|
||||||
search_ctx->ffsc_stopdirs_v = ptr;
|
search_ctx->ffsc_stopdirs_v = ptr;
|
||||||
walker = vim_strchr(walker, ';');
|
walker = vim_strchr(walker, ';');
|
||||||
if (walker) {
|
assert(!walker || walker - helper >= 0);
|
||||||
assert(walker - helper >= 0);
|
size_t len = walker ? (size_t)(walker - helper) : strlen(helper);
|
||||||
search_ctx->ffsc_stopdirs_v[dircount - 1] = xstrnsave(helper, (size_t)(walker - helper));
|
// "" means ascent till top of directory tree.
|
||||||
walker++;
|
if (*helper != NUL && !vim_isAbsName(helper) && len + 1 < MAXPATHL) {
|
||||||
|
// Make the stop dir an absolute path name.
|
||||||
|
xmemcpyz(ff_expand_buffer, helper, len);
|
||||||
|
search_ctx->ffsc_stopdirs_v[dircount - 1] = FullName_save(helper, len);
|
||||||
} else {
|
} else {
|
||||||
// this might be "", which means ascent till top of directory tree.
|
search_ctx->ffsc_stopdirs_v[dircount - 1] = xmemdupz(helper, len);
|
||||||
search_ctx->ffsc_stopdirs_v[dircount - 1] = xstrdup(helper);
|
}
|
||||||
|
if (walker) {
|
||||||
|
walker++;
|
||||||
}
|
}
|
||||||
|
|
||||||
dircount++;
|
dircount++;
|
||||||
} while (walker != NULL);
|
} while (walker != NULL);
|
||||||
search_ctx->ffsc_stopdirs_v[dircount - 1] = NULL;
|
search_ctx->ffsc_stopdirs_v[dircount - 1] = NULL;
|
||||||
@@ -892,11 +893,12 @@ char *vim_findfile(void *search_ctx_arg)
|
|||||||
if (search_ctx->ffsc_start_dir
|
if (search_ctx->ffsc_start_dir
|
||||||
&& search_ctx->ffsc_stopdirs_v != NULL && !got_int) {
|
&& search_ctx->ffsc_stopdirs_v != NULL && !got_int) {
|
||||||
ff_stack_T *sptr;
|
ff_stack_T *sptr;
|
||||||
|
// path_end may point to the NUL or the previous path separator
|
||||||
|
ptrdiff_t plen = (path_end - search_ctx->ffsc_start_dir) + (*path_end != NUL);
|
||||||
|
|
||||||
// is the last starting directory in the stop list?
|
// is the last starting directory in the stop list?
|
||||||
if (ff_path_in_stoplist(search_ctx->ffsc_start_dir,
|
if (ff_path_in_stoplist(search_ctx->ffsc_start_dir,
|
||||||
(int)(path_end - search_ctx->ffsc_start_dir),
|
(size_t)plen, search_ctx->ffsc_stopdirs_v)) {
|
||||||
search_ctx->ffsc_stopdirs_v)) {
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1231,7 +1233,7 @@ static void ff_clear(ff_search_ctx_T *search_ctx)
|
|||||||
/// check if the given path is in the stopdirs
|
/// check if the given path is in the stopdirs
|
||||||
///
|
///
|
||||||
/// @return true if yes else false
|
/// @return true if yes else false
|
||||||
static bool ff_path_in_stoplist(char *path, int path_len, char **stopdirs_v)
|
static bool ff_path_in_stoplist(char *path, size_t path_len, char **stopdirs_v)
|
||||||
{
|
{
|
||||||
// eat up trailing path separators, except the first
|
// eat up trailing path separators, except the first
|
||||||
while (path_len > 1 && vim_ispathsep(path[path_len - 1])) {
|
while (path_len > 1 && vim_ispathsep(path[path_len - 1])) {
|
||||||
@@ -1244,20 +1246,16 @@ static bool ff_path_in_stoplist(char *path, int path_len, char **stopdirs_v)
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; stopdirs_v[i] != NULL; i++) {
|
for (int i = 0; stopdirs_v[i] != NULL; i++) {
|
||||||
if ((int)strlen(stopdirs_v[i]) > path_len) {
|
// match for parent directory. So '/home' also matches
|
||||||
// match for parent directory. So '/home' also matches
|
// '/home/rks'. Check for PATHSEP in stopdirs_v[i], else
|
||||||
// '/home/rks'. Check for PATHSEP in stopdirs_v[i], else
|
// '/home/r' would also match '/home/rks'
|
||||||
// '/home/r' would also match '/home/rks'
|
if (path_fnamencmp(stopdirs_v[i], path, path_len) == 0
|
||||||
if (path_fnamencmp(stopdirs_v[i], path, (size_t)path_len) == 0
|
&& (strlen(stopdirs_v[i]) <= path_len
|
||||||
&& vim_ispathsep(stopdirs_v[i][path_len])) {
|
|| vim_ispathsep(stopdirs_v[i][path_len]))) {
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (path_fnamecmp(stopdirs_v[i], path) == 0) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -2583,6 +2583,10 @@ int get_tagfname(tagname_T *tnp, int first, char *buf)
|
|||||||
// move the filename one char forward and truncate the
|
// move the filename one char forward and truncate the
|
||||||
// filepath with a NUL
|
// filepath with a NUL
|
||||||
filename = path_tail(buf);
|
filename = path_tail(buf);
|
||||||
|
if (r_ptr != NULL) {
|
||||||
|
STRMOVE(r_ptr + 1, r_ptr);
|
||||||
|
r_ptr++;
|
||||||
|
}
|
||||||
STRMOVE(filename + 1, filename);
|
STRMOVE(filename + 1, filename);
|
||||||
*filename++ = NUL;
|
*filename++ = NUL;
|
||||||
|
|
||||||
|
@@ -1,14 +1,14 @@
|
|||||||
" Test findfile() and finddir()
|
" Test findfile() and finddir()
|
||||||
|
|
||||||
let s:files = [ 'Xdir1/foo',
|
let s:files = [ 'Xfinddir1/foo',
|
||||||
\ 'Xdir1/bar',
|
\ 'Xfinddir1/bar',
|
||||||
\ 'Xdir1/Xdir2/foo',
|
\ 'Xfinddir1/Xdir2/foo',
|
||||||
\ 'Xdir1/Xdir2/foobar',
|
\ 'Xfinddir1/Xdir2/foobar',
|
||||||
\ 'Xdir1/Xdir2/Xdir3/bar',
|
\ 'Xfinddir1/Xdir2/Xdir3/bar',
|
||||||
\ 'Xdir1/Xdir2/Xdir3/barfoo' ]
|
\ 'Xfinddir1/Xdir2/Xdir3/barfoo' ]
|
||||||
|
|
||||||
func CreateFiles()
|
func CreateFiles()
|
||||||
call mkdir('Xdir1/Xdir2/Xdir3/Xdir2', 'p')
|
call mkdir('Xfinddir1/Xdir2/Xdir3/Xdir2', 'p')
|
||||||
for f in s:files
|
for f in s:files
|
||||||
call writefile([], f)
|
call writefile([], f)
|
||||||
endfor
|
endfor
|
||||||
@@ -16,15 +16,15 @@ endfunc
|
|||||||
|
|
||||||
func CleanFiles()
|
func CleanFiles()
|
||||||
" Safer to delete each file even if it's more verbose
|
" Safer to delete each file even if it's more verbose
|
||||||
" than doing a recursive delete('Xdir1', 'rf').
|
" than doing a recursive delete('Xfinddir1', 'rf').
|
||||||
for f in s:files
|
for f in s:files
|
||||||
call delete(f)
|
call delete(f)
|
||||||
endfor
|
endfor
|
||||||
|
|
||||||
call delete('Xdir1/Xdir2/Xdir3/Xdir2', 'd')
|
call delete('Xfinddir1/Xdir2/Xdir3/Xdir2', 'd')
|
||||||
call delete('Xdir1/Xdir2/Xdir3', 'd')
|
call delete('Xfinddir1/Xdir2/Xdir3', 'd')
|
||||||
call delete('Xdir1/Xdir2', 'd')
|
call delete('Xfinddir1/Xdir2', 'd')
|
||||||
call delete('Xdir1', 'd')
|
call delete('Xfinddir1', 'd')
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
" Test findfile({name} [, {path} [, {count}]])
|
" Test findfile({name} [, {path} [, {count}]])
|
||||||
@@ -34,7 +34,7 @@ func Test_findfile()
|
|||||||
let save_dir = getcwd()
|
let save_dir = getcwd()
|
||||||
set shellslash
|
set shellslash
|
||||||
call CreateFiles()
|
call CreateFiles()
|
||||||
cd Xdir1
|
cd Xfinddir1
|
||||||
e Xdir2/foo
|
e Xdir2/foo
|
||||||
|
|
||||||
" With ,, in path, findfile() searches in current directory.
|
" With ,, in path, findfile() searches in current directory.
|
||||||
@@ -83,34 +83,58 @@ func Test_findfile()
|
|||||||
" Test upwards search.
|
" Test upwards search.
|
||||||
cd Xdir2/Xdir3
|
cd Xdir2/Xdir3
|
||||||
call assert_equal('bar', findfile('bar', ';'))
|
call assert_equal('bar', findfile('bar', ';'))
|
||||||
call assert_match('.*/Xdir1/Xdir2/foo', findfile('foo', ';'))
|
call assert_match('.*/Xfinddir1/Xdir2/foo', findfile('foo', ';'))
|
||||||
call assert_match('.*/Xdir1/Xdir2/foo', findfile('foo', ';', 1))
|
call assert_match('.*/Xfinddir1/Xdir2/foo', findfile('foo', ';', 1))
|
||||||
call assert_match('.*/Xdir1/foo', findfile('foo', ';', 2))
|
call assert_match('.*/Xfinddir1/foo', findfile('foo', ';', 2))
|
||||||
call assert_match('.*/Xdir1/foo', findfile('foo', ';', 2))
|
call assert_match('.*/Xfinddir1/foo', findfile('foo', ';', 2))
|
||||||
call assert_match('.*/Xdir1/Xdir2/foo', findfile('foo', 'Xdir2;', 1))
|
call assert_match('.*/Xfinddir1/Xdir2/foo', findfile('foo', 'Xdir2;', 1))
|
||||||
call assert_equal('', findfile('foo', 'Xdir2;', 2))
|
call assert_equal('', findfile('foo', 'Xdir2;', 2))
|
||||||
|
|
||||||
" List l should have at least 2 values (possibly more if foo file
|
" List l should have at least 2 values (possibly more if foo file
|
||||||
" happens to be found upwards above Xdir1).
|
" happens to be found upwards above Xfinddir1).
|
||||||
let l = findfile('foo', ';', -1)
|
let l = findfile('foo', ';', -1)
|
||||||
call assert_match('.*/Xdir1/Xdir2/foo', l[0])
|
call assert_match('.*/Xfinddir1/Xdir2/foo', l[0])
|
||||||
call assert_match('.*/Xdir1/foo', l[1])
|
call assert_match('.*/Xfinddir1/foo', l[1])
|
||||||
|
|
||||||
" Test upwards search with stop-directory.
|
" Test upwards search with stop-directory.
|
||||||
cd Xdir2
|
cd Xdir2
|
||||||
let l = findfile('bar', ';' . save_dir . '/Xdir1/Xdir2/', -1)
|
let l = findfile('bar', ';' . save_dir . '/Xfinddir1/Xdir2/Xdir3/', -1)
|
||||||
call assert_equal(1, len(l))
|
call assert_equal(1, len(l))
|
||||||
call assert_match('.*/Xdir1/Xdir2/Xdir3/bar', l[0])
|
call assert_match('.*/Xfinddir1/Xdir2/Xdir3/bar', l[0])
|
||||||
|
let l = findfile('bar', ';' . save_dir . '/Xfinddir1/Xdir2/Xdir3', -1)
|
||||||
|
call assert_equal(1, len(l))
|
||||||
|
call assert_match('.*/Xfinddir1/Xdir2/Xdir3/bar', l[0])
|
||||||
|
let l = findfile('bar', ';../', -1)
|
||||||
|
call assert_equal(1, len(l))
|
||||||
|
call assert_match('.*/Xfinddir1/Xdir2/Xdir3/bar', l[0])
|
||||||
|
|
||||||
let l = findfile('bar', ';' . save_dir . '/Xdir1/', -1)
|
let l = findfile('bar', ';' . save_dir . '/Xfinddir1/Xdir2/', -1)
|
||||||
|
call assert_equal(1, len(l))
|
||||||
|
call assert_match('.*/Xfinddir1/Xdir2/Xdir3/bar', l[0])
|
||||||
|
let l = findfile('bar', ';' . save_dir . '/Xfinddir1/Xdir2', -1)
|
||||||
|
call assert_equal(1, len(l))
|
||||||
|
call assert_match('.*/Xfinddir1/Xdir2/Xdir3/bar', l[0])
|
||||||
|
let l = findfile('bar', ';../../', -1)
|
||||||
|
call assert_equal(1, len(l))
|
||||||
|
call assert_match('.*/Xfinddir1/Xdir2/Xdir3/bar', l[0])
|
||||||
|
|
||||||
|
let l = findfile('bar', ';' . save_dir . '/Xfinddir1/', -1)
|
||||||
call assert_equal(2, len(l))
|
call assert_equal(2, len(l))
|
||||||
call assert_match('.*/Xdir1/Xdir2/Xdir3/bar', l[0])
|
call assert_match('.*/Xfinddir1/Xdir2/Xdir3/bar', l[0])
|
||||||
call assert_match('.*/Xdir1/bar', l[1])
|
call assert_match('.*/Xfinddir1/bar', l[1])
|
||||||
|
let l = findfile('bar', ';' . save_dir . '/Xfinddir1', -1)
|
||||||
|
call assert_equal(2, len(l))
|
||||||
|
call assert_match('.*/Xfinddir1/Xdir2/Xdir3/bar', l[0])
|
||||||
|
call assert_match('.*/Xfinddir1/bar', l[1])
|
||||||
|
let l = findfile('bar', ';../../../', -1)
|
||||||
|
call assert_equal(2, len(l))
|
||||||
|
call assert_match('.*/Xfinddir1/Xdir2/Xdir3/bar', l[0])
|
||||||
|
call assert_match('.*/Xfinddir1/bar', l[1])
|
||||||
|
|
||||||
" Test combined downwards and upwards search from Xdir2/.
|
" Test combined downwards and upwards search from Xdir2/.
|
||||||
cd ../..
|
cd ../..
|
||||||
call assert_equal('Xdir3/bar', findfile('bar', '**;', 1))
|
call assert_equal('Xdir3/bar', findfile('bar', '**;', 1))
|
||||||
call assert_match('.*/Xdir1/bar', findfile('bar', '**;', 2))
|
call assert_match('.*/Xfinddir1/bar', findfile('bar', '**;', 2))
|
||||||
|
|
||||||
bwipe!
|
bwipe!
|
||||||
call chdir(save_dir)
|
call chdir(save_dir)
|
||||||
@@ -135,7 +159,7 @@ func Test_finddir()
|
|||||||
set path=,,
|
set path=,,
|
||||||
set shellslash
|
set shellslash
|
||||||
call CreateFiles()
|
call CreateFiles()
|
||||||
cd Xdir1
|
cd Xfinddir1
|
||||||
|
|
||||||
call assert_equal('Xdir2', finddir('Xdir2'))
|
call assert_equal('Xdir2', finddir('Xdir2'))
|
||||||
call assert_equal('', 'Xdir3'->finddir())
|
call assert_equal('', 'Xdir3'->finddir())
|
||||||
@@ -158,17 +182,17 @@ func Test_finddir()
|
|||||||
|
|
||||||
" Test upwards dir search.
|
" Test upwards dir search.
|
||||||
cd Xdir2/Xdir3
|
cd Xdir2/Xdir3
|
||||||
call assert_match('.*/Xdir1', finddir('Xdir1', ';'))
|
call assert_match('.*/Xfinddir1', finddir('Xfinddir1', ';'))
|
||||||
|
|
||||||
" Test upwards search with stop-directory.
|
" Test upwards search with stop-directory.
|
||||||
call assert_match('.*/Xdir1', finddir('Xdir1', ';' . save_dir . '/'))
|
call assert_match('.*/Xfinddir1', finddir('Xfinddir1', ';' . save_dir . '/'))
|
||||||
call assert_equal('', finddir('Xdir1', ';' . save_dir . '/Xdir1/'))
|
call assert_equal('', finddir('Xfinddir1', ';' . save_dir . '/Xfinddir1/'))
|
||||||
|
|
||||||
" Test combined downwards and upwards dir search from Xdir2/.
|
" Test combined downwards and upwards dir search from Xdir2/.
|
||||||
cd ..
|
cd ..
|
||||||
call assert_match('.*/Xdir1', finddir('Xdir1', '**;', 1))
|
call assert_match('.*/Xfinddir1', finddir('Xfinddir1', '**;', 1))
|
||||||
call assert_equal('Xdir3/Xdir2', finddir('Xdir2', '**;', 1))
|
call assert_equal('Xdir3/Xdir2', finddir('Xdir2', '**;', 1))
|
||||||
call assert_match('.*/Xdir1/Xdir2', finddir('Xdir2', '**;', 2))
|
call assert_match('.*/Xfinddir1/Xdir2', finddir('Xdir2', '**;', 2))
|
||||||
call assert_equal('Xdir3', finddir('Xdir3', '**;', 1))
|
call assert_equal('Xdir3', finddir('Xdir3', '**;', 1))
|
||||||
|
|
||||||
call chdir(save_dir)
|
call chdir(save_dir)
|
||||||
@@ -192,7 +216,7 @@ func Test_find_cmd()
|
|||||||
let save_dir = getcwd()
|
let save_dir = getcwd()
|
||||||
set path=.,./**/*
|
set path=.,./**/*
|
||||||
call CreateFiles()
|
call CreateFiles()
|
||||||
cd Xdir1
|
cd Xfinddir1
|
||||||
|
|
||||||
" Test for :find
|
" Test for :find
|
||||||
find foo
|
find foo
|
||||||
|
@@ -135,6 +135,38 @@ func Test_tagsfile_without_trailing_newline()
|
|||||||
set tags&
|
set tags&
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
|
" Check that specifying a stop directory in 'tags' works properly.
|
||||||
|
func Test_tagfiles_stopdir()
|
||||||
|
let save_cwd = getcwd()
|
||||||
|
|
||||||
|
call mkdir('Xtagsdir1/Xtagsdir2/Xtagsdir3', 'pR')
|
||||||
|
call writefile([], 'Xtagsdir1/Xtags', 'D')
|
||||||
|
|
||||||
|
cd Xtagsdir1/
|
||||||
|
let &tags = './Xtags;' .. fnamemodify('./..', ':p')
|
||||||
|
call assert_equal(1, len(tagfiles()))
|
||||||
|
|
||||||
|
cd Xtagsdir2/
|
||||||
|
let &tags = './Xtags;' .. fnamemodify('./..', ':p')
|
||||||
|
call assert_equal(1, len(tagfiles()))
|
||||||
|
|
||||||
|
cd Xtagsdir3/
|
||||||
|
let &tags = './Xtags;' .. fnamemodify('./..', ':p')
|
||||||
|
call assert_equal(0, len(tagfiles()))
|
||||||
|
|
||||||
|
let &tags = './Xtags;../'
|
||||||
|
call assert_equal(0, len(tagfiles()))
|
||||||
|
|
||||||
|
cd ..
|
||||||
|
call assert_equal(1, len(tagfiles()))
|
||||||
|
|
||||||
|
cd ..
|
||||||
|
call assert_equal(1, len(tagfiles()))
|
||||||
|
|
||||||
|
set tags&
|
||||||
|
call chdir(save_cwd)
|
||||||
|
endfunc
|
||||||
|
|
||||||
" Test for ignoring comments in a tags file
|
" Test for ignoring comments in a tags file
|
||||||
func Test_tagfile_ignore_comments()
|
func Test_tagfile_ignore_comments()
|
||||||
call writefile([
|
call writefile([
|
||||||
|
Reference in New Issue
Block a user