diff --git a/src/nvim/path.c b/src/nvim/path.c index 56dffaeabc..4dc522e27a 100644 --- a/src/nvim/path.c +++ b/src/nvim/path.c @@ -2384,9 +2384,13 @@ static int path_to_absolute(const char *fname, char *buf, size_t len, int force) p = strrchr(fname, '\\'); } #endif + if (p == NULL && strcmp(fname, "..") == 0) { + // Handle ".." without path separators. + p = fname + 2; + } if (p != NULL) { - if (strcmp(p + 1, "..") == 0) { - // for "/path/dir/.." include the "/.." + if (vim_ispathsep_nocolon(*p) && strcmp(p + 1, "..") == 0) { + // For "/path/dir/.." include the "/..". p += 3; } assert(p >= fname); diff --git a/test/old/testdir/test_findfile.vim b/test/old/testdir/test_findfile.vim index 0b241e3466..06d781ed69 100644 --- a/test/old/testdir/test_findfile.vim +++ b/test/old/testdir/test_findfile.vim @@ -107,6 +107,9 @@ func Test_findfile() let l = findfile('bar', ';../', -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/Xdir2/', -1) call assert_equal(1, len(l)) @@ -117,6 +120,9 @@ func Test_findfile() let l = findfile('bar', ';../../', -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)) @@ -130,6 +136,10 @@ func Test_findfile() 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/. cd ../.. diff --git a/test/old/testdir/test_fnamemodify.vim b/test/old/testdir/test_fnamemodify.vim index 2e6c7b8a1e..f0bc2503b5 100644 --- a/test/old/testdir/test_fnamemodify.vim +++ b/test/old/testdir/test_fnamemodify.vim @@ -14,6 +14,8 @@ func Test_fnamemodify() call assert_equal($HOME .. "/foo" , fnamemodify('~/foo', ':p')) call assert_equal(fnamemodify('.', ':p:h:h:h') .. '/', fnamemodify($HOME .. '/../', ':p')) call assert_equal(fnamemodify('.', ':p:h:h:h') .. '/', fnamemodify($HOME .. '/..', ':p')) + call assert_equal(fnamemodify('.', ':p:h:h') .. '/', fnamemodify('../', ':p')) + call assert_equal(fnamemodify('.', ':p:h:h') .. '/', fnamemodify('..', ':p')) call assert_equal('test.out', fnamemodify('test.out', ':.')) call assert_equal('a', fnamemodify('../testdir/a', ':.')) call assert_equal('~/testdir/test.out', fnamemodify('test.out', ':~')) diff --git a/test/old/testdir/test_taglist.vim b/test/old/testdir/test_taglist.vim index 92d6d283ed..fbb682a9b2 100644 --- a/test/old/testdir/test_taglist.vim +++ b/test/old/testdir/test_taglist.vim @@ -143,15 +143,15 @@ func Test_tagfiles_stopdir() call writefile([], 'Xtagsdir1/Xtags', 'D') cd Xtagsdir1/ - let &tags = './Xtags;' .. fnamemodify('./..', ':p') + let &tags = './Xtags;' .. fnamemodify('..', ':p') call assert_equal(1, len(tagfiles())) cd Xtagsdir2/ - let &tags = './Xtags;' .. fnamemodify('./..', ':p') + let &tags = './Xtags;' .. fnamemodify('..', ':p') call assert_equal(1, len(tagfiles())) cd Xtagsdir3/ - let &tags = './Xtags;' .. fnamemodify('./..', ':p') + let &tags = './Xtags;' .. fnamemodify('..', ':p') call assert_equal(0, len(tagfiles())) let &tags = './Xtags;../' @@ -163,6 +163,15 @@ func Test_tagfiles_stopdir() cd .. call assert_equal(1, len(tagfiles())) + let &tags = './Xtags;..' + call assert_equal(1, len(tagfiles())) + + cd Xtagsdir2/ + call assert_equal(1, len(tagfiles())) + + cd Xtagsdir3/ + call assert_equal(0, len(tagfiles())) + set tags& call chdir(save_cwd) endfunc diff --git a/test/unit/path_spec.lua b/test/unit/path_spec.lua index 6f6a80f44e..ffad552a8a 100644 --- a/test/unit/path_spec.lua +++ b/test/unit/path_spec.lua @@ -468,8 +468,11 @@ describe('path.c', function() eq(OK, result) end) - itp('concatenates directory name if it does not contain a slash', function() - local expected = uv.cwd() .. '/..' + itp('produces absolute path for .. without a slash', function() + local old_dir = uv.cwd() + uv.chdir('..') + local expected = uv.cwd() + uv.chdir(old_dir) local filename = '..' local buflen = get_buf_len(expected, filename) local do_expand = 1 @@ -478,21 +481,18 @@ describe('path.c', function() eq(OK, result) end) - itp( - 'enters given directory (instead of just concatenating the strings) if possible and if path contains a slash', - function() - local old_dir = uv.cwd() - uv.chdir('..') - local expected = uv.cwd() .. '/test.file' - uv.chdir(old_dir) - local filename = '../test.file' - local buflen = get_buf_len(expected, filename) - local do_expand = 1 - local buf, result = vim_FullName(filename, buflen, do_expand) - eq(expected, ffi.string(buf)) - eq(OK, result) - end - ) + itp('produces absolute path if possible and if path contains a slash', function() + local old_dir = uv.cwd() + uv.chdir('..') + local expected = uv.cwd() .. '/test.file' + uv.chdir(old_dir) + local filename = '../test.file' + local buflen = get_buf_len(expected, filename) + local do_expand = 1 + local buf, result = vim_FullName(filename, buflen, do_expand) + eq(expected, ffi.string(buf)) + eq(OK, result) + end) itp('just copies the path if it is already absolute and force=0', function() local absolute_path = '/absolute/path'