From e25e86a9edcb0ba77ead2de244d9da7ffd12161e Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Fri, 11 Sep 2026 10:40:11 +0800 Subject: [PATCH] vim-patch:9.2.1067: Completion shows an included file by full path (#41849) Problem: A match found in an included file is shown with the full path of the file, while a match from a buffer is shown with the name under the current directory. A file included as "./file" even has the "./" left in: "dir/./file". Solution: Show the file by its name under the current directory, and simplify the name of a file found relative to the current one (Hirohito Higashi). closes: vim/vim#21264 https://github.com/vim/vim/commit/cff83f361de471456d98b070ec3e63b0e5e6f17c Co-authored-by: Hirohito Higashi --- src/nvim/file_search.c | 5 ++--- src/nvim/search.c | 9 ++++---- test/functional/editor/completion_spec.lua | 25 ++++++++++++++++++++++ test/old/testdir/test_ins_complete.vim | 20 +++++++++++++++++ 4 files changed, 52 insertions(+), 7 deletions(-) diff --git a/src/nvim/file_search.c b/src/nvim/file_search.c index cff8451913..37b7fd49a8 100644 --- a/src/nvim/file_search.c +++ b/src/nvim/file_search.c @@ -1505,20 +1505,19 @@ char *find_file_in_path_option(char *ptr, size_t len, int options, int first, ch } // When the file doesn't exist, try adding parts of 'suffixesadd'. - size_t NameBufflen = l; char *suffix = suffixes; while (true) { if ((os_path_exists(NameBuff) && (find_what == FINDFILE_BOTH || ((find_what == FINDFILE_DIR) == os_isdir(NameBuff))))) { - file_name = xmemdupz(NameBuff, NameBufflen); + file_name = xmemdupz(NameBuff, simplify_filename(NameBuff)); goto theend; } if (*suffix == NUL) { break; } assert(MAXPATHL >= l); - NameBufflen = l + copy_option_part(&suffix, NameBuff + l, MAXPATHL - l, ","); + copy_option_part(&suffix, NameBuff + l, MAXPATHL - l, ","); } } } diff --git a/src/nvim/search.c b/src/nvim/search.c index c988578a8d..3a35e3c8fa 100644 --- a/src/nvim/search.c +++ b/src/nvim/search.c @@ -3338,10 +3338,11 @@ search_line: } } - const int add_r = ins_compl_add_infercase(aux, i, p_ic, - curr_fname == curbuf->b_fname - ? NULL : curr_fname, - dir, cont_s_ipos, 0); + const int add_r + = ins_compl_add_infercase(aux, i, p_ic, + curr_fname == curbuf->b_fname + ? NULL : path_try_shorten_fname(curr_fname), + dir, cont_s_ipos, 0); if (add_r == OK) { // if dir was BACKWARD then honor it just once dir = FORWARD; diff --git a/test/functional/editor/completion_spec.lua b/test/functional/editor/completion_spec.lua index a383270a42..04b284c06b 100644 --- a/test/functional/editor/completion_spec.lua +++ b/test/functional/editor/completion_spec.lua @@ -1321,6 +1321,31 @@ describe('completion', function() ]]) end) + -- oldtest: Test_complete_included_file_name() + it('shows included files by relative path', function() + t.mkdir('Xincl') + finally(function() + n.rmdir('Xincl') + end) + t.mkdir('Xincl/sub') + t.write_file('Xincl/sub/inc.vim', 'let included_word = 1\n') + t.write_file('Xincl/main.vim', 'source ./sub/inc.vim\n\n') + n.exec([[ + edit Xincl/main.vim + setlocal include=^\\s*source\\s\\+ complete=i completeopt=menuone,noselect + ]]) + feed('Goincluded_') + screen:expect([[ + source ./sub/inc.vim | + | + included_^ | + {4:included_word Xincl/sub/inc.vim }{1: }| + {1:~ }|*3 + {5:-- Keyword completion (^N^P) }{19:Back at original} | + ]]) + feed('') + end) + -- oldtest: Test_complete_changed_complete_info() it('no crash calling complete_info() in CompleteChanged', function() source([[ diff --git a/test/old/testdir/test_ins_complete.vim b/test/old/testdir/test_ins_complete.vim index 9cddfda03c..4fc97fe287 100644 --- a/test/old/testdir/test_ins_complete.vim +++ b/test/old/testdir/test_ins_complete.vim @@ -3531,6 +3531,26 @@ func s:Tagfunc(t,f,o) return [] endfunc +" A match from an included file shows the file by its name under the current +" directory, without the "./" of the include line. +func Test_complete_included_file_name() + CheckRunVimInTerminal + call mkdir('Xincl/sub', 'pR') + call writefile(['let included_word = 1'], 'Xincl/sub/inc.vim') + call writefile(['source ./sub/inc.vim', ''], 'Xincl/main.vim') + let lines =<< trim END + setlocal include=^\\s*source\\s\\+ complete=i completeopt=menuone,noselect + END + call writefile(lines, 'Xincl/setup.vim') + let buf = RunVimInTerminal('-S Xincl/setup.vim Xincl/main.vim', + \ {'rows': 8, 'cols': 120}) + call term_sendkeys(buf, "Goincluded_\") + call WaitForAssert({-> assert_match('included_word\s\+Xincl/sub/inc.vim\s', + \ term_getline(buf, 4))}) + call term_sendkeys(buf, "\") + call StopVimInTerminal(buf) +endfunc + " This was using freed memory, since 'complete' was in a wiped out buffer. " Also using a window that was closed. func Test_tagfunc_wipes_out_buffer()